2010-06-02 87 views
57

我試圖使用DateTimeOffset在任何時區傳達特定的時間。我無法弄清楚如何使用TimeZoneInfo來處理夏令時。如何在夏令時期間使用TimeZoneInfo獲取當地時間?

var dt = DateTime.UtcNow; 
Console.WriteLine(dt.ToLocalTime()); 

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero); 
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset)); 

此打印出:

6/2/2010 4:37:19 PM 
6/2/2010 3:37:19 PM -06:00 

我在中央時區,而我們目前在夏令時。 我想獲得第二行改爲:

6/2/2010 4:37:19 PM -05:00 

BaseUtcOffset顯然不會更改基於DST。

我怎樣才能得到適當的偏移值正確的時間?

+9

+1 - 這簡直讓我瘋狂的是TimeZoneInfo.ConvertTimeBySystemTimeZoneId不只是這個:) – 2010-06-03 04:14:13

回答

47

你需要得到來自的TimeZoneInfo的UTCOFFSET,然後傳遞到ToOffset()方法:

var dt = DateTime.UtcNow; 
Console.WriteLine(dt.ToLocalTime()); 

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero); 
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset))); 
+0

我看到工作......你要獲得UTC針對特定日期偏移時區。 謝謝。 – jaminto 2010-06-03 19:50:57

+3

與[Karl Gjertsen的答案](http://stackoverflow.com/a/16789973/57611)相比,這不是最好的方式,它使用單一的.Net函數來完成這項工作,而不是通過創建一個新的,扔掉'DateTimeOffset'。 – ErikE 2017-01-04 00:32:35

35

您還可以使用TimeZoneInfo.ConvertTimeFromUtc,這將允許夏令時:

DateTime utc = DateTime.UtcNow; 
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone); 
5

或者更好,如果你不想硬編碼時區標識符

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id); 
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi); 
+0

難道你不能直接使用'TimeZoneInfo.Local'嗎?你爲什麼需要調用FindSystemTimeZoneById? – CoderDennis 2015-10-14 21:15:16

+1

你說得對,我們不需要它。我們可以像這樣做'DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(networkDateTime,TimeZoneInfo。本地);' – Pabinator 2015-10-15 15:40:51

+0

但是,你固定在一個時區。取決於你想如何使用我猜的代碼。 :-) – 2015-11-05 16:32:35

1

我無論是在.NET和計算器一個初學者,所以我可能是錯的,但這裏有雲:

使用TimeZoneInfo.ConvertTimeFromUtc將允許夏令時間,並根據時間轉換爲正確的時間區域+可能的DST偏移量。但是 - 結果對象中的偏移本身將顯示標準時間的偏移量,並且不考慮夏令時。所以如果你想在對象上做一個ToString,你最終會得到正確的時間(以小時和分鐘爲單位),但是在夏令時期間錯誤的偏移量可能會導致代碼後面錯誤的時間。

如果您改爲使用GetUtcOffset獲取特定時間的偏移量,然後對DateTimeOffset對象執行ToOffset,則小時/分鐘和偏移量本身都將被正確轉換,並且您可以安全地執行ToString 。

string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz"; 
string timeZoneId = "FLE Standard Time"; 
string dateTimestr = "2017-10-09T09:00:00+02:00"; 

DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr); 
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); 
TimeSpan offset = zone.GetUtcOffset(dto); 
dto = dto.ToOffset(offset); 
string localTime = dto.ToString(ExpectedDateTimePattern); 

localTime將返回「2017-10-09T10:00:00 + 03:00」。

相關問題