Câu hỏi Các phương pháp hay nhất về thời gian và múi giờ tiết kiệm ánh sáng ban ngày [đã đóng]


Tôi hy vọng sẽ đưa ra câu hỏi này và câu trả lời cho nó là hướng dẫn dứt khoát để đối phó với thời gian tiết kiệm ánh sáng ban ngày, đặc biệt là để đối phó với sự thay đổi thực tế.

Nếu bạn có bất cứ điều gì để thêm, xin vui lòng

Nhiều hệ thống phụ thuộc vào việc giữ thời gian chính xác, vấn đề là với những thay đổi về thời gian do tiết kiệm ánh sáng ban ngày - di chuyển đồng hồ về phía trước hoặc phía sau.

Ví dụ, một quy tắc kinh doanh trong một hệ thống lấy lệnh phụ thuộc vào thời điểm của lệnh - nếu đồng hồ thay đổi, các quy tắc có thể không rõ ràng. Làm thế nào thời gian của lệnh phải được duy trì? Tất nhiên là có vô số kịch bản - đây là một kịch bản đơn giản.

  • Bạn đã xử lý vấn đề tiết kiệm ánh sáng ban ngày như thế nào?
  • Giả định nào là một phần của giải pháp của bạn? (tìm kiếm ngữ cảnh ở đây)

Quan trọng, nếu không phải như vậy:

  • Bạn đã thử điều gì đã không hoạt động?
  • Tại sao nó không hoạt động?

Tôi sẽ quan tâm đến lập trình, hệ điều hành, sự kiên trì dữ liệu và các khía cạnh thích hợp khác của vấn đề.

Câu trả lời chung là tuyệt vời, nhưng tôi cũng muốn xem chi tiết đặc biệt nếu chúng chỉ có sẵn trên một nền tảng.


1886


gốc


@abatishchev - Bằng cách này GETDATE() trên SQL sẽ là UTC (như sẽ DateTime.Now). Và máy chủ sẽ không bị ảnh hưởng bởi bất kỳ loại thay đổi DST tự động nào. - Oded
@Oded: Tôi có thể đồng ý nếu "trên máy chủ" sẽ được thêm vào. Nhưng vẫn có thể ảnh hưởng đến các ứng dụng khác cần thời gian địa phương. Bằng cách này và các lý do khác, tôi nghĩ tốt hơn hết là nên yêu cầu thời gian Utc một cách rõ ràng. - abatishchev
UTC được ưu tiên là GMT, cả hai vì nó được định nghĩa chính xác hơn và vì định nghĩa GMT bị sai lệch trên một số hệ điều hành. Thông thường, mọi người đối xử với các cụm từ "GMT" và "UTC" có thể hoán đổi cho nhau nhưng chúng không hoàn toàn. Đối với hầu hết mọi phần mềm / hệ thống, hãy sử dụng UTC. Xem stackoverflow.com/questions/2292334/… - Chris Johnson
@JoshStodola - Jon Skeet 'câu trả lời'. - Kenny Evitt
@Oded bạn không thể giả định máy chủ sẽ được trên UTC, tôi đã nhìn thấy máy chủ sản xuất nơi múi giờ là "UTC" nhưng đã áp dụng DST như vậy đã thực sự UTC + 1 trong hơn một nửa năm. Đồng ý với @abatishchev phải rõ ràng và sử dụng DateTime.UtcNow và GETUTCDATE(), nó cũng cho thấy các nhà phát triển khác mà bạn đã thực sự nghĩ về nó - ono2012


Các câu trả lời:



Tóm tắt câu trả lời và dữ liệu khác: (vui lòng thêm của bạn)

