2017-04-04 35 views
1

時區和夏令時的變化特別讓我困惑。在英國,我們有GMT/BST:獲取時間直到當地時間從現在起爲N小時,考慮到夏令時的變化

在英國的時鐘向前撥1小時,在凌晨1時的最後一個星期日在 月,然後回到1小時在十月最後一個星期日凌晨2點。時鐘提前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小時。

+0

作爲一個側面的問題...如果我有'endDateTime = 26/3/2017 01:30'給定會發生什麼時間從01:00 - > 02:00跳到這個日期?這次是否存在?! –

+0

那麼你可以爲自己回答那個問題..答案是肯定的,現在時間已經到了,沒有.net不爲你做夏令時,不同的時區在一年中的不同時間做這些。如果你有時間的話,你也許能夠做出不同的時間。 – BugFinder

+0

因此,DST更改直接由Windows更改時區驅動,.Net對此並不知情?即它的工作原理與我在這兩次手動更改控制面板中的時區一樣? –

回答

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

Minor nitpick - 您可以在「TimeZoneInfo」中找到該區域。FindSystemTimeZoneById(「GMT標準時間」);「 – Evk

+0

@Evk true,謝謝你!代碼更新。 – tchrikch

+0

而且我可以調用'DateTime.Parse(...)'來獲得合適的'date1'&'date2'值沒有'DateTimeKind'雜亂? –

0

雖然tchrikch's answer是完全合理的(並且應該被接受,IMHO),這是值得添加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(); 
相關問題