Jam*_*aix 2 .net c# timezone datetime
我有一个DateTime实例Kind = DateTimeKind.Utc和一个时间跨度。
var dt = DateTime.UtcNow;
var ts = TimeSpan.FromDays(1);
Run Code Online (Sandbox Code Playgroud)
由于夏令时,当我本地化dt然后添加时,我得到的结果与我添加然后本地化时ts得到的结果不同。ts
var localizedFirst = dt.ToLocalTime() + ts; //Does account for daylight savings
var addedFirst = (dt + ts).ToLocalTime(); //Does not account for daylight savings
Run Code Online (Sandbox Code Playgroud)
这看起来很奇怪。添加本地化偏移量和添加时间跨度偏移量不应该是可交换和关联的吗?
我发现了一个类似的问题:为什么 DateTime.ToLocalTime() 不考虑夏令时?这个问题更多地涉及DateTime到 和 的转换String。DateTime我只从事算术工作TimeSpan。
该问题的最佳答案建议使用DateTimeKind.Unspecified,以便运行时假定未指定的日期是 UTC,然后在本地化时正确转换它。我很惊讶这确实有效。如果我DateTime像这样创建一个新的:
var dt2 = new DateTime(dt.Ticks, DateTimeKind.Unspecified);
Run Code Online (Sandbox Code Playgroud)
然后,两个操作顺序都会返回夏令时的正确结果。
(dt2 + ts).ToLocalTime()
dt2.ToLocalTime() + ts
Run Code Online (Sandbox Code Playgroud)
这一切对我来说似乎很荒谬。为什么我需要将Utc日期转换为正确的Unspecified转换Local?这似乎应该被视为一个错误。
其他详情:
dt:11/5/2017 2:36:13pm UTCts:TimeSpan.FromDays(699)dt:11/5/2017 9:36:13am(dt + ts).ToLocalTime():10/5/2019 10:36:13amdt.ToLocalTime() + ts:10/5/2019 9:36:13am几点:
ATimeSpan代表经过的时间长度。它的“天”是标准天,正好 24 小时长。
当天,在当地时区,由于 DST 回退过渡,有 25 个小时。
对对象的添加DateTime(通过+操作符或Add...函数)始终是在不考虑时区的情况下完成的。换句话说,无论原始.Kind属性是什么,输出都将具有相同的.Kind属性,但在加法/减法过程中根本不考虑类型。
因此,转换为当地时间后添加并不考虑 25 小时的一天。这也是有问题的,因为可能会出现不存在或存在两次的本地时间值。
因此,当您在代码注释中说“是否(或不)考虑夏令时”时,从技术上讲,您已经将其颠倒了。由于 UTC 没有转换,因此该localizedFirst变量是错误地假设本地日期为 24 小时长的结果,而该addedFirst变量是在原始日期后 24 小时后正确应用本地时区 DST 规则的结果时间轴上的点。
另外,设置DateTimeKind.Unspecified不会改变这种情况下的效果,因为该DateTime.ToLocalTime()方法将DateTimeKind.Unspecified视为DateTimeKind.Utc. 请参阅此处文档备注中的表格。 事实上,我试图复制你的结果,但dt2仅仅通过改变类型无法获得任何不同的价值。如果可以的话,请具体说明这一点。
值得指出的是,消除这种混乱正是Noda Time库存在的原因。在 Noda Time 中,这些由两种截然不同的操作表示:
LocalDateTime + Period = LocalDateTimeInstant + Duration = Instant| 归档时间: |
|
| 查看次数: |
1520 次 |
| 最近记录: |