使用巴西夏令时 (BRST) 时出现日期格式错误

Date format error when use Brazilian Summer Time (BRST)

我在从可变日期 (Sun Oct 21 01:00:00 BRST 2018) 中删除时间时遇到问题,因为当数据来自具有 1 小时差异的数据库时,它会生成计费错误。

只有在巴西夏令时的第一天才会发生这种情况

我已经尝试使用 Calendar class。

public static Date zeroTimes( final Date data ) {
        Calendar cal = Calendar.getInstance();
        cal.setTime( data );
        cal.add( Calendar.HOUR, - 1 );
        return cal.getTime();

    }

这个方法的return就是这个Sun Oct 21 01:00:00 BRST 2018, 但预期的是 Sun Oct 21 00:00:00 BRST 2018

与其尝试减去小时数,不如直接设置为午夜更容易?

Calendar cal = Calendar.getInstance();
cal.setTime(data);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

return(new Date(cal.getTime().getTime()));

在巴西夏令时 (horário de verão) 开始的那一天,时钟从 00:00 向前拨 1 小时到 01:00。这意味着没有00:00的时间,它不存在。所以很抱歉,你不能拥有那个。

  1. 首先:您的 BRST 更改日期是否正确?网上说是 2018 年 11 月 4 日

  2. Secondary: 改为夏令时的一天的日长 仅持续 23 小时,因此如果按小时计费,可能出于计费目的您必须重新考虑如何计算计费。

这里有两个问题:

  • 您的 JVM 有过时的时区数据
  • 根据陈旧的时区数据。
  • ,您正试图从凌晨 1 点减去一个小时,而该日期不存在午夜

2017 年 12 月,巴西政府更改夏令时规定,夏令时从 11 月的第一个星期日开始。请参阅 this page in Portuguese or this page in English 以获取参考。

所以虽然 2018 年的夏季 实际上 从 11 月 4 日开始,但您的 JVM 似乎认为它从 10 月 21 日开始。如果是这样的话,上午 12 点将不存在,因此凌晨 1 点将显示为该日期的开始。您没有告诉我们您在 Date 对象中有什么价值,但我认为这是问题所在。

首先,如果可以的话,我会停止使用 java.util.Datejava.time 类型在很多方面 好得多 。如果您卡在旧版本 Java 上,请使用 JSR-310 backport

其次,更新您的时区数据。有关详细信息,请参阅 this page

第三,确定您希望如何处理 DST 转换。这是我们可能无法提供太多建议的地方,除了 a) 明确地考虑它; b) 编写大量测试。您需要执行的操作的具体细节取决于您的业务规则。 (根据我的经验,决定这些业务规则的人很可能也没有考虑过这一点。不要让他们随意挥手:要求精确的规范。当然要有礼貌:)