2008-10-07 107 views
35

我知道System.TimeZone類以及DateTime.ToString()方法的許多用途。我無法找到的是一種將DateTime轉換爲除時間和日期信息之外還包含三個字母的時區縮寫的字符串的方法(事實上,與StackOverflow的相對工具提示方式大致相同時間顯示作品)。如何使用縮短的時區顯示日期時間?

爲了讓每個人都能輕鬆遵循以及消費的例子,讓我們繼續使用StackOverflow示例。如果您查看相對時間顯示的工具提示,則會顯示完整日期,時間包括12小時格式的秒數,AM/PM指定,以及三個字母的時區縮寫(在他們的情況下爲Coordinated世界時)。我意識到我可以通過使用內置方法輕鬆獲取GMT或UTC,但我真正想要的是在這種情況下,在本地—的時間,在Web服務器上。

如果我們的網絡服務器運行的是Windows Server 2k3並且它的時區設置爲CST(或者,直到daylight saving切換回來,CDT是它?),我希望我們的ASP.NET Web應用程序顯示DateTimes相對於該時區以及格式化以最終顯示「CST」。我意識到我可以很容易地對此進行硬編碼,但出於健壯性的考慮,我真的更喜歡基於運行代碼的OS環境設置的服務器的解決方案。

現在,我所擁有的一切,但使用下面的代碼時區縮寫:

myDateTime.ToString("MM/dd/yyyy hh:mm:ss tt") 

該款顯示器:

10/07/2008下午三時40分31秒

所有我想(和它的並不多,答應!)是,它說:

10/07/2008下午三時四十分31秒CDT

我可以使用System.TimeZone.CurrentTimeZone並使用它來正確顯示「中央夏令時」,但是......爲了簡潔起見,這太長了。然後,我是否堅持寫一個字符串操作例程去除空白和任何非大寫字母?雖然這可能工作,這似乎令人難以置信的黑客我...

Googling環顧這裏並沒有產生任何適用於我的具體問題。

回答

1

這取決於您所需的健壯程度。

您可能需要某種破解方式。一個簡單的方法是將字符串拆分爲空格,然後連接每個單詞的第一個字母。即

string[] words = tzname.Split(" ".ToCharArray()); 
string tzabbr = ""; 
foreach (string word in words) 
    tzabbr += word[0]; 

這不適用於地球上的每個時區,但它對大多數時間都有效。如果您需要更強大的功能,那麼您可能需要創建一個將時區名稱映射到縮寫的映射。

2

我會創建一個查找表,將時區名稱轉換爲其縮寫。如果找不到匹配,您可以返回完整的區域名稱。

請參閱time zone abbreviations

6

有一個免費的圖書館,TZ4NET,它有這些縮寫可用。在.NET 3.5之前,這是在時區之間轉換的唯一選擇之一。

如果你不想一個單獨的圖書館,你當然可以生成地圖使用的TimeZoneInfo類合理的縮寫,然後只提供給那些用戶。

19

這裏是我的快速破解方法,我只是提出來解決這個問題。

public static String TimeZoneName(DateTime dt) 
{ 
    String sName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(dt) 
     ? TimeZone.CurrentTimeZone.DaylightName 
     : TimeZone.CurrentTimeZone.StandardName; 

    String sNewName = ""; 
    String[] sSplit = sName.Split(new char[]{' '}); 
    foreach (String s in sSplit) 
     if (s.Length >= 1) 
      sNewName += s.Substring(0, 1); 

    return sNewName; 
} 
+5

這種方法有一定的缺陷。例如,在亞利桑那州,他們使用Mountain Standard Time並且沒有遵守夏令時,.NET有一個DaylightName和一個標準名稱爲「美國山區標準時間」,它將用您的方法顯示「UMST」。我期望看到「MST」(夏季和冬季)。不幸的是,.NET框架似乎在這裏不足,所以我使用了靜態查找表。 – codemonkey 2012-02-08 20:57:48

+0

這對於很多時區都不適用,例如** ACT ** _Acre Time_(UTC -5) – Tanmay 2017-11-09 08:50:18

2

如果從DaylightName拉縮寫/ StandardName,你會過得更好建設使用StringBuilder的字符串,字符串是不可變的。

public static string ToCurrentTimeZoneString(this DateTime date) 
    { 
     string name = TimeZone.CurrentTimeZone.IsDaylightSavingTime(date) ? 
      TimeZone.CurrentTimeZone.DaylightName : 
      TimeZone.CurrentTimeZone.StandardName; 
     return name; 
    } 

    public static string ToCurrentTimeZoneShortString(this DateTime date) 
    { 
     StringBuilder result = new StringBuilder(); 

     foreach (string value in date.ToCurrentTimeZoneString().Split(' ')) 
     { 
      if (value.IsNotNullOrEmptyWithTrim()) 
      { 
       result.Append(char.ToUpper(value[0])); 
      } 
     } 

     return result.ToString(); 
    } 

當然,包含KeyValuePair的數組對於跨國公司來說可能是最好的。如果你想在緊迫的期限內完成幾分鐘的剃鬚,而你在美國的公司,那麼這種方法很有效。

+1

我認爲三個字符的字符串連接並不是那麼糟糕,並且不適合在這裏使用StringBuilder,尤其是因爲您無論如何都是左右行走字符串。 – Martijn 2011-09-29 18:32:18

0

好吧,它已經4年(幾乎一個星期),這是我們帶來LINQ到討論時間...

放在一起Criag和Bob的想法...

public static String TimeZoneName2(DateTime dt) 
{ 
    var return ToCurrentTimeZoneShortString(dt) 
       .Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries); 
    return sSplit.Aggregate("", (st,w)=> st +=w[0]); 
} 

除非你可以信任的TimeZone永遠不會返回一個字符串,連續兩個空格:如果您正在使用< = NET 3.0

public static String TimeZoneName3(DateTime dt) 
{ 
    return ToCurrentTimeZoneShortString(dt).Split(' ') 
       .Aggregate("", (st,w)=> st +=w[0]); 
} 
0

然後下載TZ4Net和使用OlsonTimeZone.CurrentTimeZone .Standard> .Net 3.0的縮寫使用NodaTime或其他。時區名稱不符合任何慣例,您可以依靠簡單的字符串操作來從首字母縮略詞構造縮寫。錯誤的5%的時間仍然是錯誤的。

2

使用nodatime

下面的函數在UTC時間和縮寫本地系統時區格式,它需要一個DateTime。縮寫時區的格式字符串中使用x。查找自定義格式here

public static string ConvertToFormattedLocalTimeWithTimezone(DateTime dateTimeUtc) 
    { 
     var tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); // Get the system's time zone 
     var zdt = new ZonedDateTime(Instant.FromDateTimeUtc(dateTimeUtc), tz); 
     return zdt.ToString("MM'/'dd'/'yyyy' 'hh':'mm':'ss' 'tt' 'x", CultureInfo.InvariantCulture); 
    }