日历以错误的时区返回日期

Dón*_*nal 7 java datetime date

如果我在GMT时区的计算机上执行以下操作

TimeZone timeZone = TimeZone.getTimeZone('IST');  // India Standard Time
Calendar calendar = Calendar.getInstance(timeZone);

System.out.println(calendar.getTime());
Run Code Online (Sandbox Code Playgroud)

它打印

10月31日星期五15:18:22 GMT 2014

为什么日期印在计算机的默认时区,而不是TimeZoneCalendar与构建?

Bas*_*que 9

Joshi答案是正确的,但很简短.我会扩展一下,并展示现代课程的替代方案.

Date 没有时区

您的代码从对象中calendar.getTime()提取对象.java.util.Datejava.util.Calendar

java.util.Date班有一个善意的,但令人困惑的特征,其中的toString方法适用于JVM的当前默认时区而产生的字符串.这就产生了一种错觉,即当Date类没有时区时,它会有一个时区.A Date表示时间线上的时刻,作为自UTC UTC(1970-01-01T00:00:00Z)的第一时刻的纪元参考日期以来的毫秒数.(更令人困惑的是,Date该类实际上确实有一个位于内部深处的时区,但是无法访问且与此讨论无关.)

避免遗留日期时间类

旧的日期时间类现在已经遗留下来,取而代之的是java.time类.而是只使用java.time类.

Instant

在UTC中,相当于java.util.Date,使用Instant该类.该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多9个(9)小数的位数).

Instant instant = Instant.now();  // Current moment in UTC.
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime

要通过特定区域的挂钟时间镜头查看同一时刻,请应用a ZoneId来获取a ZonedDateTime.

指定适当的时区名称,格式continent/region,如America/Montreal,Africa/CasablancaPacific/Auckland.切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );
Run Code Online (Sandbox Code Playgroud)

搜索Stack Overflow以获取有关此主题的许多其他问题和解答.这个问题实际上与许多其他问题重复.


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.


Jig*_*shi 5

因为Date对象没有时区作为其状态的一部分,所以您需要SimpleDateFormat来格式化和打印所需时区中的日期