2012-08-08 93 views
4

該代碼已經工作了很長時間了,但現在已經打破了,當我試圖通過DateTime.Now作爲outageEndDate參數:轉換DateTime.Now到不同的時區

public Outage(DateTime outageStartDate, DateTime outageEndDate, Dictionary<string, string> weeklyHours, string province, string localProvince) 
    { 
     this.outageStartDate = outageStartDate; 
     this.outageEndDate = outageEndDate; 
     this.weeklyHours = weeklyHours; 
     this.province = province; 
     localTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[localProvince]); 

     if (outageStartDate < outageEndDate) 
     { 
      TimeZoneInfo remoteTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[province]); 
      outageStartDate = TimeZoneInfo.ConvertTime(outageStartDate, localTime, remoteTime); 
      outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime, remoteTime); 

錯誤消息我我得到的最後一行是Kind屬性設置不正確的日期時間參數(outageEndDate)。我谷歌搜索和檢查的例子,但我真的不明白錯誤信息。

任何建議表示讚賞。

問候。

編輯 - 確切的錯誤信息是:

The conversion could not be completed because the supplied DateTime did not have the Kind 
property set correctly. For example, when the Kind property is DateTimeKind.Local, the source 
time zone must be TimeZoneInfo.Local. Parameter name: sourceTimeZone 

編輯:outageEndDate.Kind = UTC

+0

請發佈確切的錯誤謝謝 – MethodMan 2012-08-08 20:55:52

+0

什麼是DateTimeKind for outageEndDate? '的Debug.WriteLine(的String.Format( 「{0}」,outageEndDate.Kind));' – 2012-08-08 21:02:40

+0

@DJKRAZE:見編輯到OP。 – Kevin 2012-08-08 21:10:51

回答

8

感謝澄清你的問題。

如果DateTime實例KindLocal,那麼TimeZoneInfo.ConvertTime會預期第二個參數是您計算機的本地時區。

如果日期時間實例KindUtc,那麼TimeZoneInfo.ConvertTime將期望第二個參數是Utc時區。

您需要outageEndDate轉化爲正確的時區第一,以防萬一localProvice時區不匹配您的計算機上的時區。

outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime); 
1

這裏的東西對你的意思是一個例子,你可以嘗試

這取決於通過「GMT + 1時區」。你的意思是永久UTC + 1,還是你的意思是UTC + 1或UTC + 2,取決於DST?

如果您使用.NET 3.5,使用TimeZoneInfo得到一個合適的時區,然後使用:

// Store this statically somewhere 
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("..."); 
DateTime utc = DateTime.UtcNow; 
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone); 

你需要制定出系統ID馬耳他時區,但你可以通過在本地運行此代碼做到這一點很容易:

Console.WriteLine(TimeZoneInfo.Local.Id); 

如果你不使用 .NET 3.5,你需要制定出夏令你小精靈。說實話,在最簡單的方式做將是一個簡單的查找表。制定出未來幾年的DST更改,然後寫一個簡單的方法來返回在特定的UTC時間與列表硬編碼的偏移。你可能只想進行排序List<DateTime>在1到2小時之間的已知變化,替代,直到你的日期是最後一次更改後:

// Be very careful when building this list, and make sure they're UTC times! 
private static readonly IEnumerable<DateTime> DstChanges = ...; 

static DateTime ConvertToLocalTime(DateTime utc) 
{ 
    int hours = 1; // Or 2, depending on the first entry in your list 
    foreach (DateTime dstChange in DstChanges) 
    { 
     if (utc < dstChange) 
     { 
      return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local); 
     } 
     hours = 3 - hours; // Alternate between 1 and 2 
    } 
    throw new ArgumentOutOfRangeException("I don't have enough DST data!"); 
}