java - Calendar.getInstance().getTime() 在 "GMT"中返回日期而不是默认时区

标签 java calendar gettime

Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());

输出:

Tue Sep 12 12:36:24 IST 2017

Mon Jan 01 12:36:24 IST 2007

但是,当我在不同的环境中使用相同的代码时,输​​出变为如下:

输出:

Tue Sep 12 12:36:24 IST 2017

Mon Jan 01 12:36:24 GMT 2007

仅供引用,我尝试在设置值之前和之后打印日历实例的时区,两者都在“IST”中。

我想知道这个问题的根本原因。

最佳答案

您问题中的第二个输出是在运行爱尔兰时间(欧洲/都柏林)的 JVM 上的正确和预期行为。 2017 年 9 月 12 日,爱尔兰正处于夏令时 (DST)。虽然没有明确记录,Date.toString()(打印从 c.getTime() 获得的 Date 时隐式调用它) 打印 JVM 时区中的日期和时间,该时区在 9 月呈现为爱尔兰夏令时的 IST。

当您在 Calendar 对象上设置日期时也使用爱尔兰时间,一天中的小时将被保留;在你的情况下,你得到 Jan 01 2007 12:36:24 Irish standard time。现在想象一下,如果爱尔兰夏令时和爱尔兰标准时间都呈现为 IST,会造成怎样的困惑。你将无法区分。相反,由于爱尔兰标准时间与格林威治标准时间一致,因此当日期在一年中的夏令时部分(一月是't).

我的猜测是您的第一个输出来自运行印度时间的 JVM。它也被呈现为 IST,并且由于印度不使用夏令时,因此使用相同的缩写形式表示夏季和冬季。

java.time

在了解您观察到的行为的解释之前,我发表了一篇关于过时的和现代的 Java 日期和时间类的评论。不过,我仍然认为评论还没有结束。这是您代码的现代版本:

    ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Dublin"));
    System.out.println(zdt);
    zdt = zdt.with(LocalDate.of(2007, Month.JANUARY, 1));
    System.out.println(zdt);

打印

2017-09-12T11:45:33.921+01:00[Europe/Dublin]
2007-01-01T11:45:33.921Z[Europe/Dublin]

如果您想使用 JVM 的时区设置,请使用 ZoneId.systemDefault() 而不是 ZoneId.of("Europe/Dublin")。顾名思义,与 Date 相反,ZonedDateTime 确实包含时区。它更符合旧的 Calendar 类。如您所见,它的 toString 方法打印了 UTC 的偏移量(Z 表示零偏移量)和明确的 region/city 格式。我相信这会减少混淆的空间。如果您想以特定格式打印日期,请使用 DateTimeFormatter

附录:代码输出示例

为了完整起见,以下是运行可能呈现为 IST 的不同时区时代码的输出:

  • Europe/Dublin(同意您的第二个输出)

    Tue Sep 12 11:19:28 IST 2017
    Mon Jan 01 11:19:28 GMT 2007
    
  • 亚洲/特拉维夫

    Tue Sep 12 13:19:28 IDT 2017
    Mon Jan 01 13:19:28 IST 2007
    
  • Asia/Kolkata(同意您的第一个输出)

    Tue Sep 12 15:49:28 IST 2017
    Mon Jan 01 15:49:28 IST 2007
    

关于java - Calendar.getInstance().getTime() 在 "GMT"中返回日期而不是默认时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46170216/

相关文章:

c - clock_gettime 和 CLOCK_PROCESS_CPUTIME_ID 的数字错误

Java - 一次更改字符串中的多个单词?

jsf - @FacesConverter(forClass = Clazz.class) 和 p :calendar

java - Android Studio 下载管理器错误 : IllegalArgumentException Expected file scheme in URI

java - 为什么 Android Calendar.set 方法在第一次修改尝试时给出错误的结果?

java - 项目欧拉 19 : Counting Sundays, Java

Javascript getTime() 函数显示不正确的值?

c - 时间结构使用

java - 如何使用 Selenium 和 Java 手动输入 OTP 后继续自动化

java - 如何防止android中设备旋转的冲突动画?