Thực hiện:

  • Bất cứ khi nào bạn đang đề cập đến một thời điểm chính xác trong thời gian, vẫn tồn tại thời gian theo một tiêu chuẩn thống nhất mà không bị ảnh hưởng bởi tiết kiệm ánh sáng ban ngày. (GMT và UTC tương đương với vấn đề này, nhưng được ưu tiên sử dụng thuật ngữ UTC. Lưu ý rằng UTC còn được gọi là Zulu hoặc là Z thời gian.)
  • Thay vào đó, nếu bạn chọn duy trì thời gian bằng cách sử dụng giá trị thời gian cục bộ, hãy bao gồm chênh lệch múi giờ địa phương cho thời gian cụ thể này từ UTC (chênh lệch này có thể thay đổi trong suốt cả năm), sao cho dấu thời gian sau đó có thể được diễn giải một cách rõ ràng.
  • Trong một số trường hợp, bạn có thể cần lưu trữ cả hai thời gian UTC và giờ địa phương tương đương. Thường thì việc này được thực hiện với hai trường riêng biệt, nhưng một số nền tảng hỗ trợ datetimeoffset loại có thể lưu trữ cả hai trong một trường duy nhất.
  • Khi lưu trữ dấu thời gian dưới dạng giá trị số, hãy sử dụng Thời gian Unix - đó là số lượng toàn bộ giây kể từ 1970-01-01T00:00:00Z (không bao gồm giây nhảy). Nếu bạn yêu cầu độ chính xác cao hơn, hãy sử dụng mili giây thay thế. Giá trị này phải luôn dựa trên UTC, không có bất kỳ điều chỉnh múi giờ nào.
  • Nếu sau này bạn có thể cần sửa đổi dấu thời gian, hãy bao gồm ID múi giờ ban đầu để bạn có thể xác định xem chênh lệch có thể đã thay đổi từ giá trị ban đầu được ghi lại hay không.
  • Khi lên lịch các sự kiện trong tương lai, thường là thời gian cục bộ được ưu tiên thay vì UTC, vì nó là phổ biến cho bù đắp thay đổi. Xem câu trả lờibài viết trên blog.
  • Khi lưu trữ toàn bộ ngày, chẳng hạn như sinh nhật và ngày kỷ niệm, không chuyển đổi thành UTC hoặc bất kỳ múi giờ nào khác.
    • Khi có thể, lưu trữ trong kiểu dữ liệu chỉ có ngày không bao gồm thời gian trong ngày.
    • Nếu không có loại như vậy, hãy đảm bảo luôn bỏ qua thời gian trong ngày khi diễn giải giá trị. Nếu bạn không thể yên tâm rằng thời gian trong ngày sẽ bị bỏ qua, hãy chọn 12:00 Trưa, thay vì 00:00 Nửa đêm là thời gian đại diện an toàn hơn vào ngày đó.
  • Hãy nhớ rằng các chênh lệch múi giờ không phải lúc nào cũng là số nguyên của giờ (ví dụ: Giờ chuẩn Ấn Độ là UTC + 05: 30 và Nepal sử dụng UTC + 05: 45).
  • Nếu sử dụng Java, hãy sử dụng java.time cho Java 8 hoặc sử dụng Giờ Joda cho Java 7 trở xuống.
  • Nếu sử dụng .MẠNG LƯỚI, hãy cân nhắc việc sử dụng Giờ Noda.
  • Nếu sử dụng .NET không có thời gian Noda, hãy xem xét DateTimeOffset thường là lựa chọn tốt hơn DateTime.
  • Nếu sử dụng Perl, hãy sử dụng Ngày giờ.
  • Nếu sử dụng Python, hãy sử dụng pytz hoặc là dateutil.
  • Nếu sử dụng JavaScript, hãy sử dụng moment.js với múi giờ sự mở rộng.
  • Nếu sử dụng PHP> 5.2, hãy sử dụng các chuyển đổi múi giờ gốc do DateTimeDateTimeZone các lớp học. Hãy cẩn thận khi sử dụng DateTimeZone::listAbbreviations() - - xem câu trả lời. Để giữ cho PHP cập nhật dữ liệu Olson, hãy cài đặt định kỳ the timezonedb Gói PECL; xem câu trả lời.
  • Nếu sử dụng C ++, hãy đảm bảo sử dụng thư viện sử dụng đúng cách thực hiện Cơ sở dữ liệu múi giờ IANA. Bao gồm các cctz, ICUThư viện "tz" của Howard Hinnant.
    • Không được dùng Tăng cường cho chuyển đổi múi giờ. Trong khi API của nó tuyên bố hỗ trợ các định danh IANA tiêu chuẩn (aka "zoneinfo"), thô sơ ánh xạ chúng với dữ liệu kiểu POSIX, mà không xem xét lịch sử phong phú của các thay đổi mà mỗi vùng có thể có. (Ngoài ra, tệp đã mất bảo trì.)
  • Hầu hết các quy tắc kinh doanh sử dụng thời gian dân sự, thay vì UTC hoặc GMT. Do đó, hãy lên kế hoạch chuyển đổi dấu thời gian UTC thành múi giờ địa phương trước khi áp dụng logic ứng dụng.
  • Hãy nhớ rằng các múi giờ và bù đắp không cố định và có thể thay đổi. Ví dụ, trong lịch sử Hoa Kỳ và Vương quốc Anh đã sử dụng cùng ngày cho 'spring forward' và 'fall back'. Tuy nhiên, trong năm 2007, Hoa Kỳ đã thay đổi ngày mà các đồng hồ được thay đổi. Điều này có nghĩa là trong 48 tuần của năm, sự khác biệt giữa thời gian London và New York là 5 giờ và trong 4 tuần (3 vào mùa xuân, 1 vào mùa thu) là 4 giờ. Hãy nhận biết các mục như thế này trong bất kỳ phép tính nào liên quan đến nhiều vùng.
  • Hãy xem xét loại thời gian (thời gian sự kiện thực tế, thời gian phát sóng, thời gian tương đối, thời gian lịch sử, thời gian định kỳ) các yếu tố (dấu thời gian, múi giờ và tên múi giờ) bạn cần lưu trữ để truy xuất chính xác - xem "Các loại thời gian" câu trả lời này.
  • Giữ cho hệ điều hành, cơ sở dữ liệu của bạn và các tệp tzdata ứng dụng đồng bộ, giữa chính họ và phần còn lại của thế giới.
  • Trên máy chủ, đặt đồng hồ phần cứng và đồng hồ OS thành UTC thay vì múi giờ địa phương.
  • Bất kể điểm đạn trước đó, mã phía máy chủ, bao gồm các trang web, nên không bao giờ mong đợi múi giờ địa phương của máy chủ là bất kỳ điều gì cụ thể. xem câu trả lời.
  • Ưu tiên làm việc với các múi giờ trên cơ sở từng trường hợp trong mã ứng dụng của bạn, thay vì trên toàn cầu thông qua cài đặt tệp cấu hình hoặc mặc định.
  • Sử dụng NTP dịch vụ trên tất cả các máy chủ.
  • Nếu sử dụng FAT32, hãy nhớ rằng dấu thời gian được lưu trữ theo giờ địa phương chứ không phải UTC.
  • Khi xử lý các sự kiện định kỳ (ví dụ: chương trình truyền hình hàng tuần), hãy nhớ rằng thời gian thay đổi với DST và sẽ khác nhau theo múi giờ.
  • Luôn truy vấn các giá trị ngày giờ độc quyền bao gồm giới hạn trên, giới hạn trên (>=, <).

Không:

  • Đừng nhầm lẫn "múi giờ", chẳng hạn như America/New_York với "chênh lệch múi giờ", chẳng hạn như -05:00. Họ là hai việc khác nhau. Xem wiki thẻ múi giờ.
  • Không sử dụng JavaScript Date đối tượng để thực hiện tính toán ngày và thời gian trong các trình duyệt web cũ hơn, vì ECMAScript 5.1 trở xuống có một lỗ hổng thiết kế có thể sử dụng thời gian tiết kiệm ánh sáng ban ngày không chính xác. (Điều này đã được sửa trong ECMAScript 6/2015).
  • Không bao giờ tin tưởng vào đồng hồ của khách hàng. Nó có thể rất không chính xác.
  • Đừng bảo mọi người "luôn sử dụng UTC ở mọi nơi". Lời khuyên phổ biến này được thiển cận một số kịch bản hợp lệ được mô tả trước đó trong tài liệu này. Thay vào đó, hãy sử dụng tham chiếu thời gian thích hợp cho dữ liệu bạn đang làm việc. (Dấu thời gian có thể sử dụng UTC, nhưng không nên lập kế hoạch thời gian trong tương lai và chỉ ngày tháng.)

