获得当前第一天和当前时间JDK 8之间的时间范围

时间:2017-08-20 17:20:36

标签: date java-8 java-time dayofweek zoneddatetime

我可以轻松计算出第一天和当前时间之间的时间段:

/**
 * Returns the time range between the first day of month and current time in milliseconds.
 *
 * @param zoneId time zone ID.
 * @return a {@code long} array, where at index: 0 - the first day of month midnight time; 1 - current time.
 */

public static long[] monthDateRange(ZoneId zoneId) {
    long[] toReturn = new long[2];

ZonedDateTime nowZdt = LocalDateTime.now().atZone(zoneId);
ZonedDateTime startZdt = nowZdt.withDayOfMonth(1);
toReturn[0] = startZdt.toInstant().toEpochMilli();
toReturn[1] = nowZdt.toInstant().toEpochMilli();
return toReturn;
}

但是如何在本周的第一天(午夜)开始计算?

2 个答案:

答案 0 :(得分:4)

TL;博士

ZonedDateTime
    .now( ZoneId.of( "Asia/Kolkata" ) )                            // Current moment in a particular time zone.
    .toLocalDate()                                                 // Extract date-only value, losing the time-of-day and time zone components.
    .with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) )  // Move to another day-of-week, or same date if this is the desired day-of-week.
    .atStartOfDay( ZoneId.of( "Asia/Kolkata" ) )                   // Determine the first moment of the day. Do *not* assume this time-of-day is 00:00:00 as anomalies such as Daylight Saving Time (DST) may mean otherwise such as 01:00:00. 
    .toInstant()                                                   // Adjust into UTC, same moment, same point on the timeline, but viewed through the lens of UTC time zone.
    .toEpochMilli()                                                // Extract a count-from-epoch in milliseconds. I do *not* recommend tracking date-time this way, but the Question requires this number.

详细

Answer by Gruodis很好,但这里有一个更直接,更灵活的替代方案。

ZonedDateTime获取当前时刻。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

TemporalAdjuster

TemporalAdjuster界面允许您操作日期时间值以获取新的日期时间值。 TemporalAdjusters类(注意复数s)提供了几个方便的实现。使用DayOfWeek枚举来指定您认为哪一天是一周的第一天。

DayOfWeek dowStartOfWeek = DayOfWeek.MONDAY ; 
LocalDate weekStartDate = now.toLocalDate().with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) ) ;
ZonedDateTime start = weekStartDate.atStartOfDay( z ) ;  // Determine first moment of the day. Note: *not* always 00:00:00.

请参阅此code run live at IdeOne.com

  

2017-08-21T00:00 + 12:00 [太平洋/奥克兰]   2017-08-21T08:44:46.439 + 12:00 [太平洋/奥克兰]

时间跨度

要报告您的时间跨度,如果需要,pou确实可以提取整秒的计数。

long epochSeconds = start.toEpochSecond() ; 

或者通过Instant提取毫秒。

long epochMillis = start.toInstant().toEpochMilli() ;

但请记住,当java.time类型解析为nanoseconds时,这两个数字都会截断任何进一步的小数秒。

除了截断之外,还有其他原因可以避免将日期时间跟踪为count-from-epoch。由于这些值对于人眼来说毫无意义,因此调试更加困难,错误的数据可能会让您失望。此外,您可以假设时期为1970-01-01T00:00:00Z,但普通软件系统至少使用another couple dozen epochs。另一个问题是计数的粒度模糊,其中一些系统使用整秒,其他系统使用毫秒,其他使用微秒,其他使用纳秒,还有一些使用其他分辨率。

Interval

因此,我建议不要返回仅仅long整数,而是返回一个对象。一对Instant个对象起作用,这是Interval项目中ThreeTen-Extra类使用的对象。该类有几个非常方便的方法,我希望调用代码可能有用,例如containsenclosesabutsoverlapsspan,{{1等等。

isEmpty

您可以应用时区来查看区域自身挂钟时间的镜头的开头或结尾。

org.threeten.extra.Interval interval = Interval.of( start.toInstant() , now.toInstant() ) ;

答案 1 :(得分:1)

解决方案:

/**
 * Returns the time range between the first day of current week midnight and current time in milliseconds.
 *
 * @param zoneId time zone ID.
 * @return a {@code long} array, where at index: 0 - the first day of current week midnight time; 1 - current time.
 */

public static long[] monthDateRange(ZoneId zoneId) {
    long[] toReturn = new long[2];

//ZonedDateTime nowZdt = LocalDateTime.now().atZone(zoneId);
ZonedDateTime nowZdt = ZonedDateTime.now(zoneId);//As suggested by Basil Bourque (tested).
//ZonedDateTime startZdt = nowZdt.with(ChronoField.DAY_OF_WEEK, 1);
ZonedDateTime startZdt = nowZdt.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));//As suggested by Basil Bourque (tested).
startZdt = startZdt.toLocalDate ().atStartOfDay(zoneId);
toReturn[0] = startZdt.toInstant().toEpochMilli();
toReturn[1] = nowZdt.toInstant().toEpochMilli();
return toReturn;
}

请参阅此code run live at IdeOne.com