在计算两者之间的周数时避免夏令时

Posted

技术标签:

【中文标题】在计算两者之间的周数时避免夏令时【英文标题】:Avoid Daylight Saving Time in calculating weeks in between 【发布时间】:2018-08-25 00:32:03 【问题描述】:

我正在尝试计算两个日期之间的周数。

使用 Java SE8

public long weekInBetween(Date date1, Date date2)

    return ChronoUnit.WEEKS.between(date1.toInstant().atZone(ZoneId.systemDefault()),
            date2.toInstant().atZone(ZoneId.systemDefault()));

使用 Joda 时间

public int weekInBetween(Date date1, Date date2)

    DateTime dateTime1 = new DateTime(date1);
    DateTime dateTime2 = new DateTime(date2);
    return Weeks.weeksBetween(dateTime1.toLocalDateTime(), dateTime2.toLocalDateTime()).getWeeks();

但是,只要过了 DST 开始日期,即 3 月 11 日。时间将向前推 1 小时,即从 UTC-8 开始的日期变为 UTC-7。因此,中间的周数不正确,比预期提前 1 周。

例如,date1Mon Feb 05 08:00:00 UTC 2018date2Mon Mar 12 07:00:00 UTC 2018,在这种情况下,周数返回 4 从技术上讲是合乎逻辑的,但我只想考虑日期而忽略时间和结果5周。我该怎么做?

【问题讨论】:

仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle。 【参考方案1】:

java.time

您可以使用 Java 8 及更高版本中内置的 java.time 类,使用 toLocalDate 方法将 ZonedDateTime 转换为 LocalDate。

date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

这样时间信息就会被删除,因为 LocalDate 不存储时间,只存储日期。

关于“时间向前推 1 小时”,如果您指的是当您使用 toInstant() 时发生这种情况,那是正常的(如果您的系统时区是 UTC + 1),因为即时只“知道”UTC + 0. 但是什么时候使用atZone 应该再次更改为您的系统时区,然后时间被“截断”。

乔达时间

对于Joda-Time,您也可以使用toLocalDate 方法代替toLocalDateTime。

dateTime1.toLocalDate();

或withTimeAtStartOfDay

dateTime1.withTimeAtStartOfDay();

【讨论】:

以上是关于在计算两者之间的周数时避免夏令时的主要内容,如果未能解决你的问题,请参考以下文章

编写一个JAVA类,用于计算两个日期之间的周数。

计算夏令时和非夏令时之间的时间差

怎么取两个日期之间的周数

在计算 DateTimes 之间的持续时间时安全处理夏令时(或任何其他理论上的非常量偏移)

2017计算机学科夏令营上机考试-A判决素数个数

如何计算编号。从当前周到给定周的周数?