2011-01-06 43 views
6

Tôi đang cố gắng di chuyển ứng dụng WPF sang SilverLight 4. Ứng dụng WPF sử dụng TimeZoneInfo.FindSystemTimeZoneById() và TimeZoneInfo.ConvertTimeFromUtc() để chuyển đổi DateTime của múi giờ speicific thành DateTime của một thời điểm cụ thể khác vùng.Vùng thời gian Silverlight chuyển đổi

Nhưng tôi không thể tìm thấy một trong các chức năng này trong SilverLight 4. SilverLight dường như hỗ trợ chuyển đổi múi giờ betwen Utc và Chỉ cục bộ.

Có cách nào để chuyển đổi DateTime từ bất kỳ múi giờ nào sang múi giờ khác trong Silverlight không?

Trả lời

2

Thật không may hiện tại không có chức năng tiêu chuẩn để thực hiện điều đó.

Cho phép kiểm tra (sử dụng phản xạ) cách thức hoạt động của phương thức TimeZoneInfo.FindSystemTimeZoneById(). Chỉ cần một trong các giá trị từ trường s_systemTimeZones:

private static Dictionary<string, TimeZoneInfo> s_systemTimeZones 
{ 
    get 
    { 
     if (s_hiddenSystemTimeZones == null) 
     { 
      s_hiddenSystemTimeZones = new Dictionary<string, TimeZoneInfo>(); 
     } 
     return s_hiddenSystemTimeZones; 
    } 
    set 
    { 
     s_hiddenSystemTimeZones = value; 
    } 
} 

Trường này lưu trữ tất cả TimeZoneInfo-s hiện có. Và khi bạn gọi FindSystemTimeZoneById (id) nó chỉ cần chọn một số giá trị từ từ điển được điền sẵn. Tôi không biết khi nào từ điển này khởi tạo và giá trị nào nó sử dụng để khởi tạo. Nhưng anh chàng từ this thread đã nói rằng TimeZoneInfo sử dụng các giá trị từ đăng ký: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Time Zones

Cách rõ ràng nhất là tạo từ điển từ điển riêng và điền nó với các giá trị. Một cái gì đó như thế này:

Dictionary<string, TimeZoneInfo> dictionary = new Dictionary<string, TimeZoneInfo>(); 
TimeZoneInfo info = new TimeZoneInfo("ID", new TimeSpan(0, 1, 0, 0), "SomeCultureName", "Some Standard Time", "Some Daylight Time", null, true); 
dictionary.Add("Some time", info); 

Nhưng có một vấn đề khác: Nhà xây dựng TimeZoneInfo là riêng tư. Vì vậy, nếu bạn muốn sử dụng chức năng FindSystemTimeZoneById() và ConvertTimeFromUtc() thì bạn nên thực hiện nó ngay từ đầu. Tạo một số lớp đại diện cho múi giờ, tạo và điền từ điển của lớp này với thông tin về múi giờ ...
Không phải tin tốt lắm, tôi biết. Nhưng tôi hy vọng nó sẽ có ích cho bạn :)

0

Trong trường hợp bất cứ ai chạy qua thread này, đây là những gì tôi đã tìm thấy ...

Microsoft mã nguồn tham khảo cho TimeZoneInfo (đầy đủ .NET 4 CLR) bao gồm phương thức TryGetTimeZoneByRegistryKey(), sẽ nhận các múi giờ từ khóa đăng ký HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones.

Tôi đoán nếu bạn đang viết ứng dụng Silverlight đáng tin cậy, bạn có thể sử dụng P/Gọi để thực hiện tra cứu đăng ký.

Đối với ứng dụng của chúng tôi, chúng tôi không muốn hiển thị hộp thoại yêu cầu quyền tin cậy đầy đủ. Tôi đã tìm kiếm thêm và tìm thấy Stephane Delcroix's open-source implementation - Tôi không chắc liệu có nguồn chính thức hơn liên kết đó hay không. Nó hoạt động với định dạng cơ sở dữ liệu múi giờ Unix (zoneinfo), mà bạn có thể download từ IANA.

Cơ sở dữ liệu múi giờ khá lớn và sẽ làm tăng kích thước của ứng dụng Silverlight nếu bạn đã bao gồm nó. Nhưng chúng tôi chỉ cần hỗ trợ một vài múi giờ. Tôi lấy một tập hợp con của cơ sở dữ liệu và đóng gói nó vào ứng dụng Silverlight của chúng tôi như một tài nguyên; sau đó tôi đã sửa đổi mã của Stephane để đọc từ luồng tài nguyên thay vì từ hệ thống tệp. Tôi đã phải loại bỏ tất cả các chức năng thời gian địa phương, vì không có/etc/localtime. Nhưng chúng tôi chỉ cần đặt tên múi giờ và khả năng chuyển đổi giữa các múi giờ này và UTC. Cách tiếp cận này dường như làm việc OK.

+0

Hmm. Tôi đã không thực sự sử dụng tải xuống IANA - tôi vừa sao chép nội dung của/etc/zoneinfo từ máy Linux gần nhất trên mạng của chúng tôi. Nó chỉ ra các tập tin IANA có định dạng văn bản, và bạn phải chạy chúng thông qua một trình biên dịch múi giờ ("zic"). Nguồn "zic" cũng nằm trên cùng trang IANA; nhưng tôi đoán sẽ dễ dàng hơn khi sử dụng các tệp nhị phân nếu bạn có máy Linux để lấy chúng. –

+0

Đây là [phiên bản trên GitHub] (https://github.com/mono/mono/tree/master/mcs/class/System.Core/System). –

1

Hơi trễ một chút, nhưng tôi đã làm điều này một lúc và đăng lên trang web cộng đồng MS để mọi người sử dụng vì nó luôn được hỏi.Tôi đã không tìm kiếm ID múi giờ, nhưng tôi đã sử dụng phương thức FromSerializedString() trong ứng dụng SL của mình. Các dịch vụ web của tôi sẽ chuyển dữ liệu ToSerializedString() dưới dạng một thuộc tính chuỗi và trong SL, tôi sẽ chỉ sử dụng đối tượng này khi cần thiết. Tôi đã làm một phản xạ của đối tượng TimeZoneInfo.

https://github.com/TWhidden/DevStuff/blob/master/StackOverflow/TimeZoneInfo.cs

Không chắc chắn nếu điều này giúp bạn (hoặc bất kỳ người đọc tương lai của bài này).

Thật thú vị khi làm và giải quyết được sự cố của tôi. Tôi đã sử dụng điều này cho V3 Silverlight, vì vậy nó sẽ là tốt cho 4/5, nhưng cũng có thể được cải thiện bởi Microsoft đã.

Cập nhật 2017-04-12: Liên kết tới GitHub, sử dụng tính năng này trong lib PCL. Nên làm việc cho SL, nhưng chúng tôi đã giảm như MS đã làm năm trước đây.

+1

Có thể là tuyệt vời nhưng liên kết đã chết ... –

+0

Cập nhật để sử dụng liên kết Github thay thế. – TravisWhidden

Các vấn đề liên quan