从当地时间到现在为止N小时获取时间,考虑夏令时变化

时间:2017-04-04 09:04:46

标签: c# .net datetime timezone

时区和夏令时的变化特别让我感到困惑。在英国,我们有GMT / BST:

  

在英国,时钟在上周日凌晨1点1小时前进   3月,并在10月的最后一个星期日凌晨2点返回1小时。该   时钟提前1小时的时段称为英国夏令时   (BST)。

鉴于当地时间00:00,我希望能够计算当地时间到03:00的时间。通常这是3个小时,但3月26日(3月的最后一个星期日)从00:00到03:00实际上是两个小时。同样,当时钟在10月00:00 - 03:00返回四个小时。

.Net DateTime类及其方法是否为我做了这件事或者我需要小心吗?

在我的情况下,我特意使用字符串,所以我正在做一个方法:

TimeSpan DifferenceBetweenLocalTimes(string startDateTime,string endDateTime) 

我可以看到像TimeZoneInfo.IsDaylightSavingTime这样的东西但是如何按照我的意愿使用它并不明显。我的应用程序将每个日历日的当地午夜视为严格的边界,即不是每天都是24小时,每年一次,我每天23小时,每天25小时。

2 个答案:

答案 0 :(得分:4)

您可以使用TimeZoneInfo类来获取从本地日期时间到UTC的偏移量(包括日光技巧)。例如

var timeZone =TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var date1 = DateTime.Parse("2017-03-26 00:00:00");
var date2 = DateTime.Parse("2017-03-26 03:00:00");
var dto1 = new DateTimeOffset(date1, timeZone.GetUtcOffset(date1));
var dto2 = new DateTimeOffset(date2, timeZone.GetUtcOffset(date2));

var diff1 = (dto2 - dto1).TotalHours;

Console.WriteLine(diff1); // this is 2 hours

GetUtcOffset方法返回该时区的时间与UTC

之间的差异

答案 1 :(得分:0)

虽然tchrikch's answer完全合理(并且应该被接受,恕我直言),但值得添加基于Noda Time的解决方案。

// Parse input as LocalDateTime values (since they represent a local date and time)
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt1 = pattern.Parse("2017-03-26 00:00:00").Value;
LocalDateTime ldt2 = pattern.Parse("2017-03-26 03:00:00").Value;

// Apply a specific time zone, now making them ZonedDateTime values
// Using "lenient" conversions allows for default handling of ambiguous/invalid values
DateTimeZone tz = DateTimeZoneProviders.Tzdb["Europe/London"];
ZonedDateTime zdt1 = ldt1.InZoneLeniently(tz);
ZonedDateTime zdt2 = ldt2.InZoneLeniently(tz);

// Now simply determine the elapsed duration between these
Duration result = zdt2 - zdt1;

请注意,NodaTime 2.0中添加了ZonedDateTime值之间的减法。如果您使用的是旧版本,则需要执行此操作:

Duration result = zdt2.ToInstant() - zdt1.ToInstant();