2012-09-01 34 views
5

Yêu cầu của tôi ở đây khá chuẩn; Tôi cần cho phép người dùng chọn TimeZone hiện tại của họ và lưu nó vào tài khoản của họ. Sau đó, tôi sẽ sử dụng giá trị này để chuyển đổi các giá trị được lưu trữ DateTime thành giờ địa phương.Lưu trữ người dùng Tùy chọn múi giờ

Suy nghĩ hiện tại của tôi là tôi sẽ cho phép người dùng chọn một .NET TimeZoneInfo.Id từ danh sách (được giữ trong DB để cho phép mô tả thân thiện hơn nhưng được xây dựng sử dụng TimeZoneInfo.GetSystemTimeZones()) - Sau đó tôi sẽ sử dụng giá trị này để trả về phiên bản TimeZoneInfo liên quan sử dụng TimeZoneInfo.FindSystemTimeZoneById() và thực hiện chuyển đổi. Vấn đề chính tôi thấy ở đây là TimeZoneInfo.Id là một giá trị được giữ trong sổ đăng ký và không phải là một Id "chuẩn" (so với Olson chẳng hạn). Do vậy, có thể việc cập nhật/di chuyển máy chủ có thể làm mất hiệu lực các Id được lưu trữ hoàn toàn và phá vỡ các chuyển đổi ..

Trong ngắn hạn - phương pháp này có hợp lệ/an toàn không? Nếu không, có cách nào tốt hơn để lưu trữ tùy chọn múi giờ của người dùng trong khi cũng xử lý tiết kiệm ánh sáng ban ngày, v.v. mà không cần tấn logic bổ sung?

+0