Thử nghiệm:

  • Khi thử nghiệm, hãy đảm bảo bạn kiểm tra các quốc gia ở phương Tây, miền Đông, miền Bắc và Phía Nam bán cầu não (trên thực tế trong mỗi quý của toàn cầu, vì vậy 4 khu vực), với cả DST đang tiến hành và không (cho 8), và một quốc gia không sử dụng DST (4 khác để bao gồm tất cả các vùng, tổng cộng 12 vùng).
  • Kiểm tra chuyển tiếp của DST, tức là khi bạn đang ở thời điểm mùa hè, hãy chọn một giá trị thời gian từ mùa đông.
  • Kiểm tra các trường hợp ranh giới, chẳng hạn như múi giờ UTC + 12, với DST, làm cho giờ địa phương UTC + 13 vào mùa hè và thậm chí cả những nơi có UTC + 13 vào mùa đông
  • Kiểm tra tất cả thư viện và ứng dụng của bên thứ ba và đảm bảo chúng xử lý dữ liệu múi giờ chính xác.
  • Kiểm tra múi giờ nửa giờ, ít nhất.

Tài liệu tham khảo:

Khác:

  • Hành lang đại diện của bạn để kết thúc abomination đó là DST. Chúng tôi luôn có thể hy vọng ...
  • Hành lang cho Giờ chuẩn trái đất

803



Sử dụng GMT không thực sự giải quyết vấn đề, bạn vẫn cần phải tìm ra gì là đồng bằng phải áp dụng, và đây là nơi mà tất cả sự phức tạp đều nằm. Đồng bằng có thể phức tạp để xác định trong các hệ thống được người dùng sử dụng ở các vùng khác nhau (với lịch trình chuyển đổi tiết kiệm ánh sáng ban ngày khác nhau) hoặc trong các hệ thống hiển thị dữ liệu lịch sử / tương lai. - ckarras
Đó là sự thật nếu tất cả các ứng dụng cần làm là để hiển thị thời gian địa phương hiện tại. Nhưng nếu chúng ta có ví dụ một máy chủ ở Úc cần hiển thị ngày / giờ cho giao dịch ở Canada vào ngày 2 tháng 4 năm 2006 (Đây là năm cuối cùng trước khi quy tắc chuyển đổi tiết kiệm ánh sáng ban ngày thay đổi ở Canada) - bạn có một cuộc gọi hệ điều hành không có thể làm DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)? - ckarras
Có, có một cuộc gọi hệ điều hành như vậy trong Windows - SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx - Michael Madsen
@ tchrist Có thể nếu bạn kiên trì, bạn có thể. - Peter Ajtai
Hãy ghi nhớ chuyển đổi các ngày trong tương lai (ngay cả chỉ ngày mai) sang UTC bạn luôn luôn mất thứ gì đó. Ví dụ: bạn đã sử dụng một số bù đắp đã biết để thực hiện chuyển đổi đó, nhưng kể từ ngày trong tương lai, luôn có khả năng nhóm đặt các quy tắc đó sẽ thay đổi các quy tắc đó. Ngoài ra, hầu như không thể chuyển đổi một số ngày trong tương lai thành UTC vì thời gian tiết kiệm ánh sáng ban ngày không được biết đến cho đến năm đó (một số quốc gia đặt ngày mỗi năm, không vượt quá 10 năm hoặc dựa trên bất kỳ quy tắc nào). - eselk


Tôi không chắc chắn những gì tôi có thể thêm vào các câu trả lời ở trên, nhưng đây là một vài điểm từ tôi:

Các loại lần

Có bốn lần khác nhau bạn nên cân nhắc:

  1. Thời gian sự kiện: ví dụ: thời gian khi một sự kiện thể thao quốc tế diễn ra, hoặc đăng quang / chết / v.v. Điều này phụ thuộc vào múi giờ của sự kiện và không phụ thuộc vào người xem.
  2. Thời gian truyền hình: ví dụ: một chương trình truyền hình cụ thể được phát sóng lúc 9 giờ tối giờ địa phương trên khắp thế giới. Quan trọng khi suy nghĩ về việc xuất bản kết quả (nói American Idol) trên trang web của bạn
  3. Thời gian tương đối: ví dụ: Câu hỏi này có đóng tiền thưởng mở trong 21 giờ. Điều này rất dễ hiển thị
  4. Thời gian định kỳ: ví dụ: Chương trình truyền hình diễn ra vào thứ Hai hàng tuần lúc 9 giờ tối, ngay cả khi DST thay đổi.

Ngoài ra còn có lịch sử / thời gian thay thế. Đây là những khó chịu vì họ có thể không bản đồ trở lại thời gian tiêu chuẩn. Ví dụ: ngày Julian, ngày theo lịch âm lịch trên sao Thổ, lịch Klingon.

Lưu trữ dấu thời gian bắt đầu / kết thúc trong UTC hoạt động tốt. Đối với 1, bạn cần một tên múi giờ sự kiện + offset được lưu trữ cùng với sự kiện. Đối với 2, bạn cần một định danh thời gian địa phương được lưu trữ với mỗi vùng và một tên múi giờ + bù đắp được lưu trữ cho mỗi người xem (có thể lấy được từ IP nếu bạn đang ở trong một cuộc khủng hoảng). Đối với 3, lưu trữ trong UTC giây và không cần múi giờ. 4 là trường hợp đặc biệt của 1 hoặc 2 tùy thuộc vào việc đó là sự kiện toàn cầu hay địa phương, nhưng bạn cũng cần lưu trữ được tạo tại dấu thời gian để bạn có thể biết liệu định nghĩa múi giờ đã thay đổi trước hay sau khi sự kiện này được tạo. Điều này là cần thiết nếu bạn cần hiển thị dữ liệu lịch sử.

Lưu trữ lần

  • Luôn luôn lưu trữ thời gian trong UTC
  • Chuyển đổi thành giờ địa phương trên màn hình (địa phương được xác định bởi người dùng xem dữ liệu)
  • Khi lưu trữ múi giờ, bạn cần tên, dấu thời gian và khoảng trống. Điều này là bắt buộc bởi vì chính phủ đôi khi thay đổi ý nghĩa của múi giờ của họ (ví dụ: govt của Mỹ đã thay đổi ngày DST) và ứng dụng của bạn cần xử lý mọi thứ một cách duyên dáng ... ví dụ: Dấu thời gian chính xác khi tập LOST hiển thị cả trước và sau quy tắc DST đã thay đổi.

