猿问

JS 和 .NET 夏令时行为之间的差异

我试图让 C# 和 JS 在 JSDate和 .NETDateTime对象上添加分钟数时生成相同的结果。我的系统使用希腊文化设置,但很可能您会在您的计算机上得到类似的结果(如果您使用这些值)。我有这个使用 moment.js 的 JS 代码:


var dt1 = new Date(2020, 0, 19, 0, 0, 0);

var m1 = moment(dt1);

[m1.toString(), m1.add(100980, 'minutes').toString()]


>  ["Sun Jan 19 2020 00:00:00 GMT+0200", "Sun Mar 29 2020 04:00:00 GMT+0300"]

..LinqPad 中的 C# 代码:


var ci = CultureInfo.CreateSpecificCulture("el-GR"); //CultureInfo.InvariantCulture; //CultureInfo.CurrentCulture;

var dt = new DateTime(2020, 1, 19, 0, 0, 0, 0, ci.Calendar, DateTimeKind.Local);

dt.ToString("G", ci).Dump();

var dt2 = dt.AddMinutes(100980);

dt2.ToString("G", ci).Dump();


> 19/1/2020 12:00:00 πμ

> 29/3/2020 3:00:00 πμ

...并且在使用不变文化进行打印时:


var ci = CultureInfo.CreateSpecificCulture("el-GR"); //CultureInfo.InvariantCulture; //CultureInfo.CurrentCulture;

var dt = new DateTime(2020, 1, 19, 0, 0, 0, 0, ci.Calendar, DateTimeKind.Local);

dt.ToString("G", CultureInfo.InvariantCulture).Dump();

var dt2 = dt.AddMinutes(100980);

dt2.ToString("G", CultureInfo.InvariantCulture).Dump();


> 01/19/2020 00:00:00

> 03/29/2020 03:00:00

有人能告诉我为什么会得到不同的结果吗?系统设置是相同的,我尝试使用两者CurrentCulture,但 CreateSpecificCulture("el-GR")没有得到与 JS 结果有任何相似之处。


我什至用JS创建了自己的addMinutes(),但仍然有同样的问题。


看起来 JS 正好在开始日期后的 100980 分钟执行夏令时切换(如果添加 100979 分钟,您就会看到这一点),但 C# 却没有!根据维基百科,JS 的行为是正确的行为。但到目前为止我非常确定 .NET 也是正确的。根据我所做的快速测试,C# 似乎在 70.2 天前进行了切换。


在向日期添加分钟数时,为了在两种语言之间获得相同的结果,我需要做什么?


交互式爱情
浏览 97回答 2
2回答

Helenr

问题是调用是在withAddMinutes上完成的。尽管有这种标记,但对象的数学运算并不考虑时区。 即使是当地时间。DateTimeDateTimeKind.LocalDateTime由于您使用的是本地类型,因此您可以简单地转换为 UTC,进行数学计算,然后再转换回来。var dt2 = dt.ToUniversalTime().AddMinutes(100980).ToLocalTime();您可能还想考虑使用该DateTimeOffset类型,并使用TimeZoneInfo.ConvertTime.

繁华开满天机

NodaTime正如我在问题更新中所写的那样,我最终使用了。它仍然不同意moment.js所有的时间,但我觉得它更经常地同意它。我想夏令时是一个巨大的混乱,没有人能够很好地处理它。
随时随地看视频慕课网APP
我要回答