Bạn đã xem ['DateTimeOffset'] (http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx) chưa? Hoặc ['NodaTime'] (http://code.google.com/p/noda-time/)? – Oded

+0

Liên quan: http://stackoverflow.com/q/2532729/1583 – Oded

+1

@Oded Vấn đề với DateTimeOffset là nó không phải là Day Light Savings biết – Paparazzi

Trả lời

8

Tôi chỉ tìm thấy câu hỏi chưa được trả lời cũ này, vì vậy tôi nghĩ nên thử nghiệm nó.

Tóm lại - phương pháp này có hợp lệ/an toàn không?

Tất cả phụ thuộc vào những gì bạn dự định làm với chúng.

Nếu bạn chỉ sử dụng nó trong mã phía máy chủ, thì có. Bạn chỉ cần lưu trữ Id múi giờ và hiển thị người dùng tương ứng DisplayName. FindSystemTimeZoneByIdGetSystemTimeZones hoàn toàn hợp lệ cho việc này.

Hãy nhớ rằng trong khi giá trị Id luôn giống nhau - thuộc tính DisplayName sẽ khác nhau dựa trên ngôn ngữ của hệ điều hành Windows mà bạn đang chạy mã. Việc triển khai là không phải là nhận thức về văn hóa, do đó, chỉ cần đặt một nền văn bản đích khác trong .Net sẽ không thay đổi chuỗi DisplayName.

Các bản ghi trong cơ sở dữ liệu múi giờ Microsoft Windows là hợp lý ổn định và được cập nhật qua Windows Update. Một số thông tin của thông tin đến từ sổ đăng ký, nhưng các chuỗi tài nguyên được bản địa hóa đến từ tzres.dll. Tất nhiên, tất cả những điều đó bị ẩn khỏi bạn bởi TimeZoneInfo và các lớp học liên quan.

Tuy nhiên, nếu bạn đang chuyển các múi giờ này Id giá trị cho các hệ thống khác - hãy cẩn thận. Có một số biến thể với các phiên bản trước của Windows. Ví dụ, tôi biết rằng tên hiển thị được sử dụng để tất cả nói "GMT" trong họ, và bây giờ chính xác hơn nói "UTC". Giá trị Id giống nhau, nhưng ai biết chính xác những gì khác không nhất quán. Đặc biệt nếu máy tính mục tiêu không nhận được cùng một bộ Windows Updates mà bạn có. Nhân tiện - các bản cập nhật được công bố here.

Bạn cũng nên biết một vài điều về cơ sở dữ liệu múi giờ Windows:

  • Nó không có khả năng đại diện cho hơn hai chuyển DST mỗi năm dương lịch. Ví dụ: in 2010, Cairo, Egypt had four transitions. Microsoft đã phát hành a hotfix, nhưng điều đó chỉ thực hiện một sửa đổi thỏa hiệp, chứ không phải chính xác về lịch sử. Có những khu vực khác có những thay đổi lịch sử như thế này mà không thể được đại diện đúng.

  • Một số thứ đã thay đổi giữa Windows XP/2003 và Vista/2008. Có một số thông tin thực sự tốt về điều này here, cùng với rất nhiều chi tiết về cách đăng ký được sử dụng.

  • Microsoft là chỉ trình phát chính với cơ sở dữ liệu múi giờ của riêng họ. Phần còn lại của thế giới sử dụng số IANA/Olson database. Điều này dẫn đến các vấn đề về khả năng tương tác. Tôi có một đăng ký phong nha về điều này trong the timezone tag wiki.

Bạn cũng nên biết rằng TimeZoneInfo được gắn bó chặt chẽ với DateTimeDateTimeOffset lớp. Đây là những thiết lập riêng của họ về quirks. DateTimeOffset có thể sử dụng được một chút, nhưng DateTime được sử dụng với sắc thái. Đọc:

Một xa tốt hơn giải pháp cho ngày và thời gian trong Net là sử dụng NodaTime. Thư viện này triển khai cả hai cơ sở dữ liệu múi giờ, bao gồm cả ánh xạ CLDR giữa chúng. Nó cũng cung cấp một API an toàn hơn nhiều, không cho phép bạn gặp rắc rối. Có thể mất một chút học lại, nhưng trước khi bạn biết, bạn sẽ sử dụng các lớp như LocalDateTime, ZonedDateTime, OffsetDateTimeInstant.

Bạn vẫn gặp sự cố rằng cơ sở dữ liệu múi giờ được cập nhật thường xuyên, vì chúng tôi để nguyên tắc chấm công cho các chính trị gia. Nhưng the TZDB folks làm một công việc khá tốt để giữ cơ sở dữ liệu lịch sử chính xác và cung cấp bí danh/liên kết khi tên vùng thay đổi. Bạn có thể xem danh sách tên tz here.

Ngoài ra, nếu bạn đi với NodaTime, bạn có thể chọn gắn bó với bản sao TZDB được biên dịch vào bản phân phối hoặc bạn có thể gửi bản sao của riêng mình bằng ứng dụng của mình. Bạn có thể (về mặt lý thuyết) viết mã của riêng bạn để kéo xuống phiên bản mới nhất từ ​​IANA và giữ cho ứng dụng của bạn được cập nhật - tất cả mà không dựa vào hệ điều hành máy chủ.

+0

Điều toàn bộ timezoneinfo.ID không có ý nghĩa. ID được mong đợi là một Mã định danh tuân theo một số tiêu chuẩn ISO. Tuy nhiên, tôi chỉ phát hiện ra rằng 'FindSystemTimeZoneById' không hoạt động chính xác trên các phiên bản Windows khác nhau.Trong một phiên bản, chuỗi được trả lại là tất cả các trường hợp thấp hơn và một trong những khác nó là trường hợp lạc đà và để làm cho vấn đề tồi tệ hơn, các FindSystemTimeZoneById không phải là trường hợp không nhạy cảm. Đi con số! – Rajiv

+0

@Rajiv - Không có tiêu chuẩn ISO cho múi giờ. Các định danh IANA/Olson (đã đề cập ở trên) là điều gần nhất chúng ta phải đạt tới một tiêu chuẩn. Về các ID Windows, tôi chưa bao giờ gặp phải bất kỳ thứ gì bị hạ thấp, trừ khi chúng bị xáo trộn bởi một cái gì đó khác. Như đã đề cập ở trên, các ID phải nhất quán trên các hệ thống trừ khi bạn đang nói về một múi giờ mới được giới thiệu đã được cài đặt trên một hệ thống nhưng không được cài đặt trên một hệ thống khác. Ví dụ: [KB3093504] (https://support.microsoft.com/en-us/kb/3093503) đã giới thiệu "Thời gian chuẩn của Bắc Triều Tiên" trong hotfix. –

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