Offsets và tên

Một ví dụ ở trên sẽ là:

Trận chung kết cúp bóng đá thế giới game   đã xảy ra ở Nam Phi (UTC + 2 - SAST)   vào ngày 11 tháng 7 năm 2010 lúc 19:00 UTC.

Với thông tin này, chúng tôi có thể xác định chính xác thời gian khi trận chung kết WCS 2010 diễn ra ngay cả khi định nghĩa múi giờ ở Nam Phi thay đổi,  có thể hiển thị cho người xem trong múi giờ địa phương của họ tại thời điểm họ truy vấn cơ sở dữ liệu.

Giờ hệ thống

Bạn cũng cần phải giữ cho hệ điều hành, cơ sở dữ liệu và các tệp tzdata ứng dụng của bạn đồng bộ, cả với nhau, và với phần còn lại của thế giới và thử nghiệm rộng rãi khi bạn nâng cấp. Nó không phải là chưa từng biết rằng một ứng dụng của bên thứ ba mà bạn phụ thuộc vào đã không xử lý một thay đổi TZ một cách chính xác.

Đảm bảo các đồng hồ phần cứng được đặt thành UTC và nếu bạn đang chạy các máy chủ trên toàn thế giới, hãy đảm bảo hệ điều hành của họ cũng được định cấu hình để sử dụng UTC. Điều này trở nên rõ ràng khi bạn cần sao chép các tệp nhật ký apache được xoay theo giờ từ các máy chủ trong nhiều múi giờ. Sắp xếp chúng theo tên tệp chỉ hoạt động nếu tất cả các tệp được đặt tên với cùng một múi giờ. Nó cũng có nghĩa là bạn không phải làm toán ngày trong đầu của bạn khi bạn ssh từ một hộp khác và cần phải so sánh dấu thời gian.

Ngoài ra, chạy ntpd trên tất cả các hộp.

Khách hàng

Không bao giờ tin tưởng dấu thời gian bạn nhận được từ máy khách là hợp lệ. Ví dụ: tiêu đề Ngày: HTTP hoặc javascript Date.getTime() gọi điện. Đây là tiền phạt khi được sử dụng làm số nhận dạng mờ hoặc khi thực hiện phép toán ngày trong một phiên duy nhất trên cùng một ứng dụng nhưng không cố gắng tham chiếu chéo các giá trị này với một số thứ bạn có trên máy chủ. Khách hàng của bạn không chạy NTP và có thể không nhất thiết phải có pin đang hoạt động cho đồng hồ BIOS của họ.

Câu đố

Cuối cùng, các chính phủ đôi khi sẽ làm những điều rất kỳ lạ:

Giờ chuẩn ở Hà Lan là   chính xác là 19 phút và 32,13 giây   trước UTC theo luật từ 1909-05-01   qua 1937-06-30. Múi giờ này   không thể được biểu diễn chính xác bằng cách sử dụng   HH: Định dạng MM.

Ok, tôi nghĩ tôi đã xong.


288



Câu trả lời này có một số điểm tuyệt vời, tôi đặc biệt muốn chỉ ra điều này "Thời gian định kỳ: ví dụ: Chương trình truyền hình vào thứ Hai hàng tuần lúc 9 giờ tối, ngay cả khi DST thay đổi" Lưu trữ thời gian trong UTC trong DB và sau đó chuyển đổi để hiển thị giúp xử lý rất nhiều khía cạnh phức tạp trong việc xử lý các múi giờ. Tuy nhiên, xử lý "các sự kiện lặp lại" mà vượt qua các rào cản DST trở nên khó khăn hơn nhiều. - Jared Hales
1 cho Trivia. Giữ nội dung thú vị làm cho công việc này thú vị hơn, điều này có thể dẫn đến tăng năng suất :) - Chris
Rất nhiều thứ tốt trong câu trả lời này, nhưng một vài vấn đề. 1) Nhiều từ viết tắt múi giờ không rõ ràng. xem ở đây  2) Không luôn luôn bạn có muốn lưu trữ trong UTC không. Hầu hết thời gian - vâng, nhưng ngữ cảnh lại quan trọng. Theo cách của bạn, thời gian truyền hình sẽ không được lưu trữ trong UTC. Ngoài ra, đôi khi chính sách bất hợp pháp hoặc chống lại của nó không lưu trữ giờ địa phương - đó là nơi những thứ như DateTimeOffset (hoặc tương đương) có ích. Nếu không, hãy viết tốt. - Matt Johnson
Trivia Hà Lan trông hợp pháp. ietf.org/rfc/rfc3339.txt phần 5.8. Nửa đường cho rằng ai đó đang kéo chân chúng tôi. - ruffin
Một ví dụ khác cho chính phủ để làm những điều kỳ lạ: timeanddate.com/news/time/turkey-scraps-dst-2016.html - Ad Infinitum


Đây là một vấn đề quan trọng và đáng ngạc nhiên khó khăn. Sự thật là không có tiêu chuẩn hoàn toàn thỏa mãn cho sự bền bỉ thời gian. Ví dụ, tiêu chuẩn SQL và định dạng ISO (ISO 8601) rõ ràng là không đủ.

Từ quan điểm khái niệm, người ta thường đề cập đến hai loại dữ liệu thời gian, và nó thuận tiện để phân biệt chúng (các tiêu chuẩn trên không): "thời gian vật lý"và"thời gian dân sự".

Một khoảnh khắc "vật lý" của thời gian là một điểm trong thời gian phổ quát liên tục mà vật lý đối phó với (bỏ qua thuyết tương đối, tất nhiên). Khái niệm này có thể được mã hóa đầy đủ-persisted trong UTC, ví dụ (nếu bạn có thể bỏ qua giây nhuận).

