我的一个项目实现了以下方法,我正在研究日期问题之一,并试图理解下面将给定日期转换为GMT的方法,但与输出混淆。
输入日期值:2010-11-29 04:00:00.0
输出日期值:Sun Nov 28 20:00:00 PST 2010
我的机器在太平洋时区(PST)运行,如果它返回GMT,我希望"2010-11-29 11:00:00.0",你能澄清getRawOffset()方法的目的是什么,为什么它返回该输出?
public static Date convertToGMT(Date date) {
TimeZone jvmTimeZone = TimeZone.getDefault();
long newTime = date.getTime() + jvmTimeZone.getRawOffset();
if (jvmTimeZone.inDaylightTime(date)) {
newTime = newTime + jvmTimeZone.getDSTSavings();
}
return new Date(newTime);
}
PST是UTC-8,因此getRawOffset()
返回一个负值:
2010-11-29 04:00:00.0 + (-8 hours) = 2010-11-28 20:00:00.0
然而,你想做的整个事情都是错误的。
Date
表示瞬间,即时间轴上与任何时区都不关联的点。因此,将Date
从一个时区转换为另一个时区是没有意义的。您可以对Date
做的唯一事情是将其转换为特定时区的本地日期/时间,反之亦然。
我也建议你使用Joda Time。Jode Time使瞬间(DateTime
)和该瞬间的本地表示(LocalDateTime
)之间的区别更加清晰。
代码就是垃圾,因为java.util.Date
总是GMT。它从来都不是一个本地时间戳,所以试图将它从一个假想的本地时间戳转换为GMT在概念上是无意义的。
最初的意图可能是误用Date
作为一种本地时间戳(与它的规范相矛盾),作为对本地时间毫升的薄包装。请记住以下关系:[UTC-millis] + [offset-millis] = [local-millis]我只会使用long
原语来进行计算,而不是j.u date。
因此您可以在代码中看到许多不一致之处。newTime
变量似乎是一种本地millis,但它被包装为j.u.d date,并返回一个假装转换为GMT的方法的结果(更混乱的是几乎不可能的)。
编辑8年后,我们现在有了java.time
包
可以将java.util.Date
实例转换为java.time.Instant
实例。为此,java.util.Date
中添加了新的转换方法。我们都应该知道,一个瞬间与格林尼治标准时间有关,而不是其他。有人能告诉我们下面的代码有什么意义吗?
public static Instant convertToGMTNew(Instant instant) {
java.util.Date date = java.util.Date.from(instant);
return convertToGMTOld(date).toInstant(); // using the method above
}
没有。这是相同的错误。新变了!!Instant确实是基于虚假的计算。Instant
和java.util.Date
没有涉及任何区域计算的转换方法,这是有充分理由的。两者都只与GMT相关,而与任何"本地"无关。瞬间。