鉴于UTC不是一个时区,而是一个时间标准(例如这里所述 ),为什么在我的Java应用程序中,我可以使用UTC,就好像它是一个时区(请参阅下面的代码段)?
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); format.setTimeZone(TimeZone.getTimeZone("UTC"));
如果UTC不是时区,为什么TimeZone.getTimeZone("UTC")
能够返回时区对象?
顺便说一句,在我的Windows机器上,UTC也在时区列表中(见屏幕截图)。
“UTC不是时区”这句话实际上是错的吗?
“UTC不是时区”这句话实际上是错的吗?
严格来说,这个说法并没有错。 UTC是一个标准,而不是一个时区 (如你已经链接)。
时区对应于世界上的一些地区,并且在该地区有许多不同的规则:
例如:在1985年,英国的巴西状态标准偏差UTC-05:00
(在DST期间UTC-04:00
),然后在1988年,没有DST的UTC-05:00
,那么在2008年标准改为UTC-04:00
(也没有DST),自2013年起,又回到UTC-05:00
,没有DST。
虽然时区跟踪所有这些变化,UTC没有这样的规则。 您可以用许多不同的方式来想到UTC:
UTC-03:00
(偏移量为负3小时 ,或UTC后3小时),而东京在UTC+09:00
( 正9小时或9小时抵消UTC)。 由于“UTC的偏移量”(不确定这个术语在技术上的准确度)总是为零,所以通常写成UTC+00:00
或者只是Z
UTC与时区的另一个区别在于,时区是由政府和法律界定的,可随时随地更改。 以上所述的阿克里所有的变化都是由政治家定义的,无论他们当时是怎么想的。 (所以,即使今天一个地区在他们的时区跟随UTC,也不能保证它将来保持不变,这就是为什么即使这些地区有自己的时区,即使它们看起来多余)。
但是无论政治家们多少次改变他们的区域偏移量,他们都必须和UTC相关(当然, 直到有新的标准出现 )。
现在,当你看到像TimeZone.getTimeZone("UTC")
这样的实现TimeZone.getTimeZone("UTC")
,你可以用两种不同的方式来思考它:
对我来说,这是两个(五十/五十)的组合。
然而, 新的java.time API将两个概念分开: ZoneRegion
和ZoneOffset
(实际上两者都是ZoneId
子类,但ZoneRegion
不公开,所以实际上我们使用ZoneId
和ZoneOffset
):
ZoneId
(始终采用Continent/City
格式,如America/Sao_Paulo
或Europe/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
,它的偏移量为零。
你仍然可以认为这是一个“错误”的设计决策或简化,使事情变得更容易(或两者兼而有之)。 国际海事组织,这个决定是一个很大的改善,比旧的java.util.TimeZone
,因为它明确指出,UTC不是一个时区(在它没有DST规则,永远不会改变),这只是一个零差UTC标准(一种非常技术性的说法是“它是UTC”)。
它也将时区和偏移量的概念分开(虽然这些概念是非常相关的,但并不是一回事)。 我看到它将UTC定义为一个特殊的偏移量作为“实现细节”。 创建另一个类只是为了处理UTC将是多余的和混乱的,保持它作为一个ZoneOffset
是一个很好的决定,简化的事情,并没有搅乱API(对我来说,公平的权衡)。
我相信许多其他系统决定采取类似的方法(这解释了为什么Windows在时区列表中有UTC)。
因为它使得生活更加简单,基本上把UTC看作是一个时区,而不是把它当作别的东西。
这是其中之一“ 严格来说,这不是”情景。 除了“观察到世界上哪个地区? 你可以把UTC看作是一个时区,它工作的很好。 所以把它稍微弯曲一点,比把整个单独的概念弯曲起来简单些。
如果您将时区视为从“时间即时”到“UTC偏移”(或等效,从“即时即时”到“本地观察时间”)的映射,那么UTC可以很好地视为时区 – 这是我们在软件中所做的大部分工作。
如果您将时区视为地理区域以及该映射,那么不会,这样做效果不佳 – 但在软件中这种情况更少。 (你总是可以假装说它是一个空的区域:)