时区和夏令时的变化尤其让我感到困惑。在英国,我们有格林威治标准时间/英国夏令时:
在英国,时钟在最后一个星期日的凌晨 1 点向前移动 1 小时 三月,并在 10 月的最后一个星期日凌晨 2 点返回 1 小时。这 时钟提前 1 小时的时间段称为英国夏令时 (英国夏令时)。
给定当地时间,例如 00:00,我希望能够计算出距离当地时间 03:00 还有多长时间。通常这是微不足道的 3 小时,但在 3 月 26 日(3 月的最后一个星期日)从 00:00 - 03:00 实际上是两个小时。同样,当时钟回到十月的00:00 - 03:00是四个小时。
.Net DateTime 类及其方法对我来说只是微不足道的,还是我需要小心?
具体就我而言,我正在使用字符串,所以我正在执行以下方法:
TimeSpan DifferenceBetweenLocalTimes(string startDateTime,string endDateTime)
我可以看到类似TimeZoneInfo.IsDaylightSavingTime
的东西,但如何使用它来做我希望的事情并不明显。我的应用程序将每个日历日的当地午夜视为严格的边界,即并非每天都有 24 小时,每年一次,我得到 23 小时和 25 小时。
您可以使用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 之间的差值
虽然tchrikch的答案是完全合理的(恕我直言,应该被接受),但值得添加基于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;
请注意,ZonedDateTime
值之间的减法是在NodaTime 2.0中添加的。 如果您使用的是旧版本,则需要改为执行以下操作:
Duration result = zdt2.ToInstant() - zdt1.ToInstant();