2012-01-18 32 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