首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从当前周的第一天到当前时间JDK 8之间的时间范围

问从当前周的第一天到当前时间JDK 8之间的时间范围
EN

Stack Overflow用户
提问于 2017-08-20 17:20:35
回答 2查看 315关注 0票数 3

我可以很容易地计算出从月的第一天到现在的时间:

代码语言:javascript
复制
/**
 * 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;
}

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-20 20:13:58

tl;dr

代码语言:javascript
复制
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.

详细信息

Gruodis回答很好,但是这里有一个更直接、更灵活的替代方案。

获取当前作为一个ZonedDateTime的时刻。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

TemporalAdjuster

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

代码语言:javascript
复制
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.

看这个在IdeOne.com现场运行的代码。

2017-08-21T00:00+12:00Pacific/奥克兰2017-08-21T08:44:46.439+12:00Pacific/奥克兰

时间跨度

为了报告你的时间跨度,如果需要的话,pou确实可以从整秒的时间里提取一个计数。

代码语言:javascript
复制
long epochSeconds = start.toEpochSecond() ; 

或者通过Instant提取毫秒。

代码语言:javascript
复制
long epochMillis = start.toInstant().toEpochMilli() ;

但是请记住,这两个数字都会进一步截断小数秒,因为java.time类型将解析为纳秒。

除了截断之外,还有其他避免将日期时间作为历代数进行跟踪的原因.因为这些值对人的眼睛来说是没有意义的,所以调试要困难得多,错误的数据可能会引起您的注意。另外,您可能假设时代是1970-01-01T00:00:00Z,但是至少有一些通用软件系统使用了又有几十个时代。另一个问题是计数的粒度模糊不清,有些系统使用整秒,另一些系统使用毫秒,其他系统使用微秒,其他系统使用其他分辨率。

Interval

因此,我建议返回一个对象,而不是只返回long整数。一对Instant对象可以工作,这是Interval类在http://www.threeten.org/threeten-extra/项目中使用的。这个类有几个非常方便的方法,我希望调用代码可能会发现一些有用的方法,比如contains、encloses、abuts、overlaps、span、isEmpty等等。

代码语言:javascript
复制
org.threeten.extra.Interval interval = Interval.of( start.toInstant() , now.toInstant() ) ;

您可以应用一个时区通过区域自己的挂钟时间的透镜来查看开始或结束。

代码语言:javascript
复制
ZonedDateTime zdtStart = interval.getStart().atZone( z );  // Or `getEnd()`.
票数 4
EN

Stack Overflow用户

发布于 2017-08-20 18:35:31

解决办法:

代码语言:javascript
复制
/**
 * 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;
}

看这个在IdeOne.com现场运行的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45784857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档