Thời gian "dân sự" là đặc tả datetime theo định mức dân sự: một thời điểm ở đây được chỉ định đầy đủ bởi một tập hợp các trường datetime (Y, M, D, H, MM, S, FS) cộng với một TZ (đặc tả múi giờ) (cũng là một "lịch", trên thực tế, nhưng cho phép giả sử chúng tôi hạn chế các cuộc thảo luận để lịch Gregorian). Một múi giờ và một lịch cùng nhau cho phép (về nguyên tắc) để ánh xạ từ một biểu diễn này sang một biểu diễn khác. Nhưng các phiên bản thời gian vật lý và dân sự về cơ bản là các loại độ lớn khác nhau, và chúng phải được tách riêng và xử lý một cách khái niệm khác nhau (một sự tương tự: mảng byte và chuỗi ký tự).

Vấn đề là khó hiểu bởi vì chúng ta nói về các loại sự kiện này thay thế cho nhau, và bởi vì thời gian dân sự có thể thay đổi chính trị. Vấn đề (và sự cần thiết phải phân biệt các khái niệm này) trở nên rõ ràng hơn cho các sự kiện trong tương lai. Ví dụ (lấy từ thảo luận của tôi đây.

John ghi lại trong lịch của mình một lời nhắc cho một số sự kiện vào ngày giờ 2019-Jul-27, 10:30:00, TZ =Chile/Santiago, (đã bù đắp GMT-4, do đó nó tương ứng với UTC 2019-Jul-27 14:30:00). Nhưng một ngày nào đó trong tương lai, quốc gia quyết định thay đổi mức bù TZ thành GMT-5.

Bây giờ, khi ngày đến ... lời nhắc nhở đó nên kích hoạt tại

A) 2019-Jul-27 10:30:00 Chile/Santiago  = UTC time 2019-Jul-27 15:30:00 ?

hoặc là

B) 2019-Jul-27 9:30:00 Chile/Santiago  = UTC time 2019-Jul-27 14:30:00 ?

Không có câu trả lời đúng, trừ khi người ta biết ý nghĩa của John khi anh ấy nói với lịch "Hãy gọi cho tôi theo 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Ý anh ấy có nghĩa là "ngày giờ dân sự" ("khi đồng hồ trong thành phố của tôi cho biết 10:30 ")? Trong trường hợp đó, A) là câu trả lời đúng.

Hay anh ta có nghĩa là "thời điểm vật lý của thời gian", một điểm trong liên tục dòng thời gian của vũ trụ của chúng ta, nói, "khi nhật thực tiếp theo "Trong trường hợp đó, câu trả lời B) là đúng.

Một vài API Ngày / Giờ có được sự khác biệt này: trong số đó, Jodatime, là nền tảng của Java DateTime API (JSR 310) tiếp theo (thứ ba!).


81



Một điểm cần xem xét khác mà tôi không thấy được giải quyết trong API là ngay cả khi thời gian và múi giờ được đưa ra, có ít nhất hai ý nghĩa hợp lý cho ví dụ: "13: 00: 00EDT". Nó có thể ám chỉ đến thứ gì đó được biết là đã xảy ra vào lúc 1 giờ địa phương, được cho là Thời gian ban ngày ở phương Đông, hay cái gì đó được biết là đã xảy ra vào thời điểm Đông phương đánh 13:00, được cho là đã xảy ra ở một nơi quan sát Giờ ban ngày miền đông. Nếu có nhiều dấu thời gian trong đó thông tin múi giờ có thể sai (ví dụ: tệp máy ảnh kỹ thuật số) ... - supercat
... biết liệu chúng phản ánh thời gian địa phương chính xác hay thời gian toàn cầu có thể quan trọng trong việc xác định cách sửa chúng. - supercat
Rõ ràng John muốn A) bởi vì mọi người đến làm việc lúc 8:30, bất kể DST hoặc múi giờ hiện tại là gì. Nếu họ đi vào DST, họ sẽ đi làm lúc 8:30, khi họ ra khỏi DST, họ sẽ đi làm lúc 8:30. Nếu quốc gia quyết định chuyển sang múi giờ khác, họ sẽ làm việc lúc 8:30 eveyday - Gianluca Ghettini


Phân biệt rõ ràng các mối quan tâm về kiến ​​trúc - để biết chính xác tầng nào tương tác với người dùng và phải thay đổi ngày giờ cho / từ biểu diễn chuẩn (UTC). Ngày giờ không phải là UTC là bản trình bày (theo múi giờ địa phương của người dùng), Thời gian UTC là mô hình (vẫn duy nhất cho các tầng giữa và giữa).

Cũng thế, quyết định khán giả thực sự của bạn là gì, bạn không phải phục vụ gì và bạn vẽ đường nào. Đừng chạm vào các lịch kỳ lạ trừ khi bạn thực sự có những khách hàng quan trọng ở đó và sau đó xem xét riêng các máy chủ hướng đến người dùng chỉ dành cho khu vực đó.

Nếu bạn có thể có được và duy trì vị trí của người dùng, hãy sử dụng vị trí để chuyển đổi ngày giờ có hệ thống (nói văn hóa .NET hoặc bảng SQL) nhưng cung cấp cách để người dùng cuối chọn các ghi đè nếu ngày giờ quan trọng đối với người dùng của bạn.

Nếu có nghĩa vụ kiểm toán lịch sử tham gia (như nói chính xác khi nào Jo trong AZ đã thanh toán hóa đơn 2 năm trước vào tháng 9) sau đó giữ cả UTC và giờ địa phương cho bản ghi (bảng chuyển đổi của bạn sẽ thay đổi trong một khoảng thời gian).

Xác định múi giờ tham chiếu thời gian cho dữ liệu đi kèm hàng loạt - giống như các tệp, dịch vụ web, vv Công ty Say East Coast có trung tâm dữ liệu trong CA - bạn cần hỏi và biết họ sử dụng tiêu chuẩn nào thay vì giả sử một hoặc khác.

Không tin tưởng các khoảng thời gian trong vùng được nhúng trong phần trình bày văn bản của ngày giờ và không chấp nhận phân tích và theo dõi chúng. Thay vào đó, luôn yêu cầu múi giờ và / hoặc vùng tham chiếu phải được xác định rõ ràng. Bạn có thể dễ dàng nhận được thời gian với bù đắp PST nhưng thời gian thực sự là EST vì đó là thời gian tham chiếu của khách hàng và các bản ghi được xuất chỉ tại một máy chủ đang ở chế độ PST.


