我在 Unix 中有一個以毫秒為單位的時間戳,現在我需要以毫秒為單位的同一給定時間戳的一天開始和一天結束。
Eg: 1637293359000 - Given timestamp
Start of the day to be 1637280000000
End of the day to be 1637323199000
uj5u.com熱心網友回復:
在系統默認時區中,您可以嘗試這樣
ZoneId zoneId = ZoneId.systemDefault();
long timestamp = 1637293359000L;
LocalDate date = Instant.ofEpochMilli(timestamp).atZone(zoneId).toLocalDate();
LocalDateTime startDay = date.atStartOfDay();
LocalDateTime endDay = date.atTime(LocalTime.MAX);
System.out.println(startDay);
System.out.println(endDay);
long startDayLongValue = startDay.atZone(zoneId).toInstant().toEpochMilli();
long endDayLongValue = endDay.atZone(zoneId).toInstant().toEpochMilli();
System.out.println(startDayLongValue);
System.out.println(endDayLongValue);
uj5u.com熱心網友回復:
我們可以使用 DateTime 實作這一點
import org.joda.time.DateTime;
long timestamp = 1629454215381L;
DateTime dateTime=new DateTime(timestamp );
long StartOfDayMillis = dateTime.withMillis(System.currentTimeMillis()).withTimeAtStartOfDay().getMillis();
long EndOfDayMillis = dateTime.withMillis(StartOfDayMillis).plusDays(1).minusSeconds(1).getMillis();
uj5u.com熱心網友回復:
tl;博士
這是代表在特定時區中看到的特定時刻的一天的記錄的完整代碼。靜態工廠方法包含我們的邏輯。
package work.basil.example;
import java.time.*;
import java.util.Objects;
public record DayInMillis( long start , long end )
{
public static DayInMillis from ( final long moment , final ZoneId zoneId )
{
Objects.requireNonNull( zoneId );
Instant instant = Instant.ofEpochMilli( moment );
ZonedDateTime zdt = instant.atZone( zoneId );
LocalDate ld = zdt.toLocalDate();
ZonedDateTime start = ld.atStartOfDay( zoneId );
ZonedDateTime end = ld.plusDays( 1 ).atStartOfDay( zoneId );
Instant startInstant = start.toInstant();
Instant endInstant = end.toInstant();
long startMilli = startInstant.toEpochMilli();
long endMilli = endInstant.toEpochMilli();
System.out.println( "instant = " instant );
System.out.println( "zdt = " zdt );
System.out.println( "start/end = " start "/" end );
System.out.println( "startInstant/endInstant = " startInstant "/" endInstant );
System.out.println( "startMilli/endMilli = " startMilli "/" endMilli );
System.out.println( "Duration (not necessarily 24 hours): " Duration.between( startInstant , endInstant ) );
return new DayInMillis( startMilli , endMilli );
}
}
用法示例:
DayInMillis.from( 1_637_293_359_000L , ZoneId.of( "Asia/Tokyo" ) )
跑的時候。
instant = 2021-11-19T03:42:39Z
zdt = 2021-11-19T12:42:39 09:00[Asia/Tokyo]
start/end = 2021-11-19T00:00 09:00[Asia/Tokyo]/2021-11-20T00:00 09:00[Asia/Tokyo]
startInstant/endInstant = 2021-11-18T15:00:00Z/2021-11-19T15:00:00Z
startMilli/endMilli = 1637247600000/1637334000000
Duration (not necessarily 24 hours): PT24H
dayInMillis = DayInMillis[start=1637247600000, end=1637334000000]
決議秒數
將 UTC 中自 1970 年第一個時刻以來的輸入毫秒數決議為一個Instant物件。
Instant instant = Instant.ofEpochMilli( 1_637_293_359_000L ) ;
調整到時區
指定您想要感知日期的時區。
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
Adjust from UTC (an offset of zero hours-minutes-seconds) to that time zone.
ZonedDateTime zdt = instant.atZone( z ) ;
Get the date
Extract the date-only portion.
LocalDate ld = zdt.toLocalDate() ;
Start of day
Let java.time determine the first moment of the day. Never assume the day starts at 00:00. Some dates in some zones may start at another time such as 01:00.
ZonedDateTime start = ld.atStartOfDay( z ) ;
Half-Open
The last moment of the day is infinitely divisible. For this and other reasons, spans of time are usually best defined using Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. This means the span of a day starts at the first moment of the day and runs up to, but does not include, the first moment of the following day.
ZonedDateTime end = ld.plusDays( 1 ).atStartOfDay( z ) ;
Now we have the span covered by a pair of ZonedDateTime objects. But you want to get a count of milliseconds since epoch for both of those.
Tracking count-from-epoch is awkward
Let me say, I do not recommend using a count-since-epoch for time-keeping. The values are inherently ambiguous as to both epoch and granularity. Furthermore, using such counts makes debugging difficult and errors hard to spot, as such values are meaningless to human readers.
ISO 8601
Instead, I suggest communicating such values textually in standard ISO 8601 format. The java.time classes use ISO 8601 formats by default when parsing/generating text.
String outputStart = start.toInstant().toString();
String outputEnd = end.toInstant().toString();
Milliseconds since epoch
But if you insist on the count of milliseconds, first extract Instant objects from our ZonedDateTime objects, effectively adjusting to UTC (offset of zero).
Instant startInstant = start.toInstant() ;
Instant endInstant = end.toInstant() ;
Interrogate for a count of milliseconds since epoch.
long startMilli = startInstant.toEpochMilli() ;
long endMilli = endInstant.toEpochMilli() ;
Avoid LocalDateTime for this problem
Notice that at no point did we use the LocalDateTime class. That class purposely lacks the context of a time zone or offset-from-UTC. So LocalDateTime cannot represent a moment, is not a point on the timeline. That makes LocalDateTime irrelevant to the problem at hand.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/360703.html
