2008-10-07 38 views
35

Tôi biết về lớp System.TimeZone cũng như sử dụng nhiều phương pháp DateTime.ToString(). Những gì tôi đã không thể tìm thấy là một cách để chuyển đổi một DateTime thành một chuỗi, ngoài các thông tin về thời gian và ngày tháng, có chứa từ viết tắt Time Zone ba chữ cái (trên thực tế, giống như cách tooltips của StackOverflow cho tương đối hiển thị thời gian hoạt động).Cách hiển thị DateTime với một Múi giờ được viết tắt?

Để tạo ví dụ dễ dàng cho mọi người theo dõi cũng như tiêu thụ, hãy tiếp tục với ví dụ về StackOverflow. Nếu bạn nhìn vào chú giải công cụ hiển thị trên thời gian tương đối, nó sẽ hiển thị với ngày đầy đủ, thời gian bao gồm giây trong định dạng mười hai giờ, chỉ định AM/PM và sau đó viết tắt là 3 ký tự của múi giờ (trong trường hợp của họ, được phối hợp Giờ quốc tế). Tôi nhận ra tôi có thể dễ dàng nhận được GMT hoặc UTC bằng cách sử dụng các phương pháp tích hợp, nhưng những gì tôi thực sự muốn là thời gian vì nó là cục bộ — trong trường hợp này, trên một máy chủ web.

Nếu máy chủ web của chúng tôi đang chạy Windows Server 2k3 và đã đặt múi giờ thành CST (hoặc, cho đến khi daylight saving chuyển về, CDT?), Tôi muốn ứng dụng web ASP.NET hiển thị DateTimes liên quan đến múi giờ đó cũng như định dạng để hiển thị "CST" ở cuối. Tôi nhận ra rằng tôi có thể dễ dàng mã hóa điều này, nhưng vì lợi ích của sự mạnh mẽ, tôi thực sự muốn một giải pháp dựa trên máy chủ đang chạy cài đặt môi trường hệ điều hành của mã.

Ngay bây giờ, tôi có tất cả mọi thứ nhưng vùng chữ viết tắt thời gian sử dụng đoạn mã sau:

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

nào hiển thị:

10/07/2008 15:40:31

Tất cả Tôi muốn (và nó không nhiều, lời hứa!) Là để nói:

10/07/2008 03:40:31 PM CDT

Tôi có thể sử dụng System.TimeZone.CurrentTimeZone và sử dụng nó để hiển thị chính xác "Daylight Daylight Time" nhưng ... đó là một chút quá dài vì lợi ích ngắn gọn. Tôi sau đó bị mắc kẹt bằng văn bản một thói quen thao tác chuỗi để tước ra không gian trắng và bất kỳ chữ hoa không? Trong khi điều đó có thể hoạt động, điều đó dường như vô cùng khó khăn đối với tôi ...

Googling và không tìm thấy bất kỳ điều gì phù hợp với câu hỏi cụ thể của tôi.

Trả lời

1

Tùy thuộc vào mức độ mạnh mẽ mà bạn cần.

Có thể bạn sẽ cần một số loại hack theo một trong hai cách. Một cách dễ dàng là chia chuỗi bằng dấu cách và sau đó ghép nối chữ cái đầu tiên của mỗi từ. tức là

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

Điều đó sẽ không hiệu quả cho mọi múi giờ trên hành tinh, nhưng nó sẽ hoạt động đối với hầu hết các múi giờ. Nếu bạn cần nó mạnh mẽ hơn thì có thể bạn sẽ cần phải tạo một bản đồ ánh xạ các tên múi giờ cho các từ viết tắt của chúng.

2

Tôi sẽ tạo bảng tra cứu chuyển đổi tên múi giờ thành chữ viết tắt của nó. Nếu không tìm thấy kết quả phù hợp, bạn có thể trả về tên vùng đầy đủ.

Xem time zone abbreviations.

6

Có một thư viện có sẵn miễn phí, TZ4NET, có sẵn các chữ viết tắt này. Trước .NET 3.5, đây là một trong những lựa chọn thay thế duy nhất để chuyển đổi giữa các múi giờ.

Nếu bạn không muốn có một thư viện riêng biệt, bạn chắc chắn có thể tạo một bản đồ các từ viết tắt hợp lý bằng cách sử dụng các lớp TimeZoneInfo và sau đó chỉ cung cấp cho người dùng của bạn.

19

Đây là phương pháp hack nhanh chóng của tôi mà tôi vừa thực hiện để giải quyết vấn đề này.

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

Cách tiếp cận này có một số sai sót. Ví dụ ở Arizona, nơi họ sử dụng Giờ chuẩn miền núi và không quan sát Giờ tiết kiệm ánh sáng ban ngày, .NET có DaylightName và StandardName là "US Mountain Standard Time" sẽ hiển thị "UMST" với phương pháp của bạn. Tôi hy vọng sẽ thấy "MST" thay thế (cả trong mùa hè và mùa đông). Thật không may là khung công tác .NET dường như bị thiếu ở đây nên tôi đã sử dụng một bảng tra cứu tĩnh. – codemonkey

+0

Điều này sẽ không hoạt động trong nhiều múi giờ, ví dụ: ** ACT ** _Acre Time_ (UTC -5) – Tanmay

2

Nếu kéo viết tắt từ DaylightName/StandardName, bạn sẽ tốt hơn khi tạo chuỗi bằng StringBuilder, cho chuỗi không thay đổi.

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(); 
    } 

Tất nhiên, một mảng chứa KeyValuePair có lẽ là tốt nhất cho một công ty đa quốc gia. Nếu bạn muốn cạo vài phút trước hạn chót, và bạn đang ở một công ty Mỹ, công việc này sẽ hoạt động.

+1

Tôi nghĩ chuỗi ký tự của ba ký tự không phải là tất cả những gì xấu và không biện minh bằng cách sử dụng StringBuilder ở đây, đặc biệt là vì bạn đang đi dây trái và phải. – Martijn

0

Ok, Đã 4 năm (và gần một tuần), đã đến lúc chúng tôi mang LINQ vào các cuộc thảo luận ...

Đưa nhau Criag và ý tưởng của Bob ...

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

Trừ khi bạn có thể tin tưởng TimeZone để không bao giờ trở lại một chuỗi với hai không gian liên tiếp:

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

Nếu bạn đang sử dụng < = Net 3.0 sau đó tải về và sử dụng TZ4Net OlsonTimeZone.CurrentTimeZone .StandardĐăng ký cho> .Net 3.0 sử dụng NodaTime hoặc khác. Các tên múi giờ không phù hợp với bất kỳ quy ước nào mà bạn có thể dựa vào thao tác chuỗi đơn giản để xây dựng từ viết tắt từ một từ viết tắt. Sai 5% thời gian vẫn còn sai.

+0

Bạn sẽ bỏ đi để kiếm lợi nhuận 95% thời gian? – micahhoover

2

Sử dụng nodatime.

Hàm sau mất DateTime trong thời gian UTC và định dạng nó bằng múi giờ hệ thống cục bộ được viết tắt. Sử dụng x trong chuỗi định dạng cho múi giờ được viết tắt. Tìm kiếm định dạng tùy chỉnh 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); 
    } 
Các vấn đề liên quan