在 Java 中将 IST 转换为 GMT 时出现问题



我在将 IST 转换为 GMT 时遇到了奇怪的问题。转换全天候正常工作,除了下午 5:30 和下午 6:30。在此期间,不是将时间转换为 12

:00:00,而是转换为 00:00:00

好的,所以我猜IST的意思是印度标准时间;即GMT + 5:30。

因此,下午 5:30 IST 将是格林威治标准时间中午 12:00,即使用传统的 24 小时制的 12:00:00。 (或者他们过去所说的"铁路时间"。

在没有您进一步输入的情况下,我最好的猜测是,要么您在处理代码时遇到了一些错误(例如,输入时间不是您认为的那样),要么区域设置存在一些奇怪的东西,影响了时间的显示方式。

我在这个答案中使用了 24 小时制来保持清晰。

您确定要从 17:30 IST 转换吗?如果您实际转换 05:30(即早上五点半),那将恰好是格林威治标准时间午夜。在 24 小时制中,午夜是 00:00,所以这一切都会加起来。

然而,这并不能解释从 06:30 开始的转换,这将是格林威治标准时间 01:30。

tl;dr

ZonedDateTime.of( 2017 , 1 , 23 , 17 , 30 , 0 , 0 , ZoneId.of( "Asia/Kolkata" ) ) 
             .toInstant()

2017-01-23T12:00:00Z

信息不足

如果不看到有问题的代码,就不可能准确地回答这个问题。但是我可以向你展示正确的现代代码,使用java.time类。

使用 java.time

您所说的"IST"是指印度标准时间、爱尔兰标准时间还是伊朗标准时间?给定示例数据,我猜测印度时间。

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

ZoneId z = ZoneId.of( "Asia/Kolkata" );
LocalDate localDate = LocalDate.of( 2017 , 1 , 23 );
LocalTime localTime = LocalTime.of( 17 , 30 ); // 5:30 PM.
ZonedDateTime zdt = ZonedDateTime.of( localDate , localTime , z );

要通过 UTC 的镜头查看同一时刻,请提取InstantInstant 类以 UTC 表示时间轴上的一个时刻,分辨率为纳秒(最多九 (9) 位小数)。

Instant instant = zdt.toInstant();

查看此代码在 IdeOne.com 实时运行。

此时,印度时间比 UTC 早五个半小时。因此,将加尔各答下午 5:30 调整为 UTC 意味着减去 5 小时 30 分钟,这会让我们回到 UTC 的中午。所以你在结果中看到。

zdt.toString(): 2017-01-23T17:30+05:30[亚洲/加尔各答]

即时字符串(): 2017-01-23T12:00:00Z


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧旧日期时间类,如java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅 Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。

从哪里获得java.time类?

  • Java SE 8SE 9 及更高版本
    • 内置。
    • 具有捆绑实现的标准 Java API 的一部分。
    • Java 9添加了一些小功能和修复。
  • Java SE 6SE 7
    • 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
  • 人造人
    • ThreeTenABP项目专门为Android改编了ThreeTen-Backport(如上所述)。
    • 请参阅如何使用ThreeTenABP...

ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

最新更新