2012-01-18 68 views
8

是的,关于日期在Java和Javascript中的另一个问题。Javascript日期和java.util.Date构造函数参数

时区格林尼治标准时间+4(莫斯科)在Java和浏览器(铬)。

<script language="javascript"> 
    var d = new Date(170798400000); 
    document.write(d); 
</script> 

给出:孙1975年6月1日00:00:00 GMT + 0400(俄罗斯标准时间)

public class Test { 
    public static void main(String[] args) { 
     java.util.Date d = new java.util.Date(170798400000L); // the same epoch value! 
     System.out.println(d); 
    } 
} 

给出:周六5月31日23时00分零零秒MSK 1975

如果我将时代价值更改为2011 - 2012年(在俄罗斯取消夏令时之后),产量确定。时区更新工具运行正常。

这是一个bug或特征?除了YYYY-MM-dd HH:mm:SS之外,还有什么办法来处理这个格式和重新解析吗?

从Javadoc中:

日期(长日期)

分配Date对象并对其进行初始化,以表示从被称为“历元”标准的基本时间指定的毫秒数,即1月1日,格林威治标准时间1970年00:00:00。

从javascript参考:

新的日期(毫秒)

毫秒 - 代表毫秒数自1 1970年1月的整数值〇点零零分00秒UTC(Unix的时代)。

+0

也许这与“时区更改”有关:http://en.wikipedia.org/wiki/Moscow_Time – 2012-01-18 15:53:59

+0

它的定义是。这是否意味着日期构造函数不能在JavaScript中使用了? – ike3 2012-01-18 15:56:03

+0

那么,如果其中一个给出了正确的答案,而另一个却没有,那么我会说另一个有一个错误:-) Java是正确的还是JavaScript?我希望Java版本能够给出正确的答案,但这只是一个怀疑。 – Pointy 2012-01-18 15:56:08

回答

1

这是一个bug或特征?

这不是Javascript的错误。至少,我看不出我可以声称这一点。

浏览器的Javascript引擎正在返回转换为“GMT + 4”的时间。显然,你想要的是与GMT + 4不同的MSK(正如你的评论所述)。不知道MSK的Javascript不算作错误,但缺少一个功能。也许js对于不具备时区的详细知识是“错误的”,但这不是一个错误。

是否有任何方式来处理,除了格​​式化和重新解析,如YYYY-MM-dd HH:mm:SS等等?

跟踪所有时区的任意细节需要大量的工作。我知道没有这样的代码库,其中包含所有可用于JavaScript的工作。因此,我相信,是的,如果您想使用真正的MSK,则必须自己手动编码该转换。

1

时间的字符串表示(如"Sun Jun 01 1975 00:00:00 GMT+0400")用于人类。时间值(1970年1月1日以来的毫秒)用于存储和计算。

那里没有错误。在JavaScript中,根据规范,字符串表示的内容与实现有关。在Java中,根据文档,可以反映夏令时可能

JavaScript specification

15.9.5.2 Date.prototype.toString ()

此函数返回一个字符串值。字符串的内容是实现 - >依赖的,但旨在以方便的,人类可读的形式表示当前时区中的日期。

Java documentation

java.util.Date, public String toString() 

Converts this Date object to a String of the form: dow mon dd hh:mm:ss zzz yyyy 

where: 
... 
zzz is the time zone (and may reflect daylight saving time).` 
0

TL;博士

Instant.ofEpochMilli(170_798_400_000L) 

1975-05-31T20:00:00Z

......还有......

Instant.ofEpochMilli(170_798_400_000L) 
     .atZone(ZoneId.of("Europe/Moscow")) 

1975-05-31T23:00 + 03:00 [欧洲/莫斯科]

live code

使用java.time

现代的方法使用java.time Java中的类8及更高版本。

您在Java中使用麻烦的旧日期,时间类,现在是遗产。这些类中的许多问题包括在生成字符串时应用当前默认时区的Date::toString方法的善意但易混淆的特性。内部值实际上始终以UTC表示,但toString会产生错觉,即Date实际上没有时区。这解释了你的神秘之处MSK

[更令人困惑的是,实际上是深埋于Date的时区,但与此讨论无关。那些老的Date/Calendar类是一个可怕的混乱。幸运的是,Java现在在任何平台上都有最好的日期 - 时间框架:java.time。

显然,您的输入表示自1970-01-01T00:00:00Z的Unix时代以来的毫秒数。

Instant类表示UTCnanoseconds(最多9个(9)小数的位数)的分辨率在时间轴上的力矩。这个类可以直接解析你的输入号码。

Instant instant = Instant.ofEpochMilli(170_798_400_000L) ; 

instant.toString():1975-05-31T20:00:00Z

如果你想看到的是同一时刻通过特定区域的wall-clock time的镜头,应用时间区。应用ZoneId以获得ZonedDateTime对象。

ZoneId z = ZoneId.of("Europe/Moscow") ; 
ZonedDateTime zdt = instant.atZone(z) ; 

1975-05-31T23:00 + 03:00 [欧洲/莫斯科]

JavaScript库是不正确

的呼叫到JavaScript库的结果不正确,其偏移量为+04:00According to Wikipedia,莫斯科时间从1930年到1981年提前3小时+03:00。 java.time框架在1975年全年的正确结果为+03:00。有关更多信息,请参阅Time in Russia。警告:我不是俄罗斯/苏联时期的专家。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore