为什么UTC(不是时区)被认为是Java中的时区(而不仅仅是那里)?

yas*_*dev 8 java windows timezone utc timezone-offset

鉴于UTC不是时区,而是时间标准(例如,如此处所述),为什么在我的Java应用程序中我可以使用UTC,就好像它是一个时区(请参阅下面的代码片段)?

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Run Code Online (Sandbox Code Playgroud)

如果UTC不是时区,为什么TimeZone.getTimeZone("UTC")能够返回时区对象?


顺便说一句,在我的Windows机器上,UTC也在时区列表中(参见屏幕截图).

声明"UTC不是时区"实际上是错误的吗?

UTC是Windows中的时区

Jon*_*eet 13

因为它使生活变得更加简单,将UTC视为一个时区比将其视为其他东西要简单得多.

它是其中之一"是的,严格来说不是"场景.除了"观察到世界哪个地区?"之外的所有事情.您可以将UTC视为时区,它可以正常工作.因此,将其略微弯曲变形比使用完全独立的概念更简单.

如果您将时区视为从"即时"到"UTC偏移"(或等效,从"即时"到"本地观察时间")的映射,则可以将UTC视为时区 - 并且这是我们在软件中所做的大部分工作.

如果您将时区视为地理区域以及该映射,那么不,它不起作用 - 但这在软件中很少有用.(并且你可以通过说它是一个空的区域来假装它:)

  • @Alnitak:不,给这些地方提供他们自己的时区(或时区集合)更准确,这些时区碰巧总是有UTC偏移0.请注意,可能有一段时间的历史,他们*没有*UTC偏移为0,这是为其提供特定ID有用的一个原因. (4认同)

小智 7

声明"UTC不是时区"实际上是错误的吗?

从技术上讲,严格来说,声明并没有错.UTC是标准,而不是时区(因为您已经链接).

时区对应于世界上的某个地区,并且有关该地区的许多不同规则:

  • 什么是UTC偏移(与UTC的差异)在夏令时和什么时候不是
  • 当DST开始和结束时
  • 该区域的偏移和夏令时的所有变化都在其历史中

例如:在1985年,巴西的阿克里州有标准偏移UTC-05:00(UTC-04:00在DST期间),然后在1988年UTC-05:00没有DST,然后在2008年标准变为UTC-04:00(并且没有DST),并且自2013年以来它又回到了UTC-05:00没有夏令时.

虽然时区会跟踪所有这些更改,但UTC没有此类规则.您可以通过多种方式考虑UTC:

  • "基础"日期/时间,其他人相对于此 - 与UTC的这种差异称为"偏移".今天,圣保罗UTC-03:00(在距离UTC时减去3小时,或3小时后),而东京则在UTC+09:00(加9小时,或比UTC早9小时).
  • 一个永不变化的"特殊"时区.它始终处于相同的偏移(零),它永远不会改变,并且永远不会有DST转换.

由于"UTC的偏移"(不确定这个术语在技术上如何准确)始终为零,因此写入的常见UTC+00:00或仅是Z.

UTC和时区之间的另一个区别是,时区由政府和法律定义,可以随时随地进行更改.上述Acre的所有变化都是由政治家定义的,无论他们当时想到什么原因.(因此,即使今天的某个地区在其时区中遵循UTC,也不能保证它在未来会保持不变,这就是为什么即使这些地区也有自己的时区,即使它们看起来多余).

但无论政治家改变他们的地区抵消多少次,他们必须相对于UTC(当然,直到新的标准出现).


现在,当您看到类似的实现时TimeZone.getTimeZone("UTC"),您可以通过两种不同的方式来考虑它:

对我来说,它是两者的混合(五十/五十).


新java.time API,虽然分隔概念2类:ZoneRegionZoneOffset(实际上都是的子类ZoneId,而ZoneRegion不是公共所以实际上我们使用ZoneIdZoneOffset):

  • 如果您使用的是ZoneIdIANA时区的名称(总是在格式Continent/City,如America/Sao_PauloEurope/Berlin),它会创建一个ZoneRegion对象-所有的DST规则"真正的"时区和它的历史过程中所抵消.因此,根据您在此处使用的日期,您可以拥有不同的偏移量ZoneId.
  • 如果您使用的是ZoneOffset(有Z,UTC,+03:00等),它将只返回一个代表偏移的对象:从UTC的差异,但没有任何DST规则.无论您使用此对象的日期,它始终与UTC具有相同的差异.

因此,ZoneId(实际上ZoneRegion)与某些区域(在某些时区)的抵消随时间变化的想法是一致的(由于DST规则,政客因为任何事情而改变事物等).并且ZoneOffset表示与UTC不同的想法,它没有DST规则且永远不会改变.

并且有一个特殊常量ZoneOffset.UTC,它表示与UTC(UTC本身)的差异.请注意,新API采用了不同的方法:它不是说所有内容都是时区而UTC是特殊类型,它表示UTC是ZoneOffset偏移值为零的值.

您仍然可以认为这是一个"错误的"设计决策或简化使事情变得更容易(或两者兼而有之).IMO,这个决定与旧版本相比是一个很大的进步java.util.TimeZone,因为它清楚地表明UTC不是一个时区(在某种意义上说它没有DST规则且永远不会改变),它只是与UTC标准的零差异(非常说"它是UTC"的技术方式.

它还将时区和偏移的概念分开(虽然彼此非常相关,但这些概念并不相同).我看到它将UTC定义为特殊偏移量作为"实现细节".创建另一个只是处理UTC的类将是多余的和令人困惑的,并将其保持为ZoneOffset一个很好的决定,简化了事情并且没有弄乱API(对我来说,这是一个公平的权衡).

我相信许多其他系统决定采取类似的方法(这解释了为什么Windows在时区列表中有UTC).