53





Bạn cần biết về Olson cơ sở dữ liệu tz, có sẵn từ ftp://elsie.nci.nih.gov/pub  http://iana.org/time-zones/. Nó được cập nhật nhiều lần mỗi năm để đối phó với những thay đổi thường xuyên vào phút cuối khi (và liệu) có chuyển đổi giữa mùa đông và mùa hè (tiêu chuẩn và tiết kiệm ánh sáng ban ngày) ở các quốc gia khác nhau trên thế giới hay không. Trong năm 2009, bản phát hành cuối cùng là năm 2009; trong năm 2010, đó là năm 2010; vào năm 2011, đó là 2011n; vào cuối tháng 5 năm 2012, bản phát hành là 2012c. Lưu ý rằng có một bộ mã để quản lý dữ liệu và dữ liệu múi giờ thực, trong hai lưu trữ riêng biệt (tzcode20xxy.tar.gz và tzdata20xxy.tar.gz). Cả mã và dữ liệu đều thuộc phạm vi công cộng.

Đây là nguồn của các tên múi giờ như America / Los_Angeles (và các từ đồng nghĩa như US / Pacific).

Nếu bạn cần theo dõi các vùng khác nhau, thì bạn cần có cơ sở dữ liệu Olson. Như những người khác đã thông báo, bạn cũng muốn lưu trữ dữ liệu theo định dạng cố định - UTC thường là dữ liệu được chọn - cùng với bản ghi múi giờ trong đó dữ liệu được tạo. Bạn có thể muốn phân biệt giữa chênh lệch giữa UTC tại thời điểm và tên múi giờ; có thể tạo sự khác biệt sau này. Ngoài ra, khi biết rằng hiện tại 2010-03-28T23: 47: 00-07: 00 (Hoa Kỳ / Thái Bình Dương) có thể hoặc không thể giúp bạn giải thích giá trị 2010-11-15T12: 30 - có thể được chỉ định trong PST ( Giờ chuẩn Thái Bình Dương) thay vì PDT (Giờ Tiết kiệm Ánh sáng ngày Thái Bình Dương).

Các giao diện thư viện chuẩn của C không phải là một công cụ vô cùng hữu ích với loại công cụ này.


Các dữ liệu Olson đã di chuyển, một phần vì A D Olson sẽ sớm nghỉ hưu, và một phần vì đã có một (nay bác bỏ) phù hợp với pháp luật chống lại các nhà bảo trì vi phạm bản quyền. Cơ sở dữ liệu múi giờ hiện được quản lý dưới sự bảo trợ của IANA, Internet Assigned Numbers Authority, và có một liên kết trên trang đầu để 'Cơ sở dữ liệu múi giờ'. Danh sách gửi thư thảo luận hiện là tz@iana.org; danh sách thông báo là tz-announce@iana.org.


38



Cơ sở dữ liệu Olson chứa lịch sử dữ liệu là tốt, mà làm cho nó đặc biệt hữu ích để xử lý DST. Ví dụ: biết rằng giá trị UTC tương ứng với ngày 31 tháng 3 năm 2000 ở Hoa Kỳ không phải là DST, nhưng giá trị UTC tương ứng với ngày 31 tháng 3 năm 2008 ở Hoa Kỳ là. - Josh Kelley
Unicode Consortium duy trì một ánh xạ giữa các ID vùng Olson tome và các ID múi giờ của Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/… - Josh Kelley
Đã cập nhật liên kết cho trang của Unicode Consortium: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/… - Span
Bạn có thể tìm thấy thông tin về phân tích cú pháp các tệp Olson ở đâu? Tôi muốn biên dịch nó thành một bảng db, nhưng không thể tìm ra cách tôi nên đọc các tệp - shealtiel
@gidireich: thông tin chính được tìm thấy với dữ liệu và không dễ hiểu. Tài liệu chính cho nó nằm trong zic.8 trang người đàn ông (hoặc zic.8.txt). Bạn sẽ cần tzcode2011i.tar.gz tệp thay vì, hoặc cũng như, tzdata2011i.tar.gz để lấy thông tin này. - Jonathan Leffler


Nói chung, bao gồm bù đắp thời gian cục bộ (bao gồm bù đắp DST) trong dấu thời gian được lưu trữ: Riêng UTC không đủ nếu sau này bạn muốn hiển thị dấu thời gian trong múi giờ ban đầu (và cài đặt DST).

Lưu ý rằng chênh lệch không phải lúc nào cũng là số nguyên của số giờ (ví dụ: Giờ chuẩn Ấn Độ là UTC + 05: 30).

Ví dụ, các định dạng phù hợp là một tuple (thời gian unix, offset in minutes) hoặc ISO 8601.


24



Để hiển thị, bù đắp là hoàn hảo. Nếu bạn muốn thực hiện thay đổi, bù đắp vẫn không đủ. Bạn cũng phải biết múi giờ vì giá trị mới có thể yêu cầu chênh lệch khác nhau. - Matt Johnson


Vượt qua ranh giới của "thời gian máy tính" và "thời gian mọi người" là một cơn ác mộng. Một trong những chính là không có loại tiêu chuẩn cho các quy tắc quản lý múi giờ và thời gian tiết kiệm ánh sáng ban ngày. Các quốc gia có thể tự do thay đổi múi giờ và quy tắc DST của họ bất kỳ lúc nào và họ thực hiện điều đó.

Một số quốc gia, ví dụ: Israel, Brazil, quyết định mỗi năm khi có thời gian tiết kiệm ánh sáng ban ngày, vì vậy không thể biết trước khi nào (nếu) DST sẽ có hiệu lực. Những người khác đã cố định (ish) quy tắc như khi DST có hiệu lực. Các quốc gia khác không sử dụng DST như tất cả.

Múi giờ không phải là sự khác biệt đầy đủ trong giờ GMT. Nepal là +5,45. Thậm chí còn có múi giờ là +13. Đó có nghĩa là:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

là tất cả cùng một thời gian, nhưng 3 ngày khác nhau!

