[英]Explanation for Timespan Differences Between C# and JavaScript
這基於自1970年以來的計算毫秒數,C#產生的日期不同於 Javascript Date.getTime()的 JavaScript和C#版本 。
對於所有這些計算,假設它們在中央標准時間內完成,因此比UTC低6小時(此偏移將在稍后再次出現)。
據我所知,JavaScript Date
對象基於Unix Epoch(1970年1月1日午夜)。 所以,如果我這樣做:
//remember that JS months are 0-indexed, so February == 1
var d = new Date(2014,1,28);
d.getTime();
我的輸出將是:
1393567200000
這表示自Unix Epoch以來的毫秒數。 這一切都很好。 在鏈接的問題中,人們要求將此功能轉換為C#,而“天真”的實現通常看起來像這樣:
//the date of interest in UTC
DateTime e = new DateTime(2014, 2, 28, 0, 0, 0, DateTimeKind.Utc);
//the Unix Epoch
DateTime s = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
//the difference between the two
TimeSpan t = (e - s);
var x = t.TotalMilliseconds;
Console.WriteLine(x);
哪個產生輸出:
1393545600000
這是21,600,000毫秒或6小時的差異:與完成這些計算的時區的UTC的精確偏差。
為了使C#實現與JavaScript匹配,這是實現:
//DateTimeKind.Unspecified
DateTime st=new DateTime(1970,1,1);
//DateTimeKind.Unspecified
DateTime e = new DateTime(2014,2,28);
//translate e to UTC, but leave st as is
TimeSpan t= (e.ToUniversalTime()-st);
var x = t.TotalMilliseconds;
Console.WriteLine(x);
這將給我輸出匹配JavaScript輸出:
1393567200000
我還沒有找到解釋為什么我們將DateTime
表示Unix Epoch與DateTimeKind
Unspecified
以便能夠匹配JavaScript。 我們不應該使用DateTimeKind.Utc
獲得正確的結果嗎? 我不明白什么細節? 這對我來說是一個純粹的學術問題,我只是好奇為什么這樣做。
正如您正確指出的那樣, .getTime()
返回“自1970年1月1日00:00:00 UTC以來的毫秒數”。
這意味着.getTime
(正如您所注意到的)包括計算中與UTC的偏移量。
為了使C#代碼反映這一點,您從中減去的時間必須包括時區信息,而1970年1月1日00:00:00 必須是UTC時間。
通過一些示例可能更容易理解。 鑒於:
DateTime e = new DateTime(2014, 2, 28, 0, 0, 0);
DateTime s = new DateTime(1970, 1, 1, 0, 0, 0);
e - s
不正確,因為s
不是UTC時間。 e.ToUniversalTime() - s.ToUniversalTime()
不正確,因為e
不再包含UTC的偏移量(就像JavaScript中的計算一樣) e.ToUniversalTime() - s
是正確的,因為我們正在使用UTC時間,而我們減去的時間包括與UTC的偏移量。 當我直接處理DateTime.Ticks
時,這對我來說更容易看到:
e.Ticks // 635291424000000000
s.Ticks // 621355968000000000
e.Ticks - s.Ticks // 13935456000000000 ("naive" implementation)
e.ToUniversalTime().Ticks - s.Ticks // 13935636000000000 (correct output)
同樣,最后一個例子符合我們的所有要求。 Unix紀元是UTC,而我們處理的時間仍有其原始偏移量。
據我所知,JavaScript Date對象基於Unix Epoch(1970年1月1日午夜)。
對,他們是。 在內部,距離紀元只有幾毫秒。 但是當你調用日期構造函數,或者查看.toString()
的輸出時,它正在使用運行代碼的本地時間。
如果您希望以UTC格式指定輸入,則必須使用不同的咒語:
var ts = Date.UTC(2014,1,28); // returns a numeric timestamp, not a Date object
var dt = new Date(ts); // if you want a date object
var s = dt.toUTCString(); // if you want the output to be in UTC
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.