C# 和 JavaScript 之间的时间跨度差异说明

2024-02-23

这是基于在 C# 中计算 1970 年以来的毫秒数会产生与 JavaScript 不同的日期 https://stackoverflow.com/q/22081128/1346943 and Javascript Date.getTime() 的 C# 版本 https://stackoverflow.com/q/8134170/1346943.

对于所有这些计算,假设它们是在中部标准时间完成的,因此比 UTC 晚 6 小时(此偏移稍后会再次出现)。

我理解 JavaScriptDate对象基于 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 纪元以来的毫秒数。这一切都很好。在链接的问题中,人们询问是否将此功能转换为 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 纪元DateTimeKind of Unspecified能够匹配JavaScript。我们不应该使用得到正确的结果吗DateTimeKind.Utc?我不明白什么细节?这对我来说纯粹是一个学术问题,我只是好奇为什么会这样。


正如您正确指出的那样,.getTime() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime回报“自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。”

意思就是.getTime(正如您所注意到的)在计算中包括与 UTC 的偏移量。

为了使 C# 代码反映这一点,您要从中减去的时间must包括时区信息,而 1 一月 1970 00:00:00must是 UTC 时间。

通过几个例子可能会更容易理解。鉴于:

DateTime e = new DateTime(2014, 2, 28, 0, 0, 0);
DateTime s = new DateTime(1970, 1, 1, 0, 0, 0);
  1. e - s是不正确的,因为s不是 UTC 时间。
  2. e.ToUniversalTime() - s.ToUniversalTime()是不正确的,因为e不再包含相对 UTC 的偏移量(就像 JavaScript 中的计算那样)
  3. e.ToUniversalTime() - s is正确,因为我们使用的是 UTC 时间and我们减去的时间包括与 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,而我们处理的时间仍然有其原始偏移量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 和 JavaScript 之间的时间跨度差异说明 的相关文章

随机推荐