Cũng không có tiêu chuẩn rõ ràng về các từ viết tắt cho múi giờ và cách chúng thay đổi khi ở trong DST, do đó bạn sẽ có những thứ như sau:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

Lời khuyên tốt nhất là tránh xa thời gian địa phương càng nhiều càng tốt và dính vào UTC nơi bạn có thể. Chỉ chuyển đổi thành giờ địa phương ở thời điểm cuối cùng có thể.

Khi thử nghiệm, hãy đảm bảo rằng bạn kiểm tra các quốc gia ở bán cầu Tây và Đông, với cả DST đang tiến hành và không phải là quốc gia không sử dụng DST (tổng cộng 6 lần).


22



Về Israel - điều này đúng một nửa. Mặc dù thời gian cho sự thay đổi DST không phải là một ngày cụ thể trong lịch Julian - có một quy tắc dựa trên lịch Do Thái (có sự thay đổi trong năm 2014). Dù sao, ý tưởng chung là chính xác - những điều này có thể và làm thay đổi một lần trong một thời gian - Yaron U.
Ngoài ra, AST = Giờ chuẩn Đại Tây Dương. Đối với 'lời khuyên tốt nhất', nó không quan trọng như một điểm khởi đầu, nhưng bạn cần phải đọc phần còn lại của trang này, và nói một lời cầu nguyện nhỏ, và bạn có thể làm cho nó đúng một lúc. - DavidWalley


Đối với PHP:

Lớp DateTimeZone trong PHP> 5.2 đã được dựa trên Olson DB mà người khác đề cập, vì vậy nếu bạn đang thực hiện chuyển đổi múi giờ trong PHP và không phải trong DB, bạn được miễn làm việc với các tệp Olson (khó hiểu).

Tuy nhiên, PHP không được cập nhật thường xuyên như Olson DB, do đó, chỉ cần sử dụng chuyển đổi múi giờ của PHP có thể để lại cho bạn thông tin DST lỗi thời và ảnh hưởng đến tính chính xác của dữ liệu của bạn. Mặc dù điều này không được dự kiến ​​xảy ra thường xuyên, điều này có thể xảy ra và sẽ xảy ra nếu bạn có nhiều người dùng trên toàn thế giới.

Để đối phó với vấn đề trên, hãy sử dụng gói timezonedb pecl, đó là chức năng là cập nhật dữ liệu múi giờ của PHP. Cài đặt gói này thường xuyên như nó được cập nhật. (Tôi không chắc liệu các gói này có cập nhật chính xác theo bản cập nhật Olson hay không, nhưng có vẻ như nó được cập nhật ở tần số ít nhất là rất gần với bản cập nhật Olson.)


18





Nếu thiết kế của bạn có thể chứa nó, tránh tất cả thời gian chuyển đổi cục bộ! 

Tôi biết một số điều này nghe có vẻ điên rồ nhưng suy nghĩ về UX: người dùng xử lý gần, ngày tương đối (hôm nay, hôm qua, thứ hai tới) nhanh hơn so với ngày tuyệt đối (2010.09.17, Thứ Sáu ngày 17 tháng 9). Và khi bạn nghĩ về nó nhiều hơn, độ chính xác của múi giờ (và DST) quan trọng hơn là ngày càng gần now(), vì vậy nếu bạn có thể diễn tả ngày / giờ trong một định dạng tương đối cho +/- 1 hoặc 2 tuần, phần còn lại của ngày có thể là UTC và nó sẽ không quan trọng quá nhiều đến 95% người dùng.

Bằng cách này bạn có thể lưu trữ tất cả các ngày trong UTC và thực hiện so sánh tương đối trong UTC và chỉ hiển thị ngày UTC của người dùng bên ngoài Ngưỡng ngày tương đối của bạn.

Điều này cũng có thể áp dụng cho đầu vào của người dùng quá (nhưng nói chung trong một thời trang hạn chế hơn). Chọn từ menu thả xuống chỉ có {Ngày hôm qua, Hôm nay, Ngày mai, Thứ Hai tới, Thứ Năm tới} sẽ đơn giản hơn và dễ dàng hơn cho người dùng hơn là công cụ chọn ngày. Bộ chọn ngày là một số trong những thành phần gây đau nhất của việc điền biểu mẫu. Tất nhiên điều này sẽ không làm việc cho tất cả các trường hợp nhưng bạn có thể thấy rằng nó chỉ mất một chút thiết kế thông minh để làm cho nó rất mạnh mẽ.


15



+1 Ý tưởng thú vị. UTC có thể là một điều tuyệt vời; o) - Jon Onstott


Trong khi tôi đã không thử nó, một cách tiếp cận để điều chỉnh múi giờ tôi sẽ tìm thấy hấp dẫn sẽ như sau:

  1. Lưu trữ mọi thứ trong UTC.

  2. Tạo bảng TZOffsets với ba cột: RegionClassId, StartDateTime và OffsetMinutes (int, tính bằng phút).

Trong bảng, lưu trữ danh sách ngày và giờ khi nào thời gian địa phương đã thay đổi và bao nhiêu. Số lượng các vùng trong bảng và số ngày sẽ tùy thuộc vào phạm vi ngày và khu vực của thế giới bạn cần hỗ trợ. Hãy suy nghĩ về điều này như thể nó là "lịch sử" ngày, mặc dù những ngày nên bao gồm tương lai cho một số giới hạn thực tế.

Khi bạn cần tính thời gian địa phương của bất kỳ thời gian UTC nào, chỉ cần thực hiện việc này:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Bạn có thể muốn cache bảng này trong ứng dụng của bạn và sử dụng LINQ hoặc một số phương tiện tương tự để thực hiện các truy vấn thay vì nhấn vào cơ sở dữ liệu.

Dữ liệu này có thể được chưng cất từ cơ sở dữ liệu tz miền công cộng.

