`"Australia/Lord_Howe"` là múi giờ kỳ lạ nhất
(ssoready.com)- Múi giờ rất phức tạp, nhưng vì máy tính phải triển khai chúng nên mức độ kỳ lạ chỉ nằm trong một phạm vi hữu hạn.
Asia/Kathmanducó độ lệch bất thường so với UTC.Africa/Casablancakhông khớp tốt với mô hình múi giờ nên được hard-code.America/Nuukbắt đầu giờ mùa hè từ -01:00.Africa/CairovàAmerica/Santiagobắt đầu giờ mùa hè vào 24 giờ (không phải 0 giờ).Australia/Lord_Howecó quy tắc giờ mùa hè kỳ lạ nhất.
PGXIIREAM: Giáo hoàng Gregory XIII chi phối mọi thứ
- Phần lớn thế giới sử dụng hệ thống thời gian dựa trên lịch Gregory.
- Lịch Gregory rất hữu ích trong việc giữ vị trí của mặt trời ổn định theo năm.
- UTC là sự chính thức hóa hiện đại của lịch Gregory, và cả thế giới đặt thời gian dựa trên chuẩn này.
Giây nhuận không quan trọng
- Sự quay của Trái Đất đang chậm lại nên người ta thêm giây nhuận để bù lại.
- Có thể bỏ qua giây nhuận vì các ngôn ngữ lập trình không biểu diễn 61 giây.
- Các nhà cung cấp cloud giải quyết vấn đề bằng cách cho đồng hồ chạy chậm lại trong thời gian có giây nhuận.
Những múi giờ kỳ lạ
Asia/Kathmandu có độ lệch bất thường
- Nepal đi trước UTC 5 giờ 45 phút.
- Máy tính có thể biết thông tin này thông qua cơ sở dữ liệu múi giờ IANA.
Các chuỗi như PDT hay CET không có nhiều ý nghĩa
- Định danh múi giờ có thể mơ hồ, và nhiều múi giờ cùng chia sẻ một định danh.
Múi giờ có giờ mùa hè được biểu diễn như thế nào?
- Quy tắc chuyển sang giờ mùa hè rất phức tạp, và máy tính tính giờ địa phương dựa trên đó.
Africa/Casablanca và Asia/Gaza đi theo mặt trăng, còn múi giờ đi theo mặt trời
- Morocco và Gaza điều chỉnh giờ mùa hè theo Ramadan, nên điều này được hard-code.
America/Nuuk chuyển sang giờ mùa hè lúc -1 giờ
- Greenland bắt đầu giờ mùa hè cùng thời điểm với châu Âu, nhưng theo giờ địa phương thì là lúc -1 giờ.
America/Santiago và Africa/Cairo chuyển đổi vào 24 giờ
- Các múi giờ này chuyển sang giờ mùa hè vào 24 giờ, tức là bước sang ngày hôm sau.
Australia/Lord_Howe có lần chuyển giờ mùa hè kỳ lạ nhất
- Đảo Lord Howe có bước chuyển giờ mùa hè 30 phút.
Tóm tắt của GN⁺
- Múi giờ rất phức tạp, nhưng vì máy tính phải triển khai chúng nên mức độ kỳ lạ chỉ nằm trong một phạm vi hữu hạn.
Australia/Lord_Howelà múi giờ độc đáo nhất với bước chuyển giờ mùa hè 30 phút.- Bài viết này hữu ích để hiểu sự phức tạp của múi giờ và có thể khiến lập trình viên thấy thú vị.
- Một dự án có chức năng tương tự là
tzdb.
1 bình luận
Các ý kiến trên Hacker News
Phần thú vị nhất trong cơ sở dữ liệu tz là nó có chứa ước tính thời điểm Big Bang, và được thiết kế để không tính các chuyển đổi múi giờ xảy ra trước Big Bang
Thông điệp commit tại https://github.com/eggert/tz/commit/b22d459a367f4d01b10f6f6b... cũng đại ý là “đừng tạo timestamp trước Big Bang vì chúng đáng ngờ về mặt vật lý”, và ngay sau đó một commit riêng cũng cấm cả leap second trước Big Bang
datetrên Linux/UnixNó có các ví dụ khoảng thế kỷ 15, kể chuyện kiểu một vị vua thích một tuần/tháng nào đó nên ra lệnh lặp lại, hay một vị vua khác ghét một tuần nào đó nên xóa nó khỏi lịch; đó là một bài đọc khá mở mang, nhưng giờ tôi không tìm thấy nữa
Nói cách khác, kết luận là “các thời điểm trước Big Bang nằm ngoài phạm vi của thư viện này, nên nếu một thuật toán chỉ trả về giá trị sai ở trước Big Bang thì thuật toán đó có thể được chấp nhận và không cần cải thiện/thay thế”
Lợi ích so với số bug ở phần đó có vẻ không lớn, và phần lớn sự phức tạp bừa bộn của tzdb nằm ở
zic. Đôi khi tôi có cảm giác sẽ tốt hơn nếuzickhông phải là một artifact mà người khác có thể phụ thuộc vàoTôi mong bản thân múi giờ biến mất trước khi lý thuyết về múi giờ trở nên lỗi thời
Tôi cho rằng múi giờ kỳ lạ nhất là Africa/Addis_Ababa. Chính người Ethiopia địa phương lại không theo cách đó
Ở địa phương, họ dịch giờ đi 6 tiếng: chu kỳ AM bắt đầu lúc rạng sáng, tức 6 giờ sáng, và chu kỳ PM bắt đầu lúc hoàng hôn, tức 6 giờ chiều
https://en.wikipedia.org/wiki/Time_in_Ethiopia
Tương tự, ngày kết thúc lúc 6 giờ chiều, thenashara. Về mặt trực giác thì nó hợp lý hơn đồng hồ kiểu tiếng Anh rất nhiều, và vì đã ăn sâu vào ngôn ngữ nên hiếm khi gây nhầm lẫn về giờ
https://en.wikipedia.org/wiki/Ethiopian_calendar
Lịch Ethiopia gồm 12 tháng, mỗi tháng 30 ngày, và 5 hoặc 6 ngày nhuận tạo thành tháng thứ 13
https://en.wikipedia.org/wiki/Roman_timekeeping
Thế giới nói tiếng Anh trước đây cũng từng đổi năm vào ngày 25 tháng 3: https://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750#...
Về mặt kỹ thuật, cả hai đều không phải đối tượng mà tzdb có thể xử lý. tzdb xử lý civil time, chứ không xử lý lịch hay các hệ thống tính toán khác
Sự kỳ lạ của
Asia/Jerusalemlà vì daylight saving time gắn chặt với vấn đề tách biệt tôn giáo và nhà nước. Những người theo tôn giáo muốn ngày làm việc thuận tiện cho các ngày lễ bắt đầu lúc hoàng hônVì vậy trong nhiều thập kỷ cho đến giữa những năm 2000, daylight saving time là kết quả đàm phán hằng năm giữa các đảng tôn giáo và các đảng thế tục, và thường chỉ được quyết định ngay trước ngày chuyển đổi nên hay gây vấn đề
Dường như vẫn còn một ngoại lệ để daylight saving time không kết thúc vào Rosh HaShanah, nên các quy tắc tương lai trông phức tạp
Nếu EU cuối cùng bãi bỏ thành công thì có thể họ cũng sẽ làm theo
Vì vậy họ không muốn daylight saving time làm một sự kiện vốn đã kết thúc muộn lại càng muộn hơn. Ngoài ra vào ngày ăn chay Yom Kippur, họ muốn việc nhịn ăn kết thúc sớm hơn 1 tiếng. Vì cố khớp với các ngày này nên thời gian áp dụng daylight saving time trở nên quá ngắn, cần phải đàm phán
Nói rằng “ngôn ngữ lập trình không thể biểu diễn một phút dài 61 giây” là không đúng. Có người đã nói rằng Raku hỗ trợ giây nhuận, và điều đó có thể một phần là do lỗi của tôi
Vì
DateTime.pm, thư viện ngày/giờ phổ biến nhất của Perl 5, hỗ trợ giây nhuận, và khi tạoDateTime.pmtôi đã triển khai phần hỗ trợ đóNhìn lại thì gần như chắc chắn đó là một sai lầm. Hầu như không ai quan tâm đến giây nhuận, và nó chỉ tạo ra những nhầm lẫn kỳ lạ như “tại sao cộng 60 giây đôi khi lại khác với cộng 1 phút?”
Đặc biệt, vì tôi cố kiểm tra xem
second => 60có hợp lệ hay không, mã trở nên phức tạp hơn rất nhiều. Constructor nhận các thành phần thời gian và một múi giờ tùy ý, nên để kiểm tra bảng giây nhuận thì phải chuyển sang UTC, nhưng bản thân phép chuyển đổi đó lại vướng vào các giá trị có chứa giây nhuận vì lý do lịch sửNó trở thành một mớ hỗn độn khổng lồ chỉ để đổi lấy lợi ích rất nhỏ, và thư viện ngày/giờ chuẩn của Raku dường như cũng vay mượn khá nhiều từ
DateTime.pmcủa Perl 5, nên tôi cho rằng nó đã thừa hưởng một phần những quyết định thiết kế tệ đóTôi tò mò quá trình suy nghĩ ban đầu là gì. Có phải đã quá đắm chìm vào vấn đề không? Khi ở quá gần một vấn đề và tập trung vào nó quá lâu, niềm vui sửa nó trước khi nó hỏng đôi khi dẫn đến những chuyện như thế này
Nó được định nghĩa đại loại là “Instant là một thời điểm cụ thể được đo bằng giây nguyên tử và phần thập phân của chúng, và không gắn với cũng như không aware về bất kỳ epoch nào”
Đầu năm nay tôi phải viết một hàm tìm giờ địa phương hiện tại khi được cung cấp một địa chỉ ở Mỹ. Cách ngây thơ là ánh xạ tĩnh bang (state) sang múi giờ, nhưng có khá nhiều ngoại lệ khiến không thể làm vậy
Trong ứng dụng đó, chi phí và tốc độ là quan trọng, nên tôi đã mua với giá vài đô một CSV ánh xạ mọi ZIP code của Mỹ sang offset UTC, việc có tuân thủ giờ tiết kiệm ánh sáng ban ngày hay không, v.v.
Vì
pytznhận tên múi giờ IANA, cuối cùng tôi phải ánh xạ thủ công thông tin offset và giờ tiết kiệm ánh sáng ban ngày sang một múi giờ cụ thể, và do các lãnh thổ hải ngoại cùng căn cứ quân sự của Mỹ nên cũng cần những ngữ nghĩa kỳ lạ như múi giờEtc[1] https://en.wikipedia.org/wiki/Tz_database#Area
ZIP code có lẽ cũng đủ, nhưng cần cẩn thận. Nếu số lượng địa chỉ không quá lớn, cách vững chắc hơn là reverse geocoding rồi dùng thư viện lấy định danh IANA từ các đa giác ranh giới múi giờ
https://github.com/RomanIakovlev/timeshape do một đồng nghiệp cũ của tôi duy trì; chúng tôi đã có thể mở mã nguồn một phần công việc từng làm nội bộ
Một hoặc hai hệ thống đóng dấu dữ liệu theo giờ địa phương, còn các hệ thống khác dùng UTC. Tôi đã mua một cuốn Farmers' Almanac cũ để xây thuật toán xử lý giờ tiết kiệm ánh sáng ban ngày, nhưng đọc các quy tắc xong thì tuyệt vọng
Lịch có quy tắc danh nghĩa cho thời điểm chuyển đổi, nhưng kèm chú thích rằng do sự can thiệp của Quốc hội, các quy tắc đã được điều chỉnh qua từng năm và sẽ tiếp tục như vậy. Tôi nói với sếp rằng “nếu tôi có thể viết thuật toán dự đoán các cuộc bỏ phiếu tương lai của Quốc hội, tôi đã thành tỷ phú và bỏ công việc kỹ sư này rồi”
Cuối cùng hình như tôi đã mã hóa các lần chuyển đổi gần đây đã biết và quy tắc danh nghĩa cho tương lai. Đó là trước thời mọi thứ đều nối mạng, và mã chạy trên các máy tính độc lập như VAX, nên cũng không có nhiều cách khác
Việc hợp nhất ba nguồn dữ liệu theo dõi, mỗi nguồn có trạng thái hiệu lực và mức suy giảm chất lượng đo lường riêng, cũng là một cơn ác mộng, nhưng vẫn dễ hơn dự đoán hành động tương lai của Quốc hội
US/Eastern. Sau đó nếu cần offset UTC, hãy dùngpytzáp dụng múi giờ đó cho ngày tương ứng để lấy offsetMúi giờ có tên đặc biệt ở chỗ chúng cố định. Các múi giờ theo offset UTC như
-05:00hoặc viết tắt nhưESTkhông cố định theo thời gian tại một vị trí cụ thể vì giờ tiết kiệm ánh sáng ban ngàyNếu hỏi ai đó về múi giờ mà đưa các lựa chọn là offset hoặc viết tắt, mọi người sẽ bối rối
Tôi dùng thư viện Python này để chuyển vĩ độ/kinh độ → múi giờ: https://github.com/jannikmi/timezonefinder
Nguồn dữ liệu cũng có vẻ là nguồn chất lượng khá cao: https://github.com/evansiroky/timezone-boundary-builder/rele...
Etc. Đặc biệt nếu định hiển thị nguyên mọi định danh cho người dùngTrong tệp đó có chú thích rằng “POSIX lấy phía tây Greenwich là dương, nhưng nhiều người lại kỳ vọng phía đông Greenwich là dương. Ví dụ
TZ='Etc/GMT+4'dùng viết tắt-04và chậm hơn UT 4 giờ, tức là phía tây Greenwich, nhưng nhiều người lại kỳ vọng nó là phía đông, nhanh hơn UT 4 giờ”Múi giờ của Palestine cũng khá kỳ lạ
https://en.wikipedia.org/wiki/Time_in_the_State_of_Palestine
Có giờ tiết kiệm ánh sáng ban ngày, nhưng ngày tháng không cố định; chính phủ công bố thời điểm bắt đầu và kết thúc hằng năm. Đôi khi họ thông báo khi chỉ còn chưa đầy một tuần, nên chắc chắn sẽ phát sinh đủ loại vấn đề thú vị
Ngày bắt đầu và kết thúc giờ tiết kiệm ánh sáng ban ngày của Israel và Palestine không nhất thiết trùng nhau
Tôi thấy gọi một chế độ giờ tiết kiệm ánh sáng ban ngày lệch 30 phút, chứ không phải 1 giờ, là “múi giờ kỳ lạ nhất” thì tiêu chuẩn hơi thấp
Hầu như những cái khác còn lạ hơn. Antarctica/Troll nghe chắc chắn kỳ lạ hơn, còn múi giờ của Morocco và Gaza thì có ít nhất một loại quy tắc khác, đến mức không thể biểu diễn bằng hệ thống hiện có. Những múi giờ bị Apple đưa vào danh sách cấm, nơi việc chuyển đổi diễn ra vào ngày trước một ngày cụ thể, cũng đủ kỳ lạ để làm hỏng thứ gì đó
Tôi đồng ý về giây nhuận. Nó gần như là kiến thức tạp nham hơn là kiến thức hữu ích mà lập trình viên cần biết. Máy tính xử lý giây nhuận bằng smear, và cũng chẳng biết nó xảy ra lúc nào. Hoàn toàn có thể quên nó đi mà sống
Tuy nhiên, từng có lúc các quốc gia chuyển từ cách bỏ qua giây nhuận sang cách tính đến nó, nên việc Australia đổi từ
GMT+xsangUTC+xvài chục năm trước là một sự chuyển đổi từ bỏ qua giây nhuận sang bao gồm nó. Việc thực tế này gần như bị bỏ qua phổ biến có lẽ lại là điều tốtNhưng lúc nào cũng hơi buồn cười khi một tổ chức lớn nói “máy chủ của chúng tôi có độ chính xác thời gian dưới mili giây nhờ đồng bộ GPS và thẻ đồng hồ nguyên tử rubidium PCIe tự phát triển”, đồng thời lại nói “giây nhuận được smear trong suốt một ngày nên thực tế thời gian máy chủ lệch ±0,5 giây cũng không sao”
[1] https://engineering.fb.com/2021/08/11/open-source/time-appli...
[2] https://engineering.fb.com/2020/03/18/production-engineering...
Ví dụ, nếu trời rất nhiều mây thì dù Mặt Trăng ở đâu cũng không thể nhìn thấy. Điều này gây vấn đề khi triển khai lịch cho việc vận hành quốc gia
Nhiều quốc gia chính thức dùng lịch Hồi giáo sử dụng ngày xấp xỉ được tính trước dựa trên khả năng nhìn thấy dự kiến tại một vị trí cụ thể. Vì vậy, lịch Hồi giáo thực ra không phải là một, mà gần như là hai loại: lịch Hồi giáo quan sát và lịch dự đoán; cả hai đều phụ thuộc vào vị trí nơi việc quan sát thực tế hoặc dự đoán được thực hiện
Tôi không biết Morocco hay Gaza làm thế nào
Chỉ có điều giờ Na Uy lại dùng giờ tiết kiệm ánh sáng ban ngày
Nhiều thị trường đã đóng cửa trong thời gian có giây nhuận, và nhiều ngân hàng vẫn dừng mọi giao dịch khi có thay đổi giờ địa phương để giảm rủi ro lỗi
Ngay cả trong những ứng dụng không quá quan tâm đến nó, cũng đã có nhiều lỗi liên quan đến giây nhuận đến mức đáng ngạc nhiên, và có lý do chính đáng để CGPM quyết định bãi bỏ giây nhuận
https://en.wikipedia.org/wiki/Leap_second#Other_reported_sof...
Một bài viết tuyệt vời về những màn nhào lộn của phần mềm múi giờ. Thật sự khá linh hoạt
Nếu tất cả đều là các offset hữu hạn được tự động hóa, thì chính sách giờ mùa hè đâu nhất thiết phải khớp với mức điều chỉnh 60 phút
Biết đâu một quốc gia nào đó có thể quyết định dùng offset thay đổi liên tục quanh năm? Bảng tra cứu offset sẽ dài hơn nhiều, nhưng cách này cũng có thể “giải quyết” giờ mùa hè. Vì cứ điều chỉnh từng chút một nên sẽ khó nhận ra, giống như giây nhuận vậy
Những người dựa vào đồng hồ kim có thể sẽ không còn phải lúc nào cũng chỉnh theo cùng một hướng nữa
Thay đổi 10 phút mỗi tháng dễ thích nghi hơn nhiều, hầu như không nhận ra, và nếu có bỏ lỡ thì cũng không nghiêm trọng như lệch 1 giờ
Cứ bỏ giờ mùa hè đi là xong. Cá nhân tôi thích giờ tiêu chuẩn vĩnh viễn hơn giờ mùa hè vĩnh viễn, nhưng miễn là có thể ngừng việc chỉnh đồng hồ hai lần mỗi năm thì tôi chấp nhận được
Tất nhiên, Trung Quốc thì nổi tiếng là rộng đến vậy mà chỉ có một múi giờ, tạo ra những tình huống thú vị cả trong nội bộ lẫn với bên ngoài
Một giả định thật sự quan trọng nhưng không lộ rõ trong định dạng dữ liệu TZif là khi đi từ giờ địa phương sang giờ UTC thì tối đa chỉ có hai khả năng
Rất nhiều phần mềm dựa vào giả định này; chẳng hạn
java.time.LocalDateTimecówithLaterOffsetAtOverlap(): https://docs.oracle.com/javase/8/docs/api/?java/time/LocalDa...Điều này ngầm giả định rằng khi không rõ 2:30 sáng có nghĩa là gì, thì chỉ có hai lời giải khả dĩ là trước và sau giờ mùa hè. Nếu một múi giờ chỉnh lùi một lần lúc 2:00 sáng rồi lại chỉnh lùi lần nữa lúc 2:15, tạo ra ba lời giải trở lên, thì rất nhiều thứ sẽ không biểu diễn được
Điều tôi thích ở cơ sở dữ liệu tz là về mặt kỹ thuật nó là diff của diff
Vì nó lưu lại sự khác biệt giữa mỗi múi giờ và UTC đã thay đổi ra sao trong lịch sử, nên có thể xem là
diff^2. Nhưng cơ sở dữ liệu tz cũng nhận cập nhật, nên các commit đó là diff của diff của diff, tứcdiff^3Còn có thể đi xa hơn nữa. Có changelog và changelog đó được lưu trong git, nên một commit đối với changelog của tz là
diff^4: một thay đổi đối với danh sách thay đổi của danh sách thay đổi của danh sách thay đổi so với UTCTôi nghĩ điểm cốt lõi là cách đóng khung rằng gần như mọi ngày/giờ thực chất là một tập hợp quy tắc khớp đang được theo dõi
Có thể đoán sẽ mất bao nhiêu giây cho đến khi một khớp được kích hoạt, nhưng không thể hoàn toàn chắc chắn cho tới khi nó thật sự xảy ra; trong một số trường hợp nó còn có thể không xảy ra chính xác bao giờ
Nửa còn lại sau đó là biến phỏng đoán delta “có vẻ sự kiện sẽ xảy ra sau X giây kể từ bây giờ” trở lại thành “khi đó đồng hồ theo múi giờ của bạn có vẻ sẽ hiển thị Y”
Phải nhớ tiếp tục theo dõi múi giờ nào đang chi phối sự kiện, và sự kiện được hiển thị theo múi giờ nào
[1] Ước tính UTC có thể lệch tiến hoặc lùi một lượng bằng giây nhuận. TAI an toàn hơn, nhưng điều đó có thể thay đổi nếu ai đó phát hiện ra một điều mới mẻ thú vị làm thay đổi cách nguyên tử cesium hoạt động
[0] Ví dụ, một quốc gia có thể biến mất và múi giờ cũng biến mất. Hoặc đồng hồ có thể nhảy từ 1:00 sang 2:00, khiến khoảng 1:30–2:00 không thật sự xảy ra một cách chính xác do bị thiếu 1 giờ