.NET 为夏季夏令时增加了一小时
本文关键字:一小时 增加 夏令时 夏季 NET | 更新日期: 2023-09-27 18:37:17
我从 Web 服务2013-10-15T12:54:18+01:00
那里得到一个以下字符串。这个日期是夏季夏令时,我的 .NET 代码(我认为是 Web 服务代理)会自动添加一个小时。如果返回值落在冬季 DST 内,则情况并非如此。返回的时间(12:54:18
)是我想要显示的,我不希望进行任何形式的重新计算。
我用TimeSpan DateTime.TimeOfDay
来显示时间。
我能做些什么来实现它?
我正在尝试将您的问题和其他评论中的碎片放在一起。到目前为止,这是我的分析:
-
在网络上,您会看到两个不同的日期和时间字符串:
-
如果没有夏令时(冬季),字符串
2013-12-30T12:54:18
-
使用夏令时(夏季),字符串
2013-10-15T12:54:18+01:00
这表明 Web 服务使用 GMT 标准时间作为时区。
-
-
您希望从日期和时间字符串中提取 GMT 时间戳。
-
但是,在您和 Web 服务之间有一些未指定的 Web 服务代理(我假设是某种 .NET 框架?),在您的代码中,您只能访问
DateTime
而且您的代码以中欧标准时区执行,如果我们忽略与日光之间的过渡的短暂时间,则在夏季和冬季基本上比 GMT 早一小时储蓄。
我希望到目前为止我是对的。
您可以使用以下代码将传入DateTime
转换为 GMT:
// Framework code creates the DateTime.
var sourceDateTime = DateTime.Parse("2013-10-15T12:54:18+01:00");
// Application code can further process the DateTime.
var destinationTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var destinationDateTime = TimeZoneInfo.ConvertTime(sourceDateTime, destinationTimeZoneInfo);
此示例在夏令时给出正确答案。传入的日期和时间字符串包含偏移量,并正确解析为本地时区 (CET)。TimeZoneInfo.ConvertTime
假定源DateTime
位于本地时区,并且结果正确。
但是,代码在没有夏令时的冬季失败:
var sourceDateTime = DateTime.Parse("2013-12-30T12:54:18");
请注意,日期和时间字符串不再包含时区偏移量。偏移量+00:00
,但由于某种原因,字符串中缺少偏移量。这意味着假定源DateTime
位于本地时区 (CET),而不是从实际时区 (GMT) 转换而来。如果我的分析是正确的,这就是你问题的根源。
另一种解释方式:
|服务器 (格林威治标准时间) |框架 |我的代码-------+---------------+---------------------------+----------------------------夏季 |+01:00 后缀 |格林威治标准时间 -> 欧洲中部时间增加 1 小时 |欧洲中部时间 -> 格林威治标准时间减去 1 小时-------+---------------+---------------------------+----------------------------冬季 |无后缀 |假设为欧洲中部时间 |欧洲中部时间 -> 格林威治标准时间减去 1 小时
这个问题没有简单的解决方法。如果您可以说服 Web 服务提供正确的偏移量,即使它+00:00
我上面的代码在夏季和冬季都可以工作。更好的是,只使用 UTC,并且只在最终用户参与时转换为本地时间。但是我想您无法控制Web服务吗?
一种选择是在与服务器相同的时区(例如 GMT)执行代码。然后,您应该能够直接使用时间戳而无需进行任何转换。
另一个更丑陋的选择是确定 Web 服务是否在夏令时之外,然后相应地调整时间:
var destinationTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
if (!destinationTimeZoneInfo.IsDaylightSavingTime(sourceDateTime)) {
var sourceDateTimeOffset = new DateTimeOffset(sourceDateTime, destinationTimeZoneInfo.BaseUtcOffset);
sourceDateTime = sourceDateTimeOffset.UtcDateTime;
}
var destinationDateTime = TimeZoneInfo.ConvertTime(sourceDateTime, destinationTimeZoneInfo);
我试图使代码尽可能通用,但实际上它只是试图解决缺少+00:00
的情况,在这种情况下,destinationTimeZoneInfo.BaseUtcOffset
正好是 0,所以这样做可能有点矫枉过正。
更重要的是,我不确定此代码在夏令时转换期间是否提供正确的结果。尽管我相信格林威治标准时间和CET在同一天过渡,欧洲中部时间仍然比格林威治标准时间早一个小时。您确实必须创建一些单元测试以确保获得所需的结果。
在此类示例中,DateTime 对象不包含偏移量。它只保存一个kind
可以是:本地偏移量(运行时环境的偏移量)或UTC。这样做,因为DateTimeOffset是你想要的:
DateTimeOffset test = DateTimeOffset.Parse("2013-10-15T12:54:18+01:00");
Console.WriteLine(test.DateTime.TimeOfDay); // UTC
Console.WriteLine(test.LocalDateTime.TimeOfDay); // Localized with the offset parsed
将输出
12:54:18
11:54:18
您可能需要查看此 MSDN 文章,其中介绍了您的 TimeOfDay 当前返回的转换。
通过检查该文章,您可以找到如何更正它的方法。时区信息是你需要的类。
编辑,Jon Skeet提供的工作也可能有所帮助,请查看Noda Time博客以获取更多信息!