【问题标题】:How to show the difference in time after the daylight saving started in Java?如何在 Java 中显示夏令时开始后的时间差异?
【发布时间】:2019-04-10 14:59:52
【问题描述】:

我想检查夏令时开始前后的时间差。我正在使用时区与 DST WRT 巴西时间存在问题的 JVM。我可以看到输出显示 10 月 21 日属于 DST,这是错误的,因为夏令时从 11 月 4 日开始。我想看看 10 月 20 日到 10 月 21 日之间的时间差是 1 小时,由于 JRE 时区问题,我可以在我的申请中看到。有什么办法可以通过程序实现这一点。下面是我用来查看日期是否在 DST 下的代码。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Timezone
{
    public static void main(String[] args) throws ParseException {
        TimeZone TIMEZONE = TimeZone.getTimeZone("Brazil/East");

        System.out.println("timeZone : " + TIMEZONE);
        Calendar c = Calendar.getInstance(TIMEZONE);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        dateFormat.setTimeZone(TIMEZONE);

        Date date = dateFormat.parse("2018-10-20T00:00:00");
        c.setTime(date);
        System.out.println("In dst " + c.getTimeZone().inDaylightTime(c.getTime()));

        date = dateFormat.parse("2018-10-21T00:00:00");
        c.setTime(date);

        System.out.println("In dst " + c.getTimeZone().inDaylightTime(c.getTime()));

        date = dateFormat.parse("2018-11-04T00:00:00");
        c.setTime(date);
        System.out.println("In dst " + c.getTimeZone().inDaylightTime(c.getTime()));

    }
}

进一步补充我的问题,我能够通过使用我的上述程序来确定夏令时。我想要它应该向我展示的东西:10 月 20 日的时间是上午 9 点,而同一时间由于 DST 移动了 1 小时,即上午 10 点。有什么方法可以实现吗?

预期输出:

     timeZone : sun.util.calendar.ZoneInfo[id="Brazil/East"]

         Time is: 21-10-2018 07:52:16

实际输出错误的 JVM:

        timeZone : timeZone : sun.util.calendar.ZoneInfo[id="Brazil/East"]

       Time is: 21-10-2018 08:52:30

【问题讨论】:

  • java.util.Timezone.inDaylightTime(Date date) 等涵盖了这个。
  • 感谢您的回复。使用上述程序,我可以知道夏令时的变化。但我想显示类似 10 月 20 日的时间是上午 9 点,而 10 月 21 日它发生了变化由于错误的 DST 到上午 10 点
  • 如果你突出显示你的JVM的ACTUAL和EXPECTED行为会更好,这样更容易理解这个问题。
  • 您有什么理由使用TimeZone、Calendar、DateFormat、SimpleDateFormat 和Date 类吗?它们都设计得很糟糕,现在已经过时了。我推荐java.time, the modern Java date and time API,。

标签: java timezone dst


【解决方案1】:

解决方案是使用错误(过时的)时区数据修复 JVM。使用 Oracle 的 Time Zone Updater Tool 非常简单。请参阅底部的链接(对于 OpenJDK,请参阅下一个链接)。

如果您想知道您的 JVM “认为”夏令时 (DST) 何时开始,您可以使用以下代码:

    ZoneId zone = ZoneId.of("America/Sao_Paulo");
    ZoneRules rules = zone.getRules();
    ZoneOffsetTransition dstStarted = rules.previousTransition(Instant.now());
    System.out.println(dstStarted);

显然我的 Java 11 有新鲜的时区数据,夏天从 11 月 4 日开始。我得到了这个输出:

过渡[差距在 2018-11-04T00:00-03:00 到 -02:00]

“间隔”是指时钟在夏令时开始时向前调转。时钟向后转动的转换被打印为“重叠”。

如果需要,您还可以查询ZoneOffsetTransition,了解转换前后的本地日期和时间、转换的瞬间、转换前后应用的UTC偏移量、转换的有符号长度(这里 1 小时)和其他信息。

我推荐 java.time,现代 Java 日期和时间 API。您使用的日期时间类 — TimeZone、Calendar、DateFormat、SimpleDateFormat 和 Date — 设计不佳且早已过时。

链接

【讨论】:

  • 提醒:还应更新其主机操作系统、其数据库引擎(如 Postgres)和库(如 Joda-Time)中的时区数据。
【解决方案2】:

我将添加一个非常简短的答案。它表明 1 天不等于 24 小时,即 DST 已更改。我还跨步到 Java 8,因为我更熟悉它。

ZoneId timezone = ZoneId.of("Brazil/East");

ZonedDateTime t = ZonedDateTime.of(2018, 10, 20, 7, 52, 16, 0, timezone);

System.out.println(t);
System.out.println(t.plus(1, ChronoUnit.DAYS));
System.out.println(t.plus(24, ChronoUnit.HOURS));

输出:

2018-10-20T07:52:16-03:00[巴西/东部]
2018-10-21T07:52:16-02:00[巴西/东部]
2018-10-21T08:52:16-02:00[巴西/东部]

【讨论】:

    猜你喜欢
    • 2014-12-30
    • 2013-09-24
    • 2017-07-11
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 2011-10-09
    • 1970-01-01
    相关资源
    最近更新 更多