我想在时间变化的时候添加会议记录。例如
在2015年10月24日的时间里,3点钟的时间会在后面一小时后退。
所以当我们凌晨2点20分,50分钟后我们凌晨2点10分。
var date = new DateTime(2015,10,24, 2,20, 00);
Console.WriteLine(date.AddMinutes(50).ToString());
上面的代码返回3:10,这是错误的。
我该如何解决?它取决于国家和时区。
答案 0 :(得分:2)
这就是为什么我开始Noda Time项目的原因。它梳理了你可能拥有的假设。例如,在你的例子中,凌晨2:20发生两次 - 所以当你说new DateTime(2015,10,24, 2,20, 00)
时系统是如何知道你的意思是第一次出现还是第二次?它甚至不清楚你期望它在哪个时区。
在Noda Time中,代码类似于:
var local = new LocalDateTime(2015, 10, 24, 2, 20, 0);
var zone = DateTimeZoneProviders.Tzdb[yourTimeZoneId];
// Apparently you want ambiguous times to resolve as the earlier
// occurrence.
var resolver = Resolvers.CreateMappingResolver(
Resolvers.ReturnEarlier, Resolvers.ThrowWhenSkipped);
// This is now the *first* occurrence of 2:20am
var zoned = local.InZone(zone, resolver);
// This is now the *second* occurrence of 2:10am
var laterZoned = zoned.Plus(Duration.FromMinutes(50));
请注意这里的所有内容都更明确。在很多情况下,你没有拥有来创建你自己的解析器 - 你可以使用InZoneStrictly
,这将导致模糊或跳过的时间,InZoneLeniently
将使用< em>稍后的模糊时间,以及跳过时间间隔之后的间隔的开始。 (对于Noda Time 2.0,其中一些略有变化,希望能使常见情况更简单。)
答案 1 :(得分:0)
你面临的一个重大错误是,时间不会在十月二十四日的时间内回溯,而是在十五时。
您可以尝试以下代码:
var date = new DateTime(2015, 10, 25, 1, 20, 00).ToUniversalTime();
Console.WriteLine($"UTC: {date}\tDST: {date.ToLocalTime().IsDaylightSavingTime()}\t{date.ToLocalTime()}");
date = date.AddMinutes(50);
Console.WriteLine($"UTC: {date}\tDST: {date.ToLocalTime().IsDaylightSavingTime()}\t{date.ToLocalTime()}");
date = date.AddMinutes(50);
Console.WriteLine($"UTC: {date}\tDST: {date.ToLocalTime().IsDaylightSavingTime()}\t{date.ToLocalTime()}");
date = date.AddMinutes(50);
Console.WriteLine($"UTC: {date}\tDST: {date.ToLocalTime().IsDaylightSavingTime()}\t{date.ToLocalTime()}");
您将在输出后获得UTC + 1(CEST UTC + 2):
UTC: 24.10.2015 23:20:00 DST: True 25.10.2015 01:20:00
UTC: 25.10.2015 00:10:00 DST: True 25.10.2015 02:10:00
UTC: 25.10.2015 02:00:00 DST: False 25.10.2015 02:00:00
UTC: 25.10.2015 01:50:00 DST: False 25.10.2015 02:50:00
答案 2 :(得分:0)
您可以使用TimeZoneInfo
执行计算,但需要使用DateTimeOffset
代替DateTime
。这也解决了两次出现的时间戳2015-10-25 02:20:00
的模糊性。通过在时间戳中包含偏移量,您知道时间戳描述了DST更改之前的时间点:
var date = new DateTimeOffset(2015, 10, 25, 2, 20, 0, TimeSpan.FromHours(2));
我假设您在夏令时期间处于欧洲时区,偏移+01:00和+02:00。通常,您将通过在该特定时间调用DateTimeOffset.Now
来创建此时间戳,但在此我手动创建时间戳,我必须指定UTC偏移量。
您现在可以提前50分钟计算新的时间戳:
Console.WriteLine(TimeZoneInfo.ConvertTime(date.AddMinutes(50), TimeZoneInfo.Local));
输出结果为:
25-10-2015 02:10:00 +01:00