getRawOffset方法的时区混淆



我的一个项目实现了以下方法,我正在研究日期问题之一,并试图理解下面将给定日期转换为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确实是基于虚假的计算。Instantjava.util.Date没有涉及任何区域计算的转换方法,这是有充分理由的。两者都只与GMT相关,而与任何"本地"无关。瞬间。

相关内容

  • 没有找到相关文章

最新更新