【发布时间】:2020-01-12 16:18:00
【问题描述】:
几个前提:
- 我所说的“流行时间”是指它在本地的处理方式(我的行业使用这个术语)。例如,东部通行时间的 UTC 偏移量为 -05:00,但 DST 期间为 -04:00
- 我发现通过将最终值视为排他性而不是骇人听闻的包容性方法来处理范围数据要干净得多(您必须从超出末尾的第一个值中减去 epsilon范围)。
例如,根据interval notation,从0(包括)到1(不包括)的值范围是[0, 1),比[0, 0.99999999999...]更具可读性(并且更不容易出现舍入问题和因此出现一个错误,因为 epsilon 值 depends on the data type 正在使用)。
考虑到这两个想法,当结束时间戳无效(即没有凌晨 2 点,它立即变为凌晨 3 点)时,如何表示春季 DST 过渡日的最后一小时时间范围?
[2019-03-10 01:00, 2019-03-10 02:00) 在您选择的支持 DST 的时区。
将结束时间设置为 03:00 非常具有误导性,因为它看起来像是一个 2 小时宽的时间范围。
当我通过这个 C# 示例代码运行它时,它崩溃了:
DateTime hourEnd_tz = new DateTime(2019, 3, 10, 0, 0, 0, DateTimeKind.Unspecified);//midnight on the spring DST transition day
hourEnd_tz = hourEnd_tz.AddHours(2);//other code variably computes this offset from business logic
TimeZoneInfo EPT = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");//includes DST rules
DateTime hourEnd_utc = TimeZoneInfo.ConvertTime(//interpret the value from the user's time zone
hourEnd_tz,
EPT,
TimeZoneInfo.Utc);
System.ArgumentException: '提供的 DateTime 表示无效时间。例如,当时钟向前调整时,被跳过的周期内的任何时间都是无效的。 参数名称:日期时间'
我该如何处理这种情况(在其他地方我已经在处理秋季ambiguous times),而不必对我的时间范围类库进行广泛的重构?
【问题讨论】:
-
放弃
DateTime本身,尤其是DateTimeKind.Unspecified- 至少DateTimeOffset会更好(如果不切换到NodaTime)。这也意味着结束时间始终有效,如果偏移量错误。否则,你实际上想用这个来完成什么? -
旁注:有非小时偏移时区。有非小时 DST 更改。在某些时区,DST 在午夜以外的时间更改(直到并包括使“午夜”无效)。 DST 可能会在不同的月份发生(在南半球,预计跳跃会以另一种方式进行......)。时区 + DST 很复杂,这就是我们试图弄清楚您实际需要做什么的原因。
-
想了几天,我相信你说的很对,
DateTimeKind.Unspecified需要尽量避免(虽然我还是要继续解释SQL ServerDATETIME实例因为其他人都使用这种类型)。我将不得不硬着头皮重构我的代码。附言我不是在尝试实现自己的 DST 规则,而是让TimeZoneInfo.ConvertTime方法为我处理它,并将 DST 规则从标准标识符复制到我的自定义时区定义中。