1º;夏时制的一天Java和JS表现出不同的行为

1º;夏时制的一天Java和JS表现出不同的行为,java,javascript,dst,Java,Javascript,Dst,假设2012年10月21日00:00:00,巴西利亚格林尼治时间-0300:DST,此时时钟应提前一小时 爪哇 Chrome/FireFox(控制台) Java中的结果是我所期望的,但JS中的结果我无法理解。我在比约德说的地方找到了这个 这是绝对正确的行为 但没有解释为什么这种行为是可以的 我的问题是: 为什么JS返回过去一小时的日期? 另外,我知道日期标记为“弃用”,但我使用的是GWT;日期是我唯一的选择。就我所知,这个答案基本上是不正确的。我甚至对Java版本也不完全满意 从根本上说,您试图

假设2012年10月21日00:00:00,巴西利亚格林尼治时间-0300:DST,此时时钟应提前一小时

爪哇

Chrome/FireFox(控制台)

Java中的结果是我所期望的,但JS中的结果我无法理解。我在比约德说的地方找到了这个

这是绝对正确的行为

但没有解释为什么这种行为是可以的

我的问题是:

为什么JS返回过去一小时的日期?


另外,我知道日期标记为“弃用”,但我使用的是GWT;日期是我唯一的选择。

就我所知,这个答案基本上是不正确的。我甚至对Java版本也不完全满意

从根本上说,您试图构建一个从未发生过的本地日期/时间。从当地时间转换为UTC总是很棘手,因为有三种可能性:

  • 清晰的地图,在大多数时区,每年只有两个小时是这样的
  • 不明确的映射,在向后转换期间,相同的本地时间段出现两次(例如,本地时间为12:59 AM、1:00、…1:59 AM、1:00、1:59 AM、2:00)
  • “间隙”映射,其中本地时间段根本不存在(例如,本地时间为上午12:59、凌晨2点、凌晨2:01)
巴西在午夜将时钟向前移动,因此当地时间实际上是:

October 20th 11:58pm
October 20th 11:59pm
October 21st 01:00am
October 21st 01:01am
你要求的当地时间根本没有发生。看起来Java只是假设您想要向前滚动它。。。然而JavaScript正在变得混乱:(例如,如果您要求在2013年2月16日开始时为午夜,JavaScript结果会更容易理解(但仍然不正确)——时钟会回到15日晚上11点。16日上午12点是明确的,因为它只能发生在“秒”之后15日晚上11点至11点59分


一个好的日期/时间API(在我非常有偏见的观点中)会迫使你在转换时说出你希望如何产生歧义和间隙。

在我看来,间隙只能有一种(非异常抛出)方法来处理它们,即“假装某人忘记调整手表”这就是Java在本例中所做的。但问题的一部分是,日期构造函数没有使用时区参数,因此它们在本地时区中运行…这使得解析这些日期更加困难,因为实际上,本地时区在切换过程中会发生变化。如果它们使用时区参数t如果没有歧义或间隙…只留下闰秒问题;-)@StephenConnolly:不,假设您仍然在该时区内表示本地日期/时间,那么仍然会有歧义/间隙问题。时区本身不会改变(例如,无论是英国夏令时还是格林威治标准时间,我仍在欧洲/伦敦时区)。间隙也可以用各种方式处理——它可以返回间隙前的最后一个瞬间、间隙后的第一个瞬间、“假装某人忘记调整手表”瞬间,或者抛出异常。(IMO,抛出异常绝对是一种选择。)我理解您解释的三种可能性,但返回到晚上11点不应该发生,因为无法确定2013年2月15日晚上11:00:00到晚上11:59:59是否为DST。这不是问题,因为我们在DST结束时没有“差距”。那么,我应该接受JS完全错误的答案吗?@Mauro:我将重写关于二月部分的部分;晚上11点会模棱两可,但上午12点不会。是的,在这种情况下,它看起来真的,真的像一个JS bug。@JonSkeet,不,我是说时区应该始终是构造函数的一部分,因为指定“BRT”或“BRST”将消除这个问题。。。在corse中,那些3/4字母的代码不是唯一的。。。IST也被其他国家使用,不仅仅是“爱尔兰夏季”
new Date(2012, 9, 21, 0, 0 ,0)
Sat Oct 20 2012 23:00:00 GMT-0300 (Hora oficial do Brasil)
October 20th 11:58pm
October 20th 11:59pm
October 21st 01:00am
October 21st 01:01am