我从网络服务2013-10-15T12:54:18+01:00
获取以下字符串。这个日期是在夏天夏令时和我的.NET代码(我认为是Web服务代理)自动添加一个小时。如果返回值随冬季夏令时降低,则情况并非如此。返回的时间(12:54:18
)是我想要显示的内容,我不想进行任何类型的重新计算。
我使用TimeSpan DateTime.TimeOfDay
来显示时间。
我能做些什么来实现它?
答案 0 :(得分:3)
我正在尝试将您的问题和其他评论中的各个部分放在一起。到目前为止,这是我的分析:
在线上你会看到两个不同的日期和时间字符串:
没有夏令时(冬天),字符串为2013-12-30T12:54:18
夏令时(夏令时)字符串为2013-10-15T12:54:18+01:00
这表示网络服务使用 GMT标准时间作为时区。
您想从日期和时间字符串中提取GMT时间戳。
但是,在您和Web服务之间有一些未指定的 Web服务代理(我假设某种.NET框架?),在您的代码中,您只能访问{ {1}}此外,您的代码正在中欧标准时间时区执行,如果我们忽略过渡时间的短暂时间,那么在夏季和冬季基本上比GMT提前一小时从夏令时开始。
我希望到目前为止我是正确的。
您可以使用以下代码将传入的DateTime
转换为GMT:
DateTime
此示例在夏令时期间给出正确答案。传入的日期和时间字符串包含偏移量,并正确解析为本地时区(CET)。 // 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);
假定源TimeZoneInfo.ConvertTime
位于本地时区且结果正确。
然而,代码在冬季没有夏令时失败:
DateTime
请注意,日期和时间字符串不再包含时区偏移量。偏移量为var sourceDateTime = DateTime.Parse("2013-12-30T12:54:18");
,但由于某种原因,字符串中缺少该偏移量。这意味着假定源+00:00
位于本地时区(CET)而不是从实际时区(GMT)转换。 如果我的分析正确,这就是问题的根源。
另一种解释方式:
| Server (GMT) | Framework (CET) | My code -------+---------------+---------------------------+---------------------------- Summer | +01:00 suffix | GMT -> CET adds 1 hour | CET -> GMT subtracts 1 hour -------+---------------+---------------------------+---------------------------- Winter | No suffix | Assumed to be CET | CET -> GMT subtracts 1 hour
这个问题没有简单的解决办法。如果您可以说服Web服务提供正确的偏移量,即使它是DateTime
,我的代码将在夏季和冬季都有效。更好的是,仅使用UTC并且仅在最终用户参与时转换为本地时间。但我想你无法控制网络服务?
一种选择是在与服务器相同的时区执行代码(例如GMT)。然后你应该可以直接使用时间戳而无需任何转换。
另一个更丑陋的选择是确定Web服务是否在夏令时之外,然后相应地调整时间:
+00:00
我试图尽可能保持代码的一般性,但实际上它只是试图修复缺少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
正好是0所以它可能略微过度杀伤这样做。
更重要的是,我不确定此代码是否会在夏令时转换期间提供正确的结果。尽管我认为同一时间的格林尼治标准时间和CET过渡仍然比格林威治标准时间提前一小时。您必须创建一些单元测试以确保获得所需的结果。
答案 1 :(得分:2)
在这种示例中,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
答案 2 :(得分:1)
您可能需要查看this MSDN article,其中描述了TimeOfDay当前返回的转换。
通过检查该文章,您可以找到如何纠正它的方法。 TimeZoneInfo是您需要的类。
编辑,Jon Skeet提供的工作也可以提供帮助,请查看Noda Time blogspot以获取更多信息!