【发布时间】:2017-06-28 22:09:02
【问题描述】:
我正在使用 java 日历在午夜 (GMT) 创建某个日期,然后将时区更改为我的本地时区,以确保请求的时间为 1:00 (GMT +1)。 下面的代码有效,包括。 2 个成功的断言。
TimeZone TIMEZONE_GMT = TimeZone.getTimeZone("GMT");
TimeZone TIMEZONE_LOCAL = TimeZone.getDefault(); // GMT + 1
private Calendar getMidnightGmtCalendarWithLocalTimezone() {
Calendar calendar = Calendar.getInstance(Locale.GERMAN);
calendar.set(2017, Calendar.JANUARY, 1, 0, 0, 0);
calendar.setTimeZone(TIMEZONE_GMT); // Probably not required
assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY)); // Assert 1
// Log.i("TAG", "" + calendar.get(Calendar.HOUR_OF_DAY));
calendar.setTimeZone(TIMEZONE_LOCAL);
assertEquals(1, calendar.get(Calendar.HOUR_OF_DAY)); // Assert 2
return calendar;
}
现在我删除了第一个断言,我预计不会有任何变化。现实:第二个断言现在失败了!我试图理解 .get() 的实现,显然它也计算了一些时间,所以它不仅仅是收集值。我仍然不明白为什么我的第二个断言失败了。
当我取消注释 Log 行时,第二个断言再次成功(只是为了确保问题来自 calendar.get(),而不是断言!)
所以第一个问题:为什么会发生这种情况? 第二个问题:当我将时间设置为格林威治标准时间的午夜时,如何确保我有一个本地时区的日历实例? (换句话说,我怎样才能正确转换时区?)
编辑: 我在 Android 上使用它,所以不能使用 Java8。 Joda time(如下所示)是一个很好的选择,我一定会研究一下。但是,作为我的问题的答案,我想知道 Java7 日历是如何工作的,因为我目前必须使用该代码。
【问题讨论】:
-
如果您使用的是 JDK 8,我建议您放弃 Calendar 并尝试使用新的 java.time 包。您应该这样做 - 它是唯一一个没有超过其支持生命周期的 JDK。跨度>
-
@duffymo 我完全同意你的看法,只是想知道,你能否提供任何关于为什么应该放弃使用
Calendar类的权威描述? -
权威? java.util.Calendar 是 JDK 1.0 的经典版本。从一开始就承认它复杂且难以使用。 (如果我没记错的话,由 IBM 编写。)开发 JODA 是为了解决这些问题。它非常成功,Oracle 将它作为 java.time 包折叠到 JDK 8 中。日历是超过 20 年的故障。它已被公认的巨大改进所取代。我根据历史要求权威。这对你来说足够了吗?
-
@duffymo 澄清一下,Joda-Time 启发了 java.time,并由同一个人 Stephen Colbourne 领导。但是 java.time 是重新设计的,不是 Joda-Time 的替代品。所以你关于“折叠成”的句子过于简单化了。否则你的观点是正确的:java.time 类内置于 Java 8 和更高版本中,以取代令人困惑和有缺陷的旧日期时间类,例如
Calendar和Date,它们现在是 legacy。 java.time pkg 文档的第一行:日期、时间、瞬间和持续时间的主要 API。 -
@BasilBourque,感谢您的更正。我很欣赏这种教育。
标签: android calendar timezone java-7