Calendar.getInstance()。getTime()返回“ GMT”中的日期代替默认时区 [英] Calendar.getInstance().getTime() returning date in "GMT" instead of Default TimeZone

查看:783
本文介绍了Calendar.getInstance()。getTime()返回“ GMT”中的日期代替默认时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

输出:


IST 2017年9月12日星期二12:36:24

Tue Sep 12 12:36:24 IST 2017


IST Jan 2007年1月1日12:36:24

Mon Jan 01 12:36:24 IST 2007


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

But, When I use the same code in a different environment, Output changes to below:

输出:


Tue Sep 12 12:36:24 IST 2017

Tue Sep 12 12:36:24 IST 2017


Mon Jan 01 12:36:24 GMT 2007

Mon Jan 01 12:36:24 GMT 2007


仅供参考,我尝试在设置值之前和之后打印日历实例的时区,并且两者都在 IST中。

FYI, I tried to print the timezone of the calendar instance, before and after setting the values and both are in "IST".

我想要知道其根本原因。

I want to know the root cause of this.

推荐答案

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

The second output in your question is the correct and expected behaviour on a JVM running Irish time (Europe/Dublin). On September 12, 2017 Ireland is on summer time (DST). While it is not clearly documented, Date.toString() (which you invoke implicitly when printing the Date you get from c.getTime()) prints the date and time in the JVM’s time zone, which in September is rendered as IST for Irish Summer Time.

同时使用爱尔兰时间在日历对象上设置日期时,将保留一天中的小时;就您而言,您将获得Jan 01 2007 12:36:24爱尔兰标准时间。现在想象一下,如果将爱尔兰夏令时和爱尔兰标准时间都渲染为IST会造成混淆。您将无法区分。相反,由于爱尔兰的标准时间与格林尼治标准时间一致,因此当夏令时的日期为 not 时, Date.toString()会显示此内容

When you set the date on the Calendar object also using Irish time, the hour of day is preserved; in your case you get Jan 01 2007 12:36:24 Irish standard time. Now imagine the confusion if both Irish Summer Time and Irish Standard Time were rendered as IST. You would not be able to distinguish. Instead, since Irish standard time coincides with GMT, this is what Date.toString() prints when the date is not in the summer time part of the year (which January isn’t).

我的猜测是,您的第一个输出来自运行印度时间的JVM。它也被渲染为IST,并且由于印度不使用夏季时间,所以夏季和冬季也使用相同的缩写。

My guess is that your first output is from a JVM running India time. It too is rendered as IST, and since India doesn’t use summer time, the same abbreviation is given summer and winter.

在理解您观察到的行为的解释之前,我发表了有关过时的Java日期和时间类的评论。不过,我仍然认为该评论不会消失。这是您代码的现代等效项:

Before understanding the explanation for the behaviour you observed, I posted a comment about the outdated and the modern Java date and time classes. I still don’t think the comment is way off, though. This is the modern equivalent of your code:

    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

If you want to use the JVM’s time zone setting, use ZoneId.systemDefault() instead of ZoneId.of("Europe/Dublin"). As the name states, contrary to Date, ZonedDateTime does include a time zone. It corresponds more to the old Calendar class. As you can see, its toString method prints the offset from UTC (Z meaning zero offset) and the time zone name in the unambiguous region/city format. I believe that this leaves a lot less room for confusion. If you want to print the date in a specific format, use a DateTimeFormatter.

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

For the sake of completeness, here are the outputs from your code when running different time zones that may be rendered as IST:


  • 欧洲/都柏林(同意您的第二笔输出)

  • Europe/Dublin (agrees with your second output)

Tue Sep 12 11:19:28 IST 2017
Mon Jan 01 11:19:28 GMT 2007


  • 亚洲/特拉维夫

  • Asia/Tel_Aviv

    Tue Sep 12 13:19:28 IDT 2017
    Mon Jan 01 13:19:28 IST 2007
    


  • 亚洲/加尔各答(同意您的第一笔输出)

  • Asia/Kolkata (agrees with your first output)

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


  • 这篇关于Calendar.getInstance()。getTime()返回“ GMT”中的日期代替默认时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