【问题标题】:DateTime error during time change to daylight saving time时间更改为夏令时期间的 DateTime 错误
【发布时间】:2020-11-19 20:22:53
【问题描述】:

我必须随着时间的推移绘制一个数据集,该数据集是从一个短数组中计算出来的。这可行,但在转换到正确的时区时会引发异常:

System.ArgumentException: "提供的DateTime表示一个无效的时间。例如,时钟向前调整时,被跳过的周期内的任何时间都是无效的。参数名称:dateTime"

问题是数据集是在时间转换到夏令时期间记录的,因此在凌晨 2 点到 3 点之间存在间隙。从凌晨 2 点开始,时间无效,因为它们根本不存在。但是,当我尝试包含一个 if 语句来证明无效时间时,它并没有帮助,因为布尔“isvalid”总是错误的。我不明白为什么 bool 保持为假,尽管几行之后它会抛出这个 DateTime 无效的异常,所以我该怎么办?感谢您的帮助!

补充信息:date_0 的KindLocal

DateTime date_0;             //equals {29.03.2020 02:00:00} which is invalid 
TimeZoneInfo tzf = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");                       
bool isInvalid = tzf.IsInvalidTime(date_0);
if (isInvalid)
    {
          //do something (but this is never reached)
    }
DateTime dt = TimeZoneInfo.ConvertTime(date_0, tzf);   //here the exception is thrown
var isSum = tzf.IsDaylightSavingTime(dt);
if (isSum) date_0 = date_0.AddHours(1);

解决方案

感谢提供帮助的 cmets。问题是 date_0 的 KindTimeZoneInfo tzf 不同。我通过将 tzf 更改为对应于 date_0 的 Local 来解决它。现在无效的DateTime 被识别并且可以进行进一步的步骤。

TimeZoneInfo tzf = TimeZoneInfo.Local;
if(tzf.IsInvalidTime(date_0))
   {
         // ...
   } 

【问题讨论】:

  • "如果 dateTime 无效,则为 true;否则为 false。" - docs 所以你的 isvalid 变量被反转了。它实际上应该是isInValidisvalid = !tzf.IsInvalidTime(date_0);
  • date_0 有什么种类?如果您不是专门处理 UTC 和本地时间,您可能应该使用DateTimeOffset
  • @Fildor:你是对的。我更改了变量名以便更好地理解
  • @JeremyLakeman:date_0 的类型是本地

标签: c# winforms datetime timezone argumentexception


【解决方案1】:

我假设您的DateTime 有一个KindUnspecified。来自在线文档 然后IsInvalidTime 会假设“dateTime 是 TimeZoneInfo 对象的时间,并确定它是否无效”。

ConvertTime 表示“假定为本地时间。将本地时间转换为destinationTimeZone 中的时间。”

因此,如果您的本地时区与您的 TimeZoneInfo 不同,结果将令人惊讶。

如果您的 DateTime.Kind 是本地的,但您的 TimeZoneInfo 不是本地的,那么文档建议 IsInvalidTime 将“将 dateTime 转换为 TimeZoneInfo 对象的时间并返回 false。” source code 确实如此。总是返回 false 的函数有什么意义?

由于您正在处理的日期时间看起来既不是本地时间也不是 UTC,因此您应该转换为 DateTimeOffset,或者将所有内容都转换为 UTC。

date_0 = DateTime.SpecifyKind(date_0, DateTimeKind.Unspecified);
if (tzf.IsInvalidTime(date_0)){
   // ...
}
var dto = new DateTimeOffset(date_0, tzf.GetUtcOffset(date_0));

【讨论】:

  • 感谢这对我有很大帮助,我在原来的帖子中添加了一个解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-10-18
  • 2011-04-29
  • 1970-01-01
  • 2012-04-07
  • 2014-12-30
  • 2012-07-09
  • 2015-07-09
  • 2017-08-28
相关资源
最近更新 更多