Ưu điểm và chú thích của phương pháp này:

  1. Không có quy tắc nào được đưa vào mã, bạn có thể điều chỉnh độ lệch cho các vùng hoặc phạm vi ngày mới dễ dàng.
  2. Bạn không cần phải hỗ trợ mọi phạm vi ngày hoặc vùng, bạn có thể thêm chúng khi cần.
  3. Các vùng không cần phải tương ứng trực tiếp với các ranh giới địa chính trị, và để tránh trùng lặp các hàng (ví dụ, hầu hết các tiểu bang ở Hoa Kỳ xử lý DST theo cùng một cách), bạn có thể có các mục RegionClass rộng liên kết trong một bảng khác với các danh sách truyền thống khác tiểu bang, quốc gia, v.v.
  4. Đối với các tình huống như Hoa Kỳ, nơi bắt đầu và ngày kết thúc của DST đã thay đổi trong vài năm qua, điều này khá dễ giải quyết.
  5. Vì trường StartDateTime có thể lưu trữ thời gian, thời gian thay đổi tiêu chuẩn 2:00 AM được xử lý dễ dàng.
  6. Không phải ở khắp mọi nơi trên thế giới sử dụng DST 1 giờ. Điều này xử lý những trường hợp dễ dàng.
  7. Bảng dữ liệu là nền tảng chéo và có thể là một dự án mã nguồn mở riêng biệt có thể được sử dụng bởi các nhà phát triển sử dụng gần như bất kỳ nền tảng cơ sở dữ liệu hoặc ngôn ngữ lập trình nào.
  8. Điều này có thể được sử dụng cho offsets mà không có gì để làm với múi giờ. Ví dụ: các điều chỉnh 1 giây xảy ra theo thời gian để điều chỉnh xoay vòng trái đất, điều chỉnh lịch sử và trong lịch Gregorian, v.v.
  9. Vì đây là trong một bảng cơ sở dữ liệu, các truy vấn báo cáo chuẩn, v.v. có thể tận dụng dữ liệu mà không có một chuyến đi thông qua mã logic nghiệp vụ.
  10. Điều này cũng xử lý bù trừ múi giờ nếu bạn muốn và thậm chí có thể tính đến các trường hợp lịch sử đặc biệt khi một vùng được gán cho múi giờ khác. Tất cả những gì bạn cần là một ngày ban đầu gán thời gian bù đắp múi giờ cho mỗi vùng với ngày bắt đầu tối thiểu. Điều này sẽ yêu cầu tạo ít nhất một vùng cho từng múi giờ, nhưng sẽ cho phép bạn đặt các câu hỏi thú vị như: "Sự khác biệt giữa giờ địa phương giữa Yuma, Arizona và Seattle, Washington vào ngày 2 tháng 2 năm 1989 lúc 5:00 sáng?" (Chỉ cần trừ một SUM () từ cái còn lại).

Bây giờ, nhược điểm duy nhất của phương pháp này Hay bất cứ thứ gì khác đó là chuyển đổi từ giờ địa phương để GMT không hoàn hảo, vì bất kỳ thay đổi DST nào có chênh lệch âm với đồng hồ lặp lại thời gian địa phương đã cho. Không có cách nào dễ dàng để đối phó với điều đó, tôi sợ, đó là một lý do để lưu trữ thời gian địa phương là tin xấu ở nơi đầu tiên.


15



Ý tưởng cơ sở dữ liệu của bạn đã được triển khai làm Cơ sở dữ liệu Olson. Mặc dù thời gian tiết kiệm ánh sáng ban ngày tạo ra sự chồng chéo chỉ định múi giờ cụ thể ban ngày có thể giúp giải quyết vấn đề. 2:15 EST và 2:15 EDT là thời điểm khác nhau. Như đã lưu ý trong các bài viết khác xác định bù đắp cũng giải quyết sự mơ hồ. - BillThor
Vấn đề lớn với việc giữ cơ sở dữ liệu của riêng bạn là giữ cho nó được cập nhật. Olson và Windows được duy trì cho bạn. Tôi đã có nhiều trường hợp chuyển đổi DST kém vì bảng đã lỗi thời. Ripping chúng ra hoàn toàn và dựa vào một khuôn khổ hoặc cơ sở dữ liệu cấp độ hệ điều hành là đáng tin cậy hơn nhiều. - Matt Johnson
Không tạo cơ sở dữ liệu của riêng bạn: luôn dựa vào API của hệ thống! - Alex


Tôi đã nhấn điều này trên hai loại hệ thống, "hệ thống lập kế hoạch thay đổi (ví dụ: công nhân nhà máy)" và "hệ thống quản lý phụ thuộc khí đốt ..."

23 và 25 giờ dài ngày là một nỗi đau để đối phó với, vì vậy là 8 giờ thay đổi mà mất 7 giờ hoặc 9 giờ. Vấn đề là bạn sẽ thấy rằng mỗi khách hàng, hoặc thậm chí bộ phận của khách hàng có các quy tắc khác nhau mà họ đã tạo ra (thường không có tài liệu) về những gì họ làm trong những trường hợp đặc biệt này.

Một số câu hỏi tốt nhất không được yêu cầu của khách hàng cho đến sau khi họ đã trả tiền cho phần mềm “ngoài giá” của bạn. Rất hiếm khi tìm thấy một khách hàng nghĩ về loại vấn đề này ở phía trước khi mua phần mềm.

Tôi nghĩ rằng trong mọi trường hợp, bạn nên ghi lại thời gian trong UTC và chuyển đổi sang / từ giờ địa phương trước khi lưu trữ ngày / giờ. Tuy nhiên, ngay cả khi biết thời gian nhất định có thể gặp khó khăn với việc tiết kiệm ánh sáng ban ngày và múi giờ.


12



Bạn gái của tôi, một y tá, làm việc đêm và họ phải viết múi giờ trong quá trình chuyển đổi DST. Ví dụ: 2AM CST so với CDAM 2AM - Joe Phillips
Có, điều này là phổ biến: khi bạn tính trung bình hàng ngày (dân sự), bạn phải đối phó với những ngày 23, 24 hoặc 25 giờ. Kết quả là, khi bạn tính toán thêm 1 ngày không thêm 24 giờ! Thứ hai, đừng cố gắng xây dựng mã múi giờ của riêng bạn; chỉ sử dụng hệ thống API. Và đừng quên cập nhật từng hệ thống được triển khai để có được cơ sở dữ liệu múi giờ cập nhật. - Alex