Praktik terbaik zona waktu hemat waktu dan zona waktu [ditutup]


2046

Saya berharap untuk membuat pertanyaan ini dan jawaban untuk itu panduan definitif untuk berurusan dengan waktu musim panas, khususnya untuk berurusan dengan perubahan perubahan yang sebenarnya.

Jika Anda memiliki sesuatu untuk ditambahkan, silakan lakukan

Banyak sistem bergantung pada menjaga waktu yang akurat, masalahnya adalah perubahan waktu karena penghematan siang hari - menggerakkan jam maju atau mundur.

Misalnya, seseorang memiliki aturan bisnis dalam sistem pengambilan pesanan yang bergantung pada waktu pesanan - jika jam berubah, aturan mungkin tidak sejelas ini. Bagaimana seharusnya waktu pesanan dipertahankan? Tentu saja ada banyak skenario yang tak ada habisnya - yang ini hanyalah ilustrasi.

  • Bagaimana Anda menangani masalah penghematan siang hari?
  • Asumsi apa yang merupakan bagian dari solusi Anda? (mencari konteks di sini)

Sama pentingnya, jika tidak lebih dari itu:

  • Apa yang Anda coba yang tidak berhasil?
  • Mengapa itu tidak berhasil?

Saya akan tertarik pada pemrograman, OS, kegigihan data dan aspek terkait lainnya dari masalah ini.

Jawaban umum sangat bagus, tetapi saya juga ingin melihat detail terutama jika hanya tersedia pada satu platform.


2
@abatishchev - Cara ini GETDATE()pada SQL akan menjadi UTC (seperti yang akan DateTime.Now). Dan server tidak akan terpengaruh oleh perubahan DST otomatis apa pun.
Oded

4
@Oded: Saya bisa setuju jika "di server" akan ditambahkan. Namun tetap saja itu dapat mempengaruhi aplikasi lain yang membutuhkan waktu lokal. Dengan alasan ini dan lainnya saya pikir lebih baik untuk meminta Utc waktu secara eksplisit.
abatishchev

7
UTC lebih disukai daripada GMT, baik karena lebih tepat didefinisikan dan karena definisi GMT kacau pada beberapa sistem operasi. Adalah umum bagi orang-orang untuk memperlakukan istilah "GMT" dan "UTC" sebagai yang dapat dipertukarkan tetapi tidak sepenuhnya. Untuk hampir semua tujuan perangkat lunak / sistem, gunakan UTC. Lihat stackoverflow.com/questions/2292334/…
Chris Johnson

7
@JoshStodola - ' jawaban ' Jon Skeet .
Kenny Evitt

1
@Daftar Anda tidak dapat menganggap servernya berada di UTC, saya telah melihat server produksi di mana zona waktu "UTC" tetapi sudah menerapkan DST, jadi sebenarnya UTC + 1 lebih dari setengah tahun. Setuju dengan @abatishchev untuk menjadi eksplisit dan digunakan DateTime.UtcNowdan GETUTCDATE(), itu juga menunjukkan pengembang lain bahwa Anda benar-benar memikirkannya
ono2012

Jawaban:


940

Ringkasan jawaban dan data lain: (silakan tambahkan milik Anda)

Melakukan:

  • Setiap kali Anda merujuk pada saat yang tepat dalam waktu, tetapkan waktu sesuai dengan standar terpadu yang tidak terpengaruh oleh penghematan siang hari. (GMT dan UTC setara dengan hal ini, tetapi lebih disukai menggunakan istilah UTC. Perhatikan bahwa UTC juga dikenal sebagai Zulu atau waktu Z. )
  • Jika sebaliknya Anda memilih untuk bertahan waktu menggunakan nilai waktu lokal, sertakan offset waktu lokal untuk waktu khusus ini dari UTC (offset ini dapat berubah sepanjang tahun), sedemikian rupa sehingga cap waktu nanti dapat diartikan secara jelas.
  • Dalam beberapa kasus, Anda mungkin perlu untuk menyimpan baik waktu UTC dan waktu setempat setara. Seringkali ini dilakukan dengan dua bidang terpisah, tetapi beberapa platform mendukung datetimeoffsetjenis yang dapat menyimpan keduanya dalam satu bidang tunggal.
  • Saat menyimpan cap waktu sebagai nilai numerik, gunakan waktu Unix - yang merupakan jumlah seluruh detik sejak 1970-01-01T00:00:00Z(tidak termasuk detik kabisat). Jika Anda membutuhkan presisi lebih tinggi, gunakan milidetik saja. Nilai ini harus selalu didasarkan pada UTC, tanpa penyesuaian zona waktu.
  • Jika nanti Anda perlu memodifikasi timestamp, sertakan ID zona waktu asli sehingga Anda dapat menentukan apakah offset mungkin telah berubah dari nilai awal yang direkam.
  • Saat menjadwalkan acara mendatang, biasanya waktu lokal lebih disukai daripada UTC, karena biasanya offset diganti. Lihat jawaban , dan posting blog .
  • Saat menyimpan seluruh tanggal, seperti ulang tahun dan hari jadi, jangan mengonversi ke UTC atau zona waktu lainnya.
    • Jika memungkinkan, simpan dalam tipe data hanya tanggal yang tidak termasuk waktu hari.
    • Jika jenis seperti itu tidak tersedia, pastikan untuk selalu mengabaikan waktu saat menafsirkan nilai. Jika Anda tidak dapat yakin bahwa waktu hari akan diabaikan, pilih 12:00 siang, daripada 00:00 Tengah malam sebagai waktu perwakilan yang lebih aman pada hari itu.
  • Ingatlah bahwa offset zona waktu tidak selalu merupakan jumlah jam bilangan bulat (misalnya, Waktu Standar India adalah UTC + 05: 30, dan Nepal menggunakan UTC + 05: 45).
  • Jika menggunakan Java, gunakan java.time untuk Java 8 dan yang lebih baru.
  • Jika menggunakan .NET , pertimbangkan untuk menggunakan Noda Time .
  • Jika menggunakan .NET tanpa Noda Time, pertimbangkan bahwa DateTimeOffsetseringkali merupakan pilihan yang lebih baik daripada DateTime.
  • Jika menggunakan Perl, gunakan DateTime .
  • Jika menggunakan Python, gunakan pytz atau dateutil .
  • Jika menggunakan JavaScript, gunakan moment.js dengan ekstensi zona waktu-saat .
  • Jika menggunakan PHP> 5.2, gunakan konversi zona waktu asli yang disediakan oleh DateTime, dan DateTimeZonekelas. Hati-hati saat menggunakan DateTimeZone::listAbbreviations()- lihat jawaban . Untuk menjaga agar PHP selalu mendapatkan data terbaru Olson, instal paket PECL timezonedb secara berkala ; lihat jawabannya .
  • Jika menggunakan C ++, pastikan untuk menggunakan pustaka yang menggunakan basis data zona waktu IANA dengan benar . Ini termasuk perpustakaan cctz , ICU , dan Howard Hinnant "tz" .
    • Jangan gunakan Peningkatan untuk konversi zona waktu. Sementara API-nya mengklaim mendukung pengidentifikasi IANA (alias "zoneinfo") standar, API secara kasar memetakannya ke data gaya POSIX, tanpa mempertimbangkan sejarah perubahan yang kaya yang dimiliki masing-masing zona. (Selain itu, file tersebut tidak lagi dalam pemeliharaan.)
  • Jika menggunakan Rust, gunakan chrono .
  • Sebagian besar aturan bisnis menggunakan waktu sipil, bukan UTC atau GMT. Karenanya, rencanakan untuk mengonversi stempel waktu UTC ke zona waktu lokal sebelum menerapkan logika aplikasi.
  • Ingatlah bahwa zona waktu dan offset tidak diperbaiki dan dapat berubah. Misalnya, secara historis AS dan Inggris menggunakan tanggal yang sama untuk 'melompat ke depan' dan 'mundur'. Namun, pada tahun 2007 AS mengubah tanggal saat jam berubah. Ini sekarang berarti bahwa selama 48 minggu dalam setahun perbedaan antara waktu London dan waktu New York adalah 5 jam dan selama 4 minggu (3 pada musim semi, 1 pada musim gugur) adalah 4 jam. Waspadai hal-hal seperti ini dalam perhitungan apa pun yang melibatkan banyak zona.
  • Pertimbangkan jenis waktu (waktu acara aktual, waktu siaran, waktu relatif, waktu historis, waktu berulang) elemen apa (stempel waktu, offset zona waktu dan nama zona waktu) yang perlu Anda simpan untuk pengambilan yang benar - lihat "Jenis Waktu" di jawaban ini .
  • Menyinkronkan file tzdata OS, basis data, dan aplikasi Anda, di antara mereka dan seluruh dunia.
  • Di server, atur jam perangkat keras dan jam OS ke UTC daripada zona waktu lokal.
  • Terlepas dari poin sebelumnya, kode sisi server, termasuk situs web, tidak boleh mengharapkan zona waktu lokal server menjadi sesuatu yang khusus. Lihat jawaban .
  • Lebih suka bekerja dengan zona waktu berdasarkan kasus per kasus dalam kode aplikasi Anda, daripada secara global melalui pengaturan file konfigurasi atau default.
  • Gunakan NTP layanan di semua server.
  • Jika menggunakan FAT32 , ingat bahwa cap waktu disimpan dalam waktu lokal, bukan UTC.
  • Ketika berhadapan dengan acara berulang (acara TV mingguan, misalnya), ingatlah bahwa waktu berubah dengan DST dan akan berbeda di seluruh zona waktu.
  • Selalu kueri nilai tanggal-waktu sebagai inklusif batas bawah, batas atas eksklusif ( >=, <).

Jangan:

  • Jangan bingung "zona waktu", seperti America/New_Yorkdengan "zona waktu offset", seperti -05:00. Mereka adalah dua hal yang berbeda. Lihat wiki tag zona waktu .
  • Jangan menggunakan objek JavaScript Dateuntuk melakukan perhitungan tanggal dan waktu di browser web yang lebih lama, karena ECMAScript 5.1 dan yang lebih rendah memiliki cacat desain yang dapat menggunakan waktu musim panas secara salah. (Ini diperbaiki dalam ECMAScript 6/2015).
  • Jangan pernah mempercayai jam klien. Mungkin salah.
  • Jangan bilang orang untuk "selalu menggunakan UTC di mana-mana". Saran yang tersebar luas ini adalah pandangan picik dari beberapa skenario valid yang dijelaskan sebelumnya dalam dokumen ini. Sebagai gantinya, gunakan referensi waktu yang sesuai untuk data yang Anda kerjakan. ( Timestamping dapat menggunakan UTC, tetapi penjadwalan waktu di masa depan dan nilai hanya tanggal tidak boleh.)

Pengujian:

  • Saat menguji, pastikan Anda menguji negara di Barat, Timur, Utara dan Selatan belahan bumi (pada kenyataannya di setiap kuartal dunia, jadi 4 wilayah), dengan kedua DST sedang berlangsung dan tidak (memberi 8), dan negara yang tidak tidak menggunakan DST (4 lainnya untuk mencakup semua wilayah, membuat total 12).
  • Uji transisi DST, yaitu saat Anda berada di waktu musim panas, pilih nilai waktu dari musim dingin.
  • Uji batas kasus, seperti zona waktu yaitu UTC + 12, dengan DST, menjadikan waktu lokal UTC + 13 di musim panas dan bahkan tempat-tempat yang UTC + 13 di musim dingin
  • Tes semua perpustakaan dan aplikasi pihak ketiga dan pastikan mereka menangani data zona waktu dengan benar.
  • Tes zona waktu setengah jam, setidaknya.

Referensi:

Lain:

  • Lobi perwakilan Anda untuk mengakhiri kekejian yang DST. Kita selalu bisa berharap ...
  • Lobi untuk Waktu Standar Bumi

31
Menggunakan GMT tidak benar-benar menyelesaikan masalah, Anda masih perlu mencari tahu apa delta yang tepat untuk diterapkan, dan di sinilah semua kompleksitas berada. Delta dapat menjadi kompleks untuk menentukan dalam sistem yang digunakan oleh pengguna di berbagai wilayah (dengan jadwal sakelar daylight saving berbeda) atau dalam sistem yang menunjukkan data historis / mendatang.
ckarras

10
Itu benar jika semua aplikasi perlu lakukan adalah untuk menampilkan waktu setempat saat ini. Tetapi jika kita memiliki misalnya server di Australia yang perlu menampilkan tanggal / waktu untuk transaksi di Kanada pada 2 April 2006 (Ini adalah tahun terakhir sebelum aturan switching hemat cahaya siang hari berubah di Kanada) - apakah Anda memiliki panggilan OS yang dapat melakukan DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)?
ckarras

22
Ya, ada panggilan OS di Windows - SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
Michael Madsen

7
@tchrist Mungkin jika Anda gigih Anda bisa.
Peter Ajtai

16
Ingatlah bahwa mengonversi tanggal mendatang (bahkan besok saja) ke UTC Anda selalu kehilangan sesuatu. Misalnya, Anda menggunakan beberapa offset yang diketahui untuk melakukan konversi itu, tetapi karena tanggalnya di masa depan, selalu ada kemungkinan grup yang menetapkan aturan tersebut akan mengubah aturan itu. Juga, hampir tidak mungkin untuk mengubah beberapa tanggal di masa mendatang ke UTC karena waktu penghematan siang hari tidak diketahui sampai tahun itu (beberapa negara menetapkan tanggal setiap tahun, bukan 10+ tahun ke depan atau berdasarkan pada aturan yang ditetapkan).
eselk

319

Saya tidak yakin apa yang dapat saya tambahkan ke jawaban di atas, tetapi berikut adalah beberapa poin dari saya:

Jenis kali

Ada empat waktu berbeda yang harus Anda pertimbangkan:

  1. Waktu acara: mis., Waktu peristiwa olahraga internasional terjadi, atau penobatan / kematian / dll. Ini tergantung pada zona waktu acara dan bukan penampil.
  2. Waktu televisi: misalnya, acara TV tertentu disiarkan pada jam 9 malam waktu setempat di seluruh dunia. Penting ketika berpikir tentang menerbitkan hasil (katakanlah American Idol) di situs web Anda
  3. Waktu relatif: mis .: Pertanyaan ini memiliki penutupan karunia terbuka dalam 21 jam. Ini mudah ditampilkan
  4. Waktu berulang: mis. Acara TV setiap hari Senin jam 9 malam, bahkan ketika DST berubah.

Ada juga waktu bersejarah / alternatif. Ini menjengkelkan karena mereka mungkin tidak memetakan kembali ke waktu standar. Contoh: Tanggal Julian, tanggal menurut kalender Lunar di Saturnus, kalender Klingon.

Menyimpan cap waktu mulai / berakhir di UTC berfungsi dengan baik. Untuk 1, Anda memerlukan nama zona waktu acara + offset yang disimpan bersama dengan acara tersebut. Untuk 2, Anda memerlukan pengidentifikasi waktu lokal yang disimpan dengan masing-masing wilayah dan nama zona waktu lokal + offset yang disimpan untuk setiap pengunjung (dimungkinkan untuk menurunkan ini dari IP jika Anda berada dalam krisis). Selama 3, simpan dalam UTC detik dan tidak perlu zona waktu. 4 adalah kasus khusus 1 atau 2 tergantung pada apakah itu acara global atau lokal, tetapi Anda juga perlu menyimpan yang dibuat di stempel waktu sehingga Anda dapat mengetahui apakah definisi zona waktu berubah sebelum atau setelah acara ini dibuat. Ini diperlukan jika Anda perlu menampilkan data historis.

Menyimpan waktu

  • Selalu simpan waktu dalam UTC
  • Konversikan ke waktu lokal pada tampilan (lokal didefinisikan oleh pengguna melihat data)
  • Saat menyimpan zona waktu, Anda memerlukan nama, stempel waktu, dan offset. Ini diperlukan karena pemerintah kadang-kadang mengubah arti zona waktu mereka (misalnya: pemerintah AS mengubah tanggal DST), dan aplikasi Anda perlu menangani hal-hal dengan anggun ... misalnya: Stempel waktu yang tepat ketika episode HILANG menunjukkan sebelum dan sesudah aturan DST berubah.

Offset dan nama

Contoh di atas adalah:

Pertandingan final piala dunia sepak bola terjadi di Afrika Selatan (UTC + 2 - SAST) pada 11 Juli 2010 pukul 19.00 UTC.

Dengan informasi ini, kami secara historis dapat menentukan waktu yang tepat ketika final WCS 2010 berlangsung bahkan jika definisi zona waktu Afrika Selatan berubah, dan dapat menampilkannya kepada pemirsa di zona waktu lokal mereka pada saat mereka menanyakan database.

Waktu sistem

Anda juga perlu menyimpan file tzdata OS, database, dan aplikasi Anda dalam sinkronisasi, baik satu sama lain, dan dengan seluruh dunia, dan menguji secara luas ketika Anda memutakhirkan. Bukan tidak pernah terdengar bahwa aplikasi pihak ketiga yang Anda andalkan tidak menangani perubahan TZ dengan benar.

Pastikan jam perangkat keras diatur ke UTC, dan jika Anda menjalankan server di seluruh dunia, pastikan OS mereka juga dikonfigurasi untuk menggunakan UTC. Ini menjadi jelas ketika Anda perlu menyalin file log apache yang diputar setiap jam dari server di beberapa zona waktu. Mengurutkannya berdasarkan nama file hanya berfungsi jika semua file diberi nama dengan zona waktu yang sama. Ini juga berarti bahwa Anda tidak harus melakukan matematika tanggal di kepala ketika Anda ssh dari satu kotak ke kotak lainnya dan perlu membandingkan cap waktu.

Juga, jalankan ntpd di semua kotak.

Klien

Jangan pernah percaya cap waktu yang Anda dapatkan dari mesin klien valid. Misalnya, Tanggal: tajuk HTTP, atau Date.getTime()panggilan javascript . Ini baik-baik saja ketika digunakan sebagai pengidentifikasi buram, atau ketika melakukan matematika tanggal selama satu sesi pada klien yang sama, tetapi jangan mencoba referensi silang nilai-nilai ini dengan sesuatu yang Anda miliki di server. Klien Anda tidak menjalankan NTP, dan mungkin tidak memiliki baterai yang berfungsi untuk jam BIOS mereka.

Hal sepele

Akhirnya, pemerintah terkadang akan melakukan hal-hal yang sangat aneh:

Waktu standar di Belanda tepat 19 menit dan 32,13 detik di atas UTC secara hukum dari 1909-05-01 hingga 1937-06-30. Zona waktu ini tidak dapat direpresentasikan secara tepat menggunakan format HH: MM.

Ok, saya pikir saya sudah selesai.


6
Jawaban ini memiliki beberapa poin bagus, saya terutama ingin menunjukkan bagian ini "Waktu berulang: misalnya: Acara TV setiap hari Senin jam 9 malam, bahkan ketika DST berubah" Menyimpan waktu dalam UTC dalam DB dan kemudian mengonversi untuk tampilan membantu menangani banyak aspek rumit dalam berurusan dengan zona waktu. Namun, menangani "acara berulang" yang melintasi hambatan DST menjadi lebih sulit.
Jared Hales

45
+1 untuk Trivia. Menjaga konten tetap menarik membuat tugas ini lebih menyenangkan, yang dapat menyebabkan peningkatan produktivitas :)
Chris

4
Banyak hal bagus dalam jawaban ini, tetapi beberapa masalah. 1) Banyak singkatan zona waktu ambigu. lihat di sini 2) Tidak selalu ingin Anda simpan di UTC. Sebagian besar waktu - ya, tetapi konteks penting. Dalam ketentuan Anda, waktu televisi tidak akan disimpan dalam UTC. Juga, terkadang melanggar hukum atau melanggar kebijakan untuk tidak menyimpan waktu setempat - yang mana hal-hal seperti DateTimeOffset(atau setara) sangat berguna. Kalau tidak, tulis yang baik.
Matt Johnson-Pint

1
Jadi, semua orang setuju bahwa perpustakaan Joda sejauh ini merupakan alat terbaik yang tersedia untuk pekerjaan itu. Namun, kita perlu terus memperbarui (membangun kembali) file jar JODA sesuai artikel ini ( joda.org/joda-time/tz_update.html ) agar tetap up to date dengan informasi zona waktu terbaru. Apakah ada cara standar untuk mengunduh data zona waktu terbaru dari situs web IANA ( iana.org/time-zones ) dan membangun kembali perpustakaan joda? Dengan kata lain, apakah mungkin untuk mengotomatiskan proses ini daripada melakukannya secara manual?
saravana_pc

2
Trivia Belanda terlihat sah. ietf.org/rfc/rfc3339.txt bagian 5.8. Setengah jalan mengira seseorang sedang menarik kaki kami.
ruffin

89

Ini adalah masalah yang sulit dan penting. Yang benar adalah bahwa tidak ada standar yang sepenuhnya memuaskan untuk waktu yang bertahan lama. Sebagai contoh, standar SQL dan format ISO (ISO 8601) jelas tidak cukup.

Dari sudut pandang konseptual, orang biasanya berurusan dengan dua jenis data tanggal-waktu, dan lebih mudah untuk membedakannya (standar di atas tidak): " waktu fisik " dan " waktu sipil ".

Instan waktu "fisik" adalah titik dalam garis waktu universal berkesinambungan yang dihadapi fisika (tentu saja, mengabaikan relativitas). Konsep ini dapat dikodekan secara memadai dalam UTC, misalnya (jika Anda dapat mengabaikan detik kabisat).

Waktu "sipil" adalah spesifikasi waktu pakai yang mengikuti norma sipil: titik waktu di sini ditentukan sepenuhnya oleh seperangkat bidang waktu pakai (Y, M, D, H, MM, S, FS) ditambah TZ (spesifikasi zona waktu) (juga "kalender", sebenarnya; tetapi mari kita asumsikan kita membatasi diskusi untuk kalender Gregorian). Zona waktu dan kalender secara bersama memungkinkan (pada prinsipnya) untuk memetakan dari satu representasi ke yang lain. Tetapi contoh waktu sipil dan fisik pada dasarnya berbeda jenis besarnya, dan mereka harus disimpan secara konseptual dipisahkan dan diperlakukan secara berbeda (analogi: array byte dan string karakter).

Masalahnya membingungkan karena kita berbicara tentang peristiwa semacam ini secara bergantian, dan karena masa sipil dapat berubah secara politik. Masalahnya (dan kebutuhan untuk membedakan konsep-konsep ini) menjadi lebih jelas untuk peristiwa di masa depan. Contoh (diambil dari diskusi saya di sini .

John mencatat dalam kalendernya pengingat untuk beberapa acara pada waktu tayang 2019-Jul-27, 10:30:00, TZ = Chile/Santiago, (yang telah mengimbangi GMT-4, maka itu sesuai dengan UTC 2019-Jul-27 14:30:00). Tetapi suatu hari di masa depan, negara memutuskan untuk mengubah TZ offset ke GMT-5.

Sekarang, ketika hari itu tiba ... jika pengingat itu memicu

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

atau

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

Tidak ada jawaban yang benar, kecuali ada yang tahu apa yang dimaksud secara konseptual John ketika ia mengatakan pada kalender "Tolong telepon saya di 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Apakah maksudnya "waktu kencan sipil" ("ketika jam di kota saya memberi tahu pukul 10:30")? Dalam hal itu, A) adalah jawaban yang benar.

Atau apakah yang dia maksudkan adalah "instan fisik waktu", sebuah titik dalam garis waktu alam semesta kita, katakan, "ketika gerhana matahari berikutnya terjadi". Dalam hal itu, jawaban B) adalah yang benar.

Beberapa Date / Time API mendapatkan pembedaan ini dengan benar: di antaranya, Jodatime , yang merupakan fondasi Java DateTime API (ketiga!) Berikutnya (ketiga!).


1
Poin lain untuk dipertimbangkan yang belum pernah saya bahas dalam API adalah bahwa bahkan ketika waktu dan zona waktu diberikan, setidaknya ada dua arti yang masuk akal untuk mis. "13: 00: 00EDT". Itu bisa merujuk pada sesuatu yang diketahui terjadi pada jam 1 siang waktu setempat, yang diyakini sebagai Waktu Siang Timur, atau sesuatu yang diketahui terjadi pada saat waktu bagian Timur pukul 13:00, yang diyakini telah terjadi di tempat yang mengamati Waktu Siang Timur. Jika seseorang memiliki banyak cap waktu di mana info zona waktu mungkin salah (mis. File kamera digital) ...
supercat

1
... mengetahui apakah mereka mencerminkan waktu lokal yang akurat atau waktu global mungkin penting dalam menentukan cara memperbaikinya.
supercat

3
Jelas John menginginkan A) karena orang pergi bekerja pada pukul 8:30, apa pun DST atau zona waktu saat ini. Jika mereka masuk ke DST, mereka akan pergi bekerja pada pukul 8:30, ketika mereka keluar dari DST, mereka akan pergi bekerja pada pukul 8:30. Jika negara itu memutuskan untuk pindah ke zona waktu lain, mereka akan pergi bekerja pada jam 8:30 setiap hari
Gianluca Ghettini

59

Buat pemisahan arsitektural yang jelas dari keprihatinan - untuk mengetahui dengan tepat tier mana yang berinteraksi dengan pengguna, dan harus mengubah tanggal-waktu untuk / dari representasi kanonik (UTC). Tanggal-waktu non-UTC adalah presentasi (mengikuti zona waktu pengguna), waktu UTC adalah model (tetap unik untuk back-end dan tingkatan menengah).

Juga, putuskan apa audiens Anda yang sebenarnya, apa yang tidak harus Anda layani dan di mana Anda menentukan batas . Jangan menyentuh kalender eksotis kecuali Anda benar-benar memiliki pelanggan penting di sana dan kemudian pertimbangkan server terpisah yang menghadap pengguna hanya untuk wilayah itu.

Jika Anda dapat memperoleh dan memelihara lokasi pengguna, gunakan lokasi untuk konversi tanggal-waktu yang sistematis (katakanlah .NET culture atau tabel SQL) tetapi berikan cara bagi pengguna akhir untuk memilih penggantian jika tanggal-waktu sangat penting bagi pengguna Anda.

Jika ada kewajiban audit historis yang terlibat (seperti memberi tahu kapan Jo di AZ membayar tagihan 2 tahun lalu pada bulan September) maka simpanlah waktu UTC dan waktu setempat untuk dicatat (tabel konversi Anda akan berubah dalam perjalanan waktu).

Tetapkan zona waktu referensial waktu untuk data yang datang dalam bentuk seperti file, layanan web, dll. Katakanlah East Coast company memiliki pusat data di CA - Anda perlu bertanya dan tahu apa yang mereka gunakan sebagai standar alih-alih dengan asumsi satu atau yang lain.

Jangan mempercayai offset zona waktu yang tertanam dalam representasi tekstual dari tanggal-waktu dan tidak menerima untuk mem-parsing dan mengikuti mereka. Alih-alih selalu meminta zona waktu dan / atau zona referensi harus didefinisikan secara eksplisit . Anda dapat dengan mudah menerima waktu dengan PST offset tetapi waktu sebenarnya EST karena itulah waktu referensi klien dan catatan baru saja diekspor di server yang ada di PST.


40

Anda perlu tahu tentang basis data Olson tz , yang tersedia di ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . Diperbaharui beberapa kali per tahun untuk menghadapi perubahan yang sering menit terakhir ketika (dan apakah) beralih antara waktu musim dingin dan musim panas (penghematan standar dan siang hari) di berbagai negara di seluruh dunia. Pada tahun 2009, rilis terakhir adalah tahun 2009; pada 2010, itu 2010n; pada 2011, itu 2011n; pada akhir Mei 2012, rilisnya adalah 2012c. Perhatikan bahwa ada satu set kode untuk mengelola data dan data zona waktu aktual itu sendiri, dalam dua arsip terpisah (tzcode20xxy.tar.gz dan tzdata20xxy.tar.gz). Baik kode dan data berada dalam domain publik.

Ini adalah sumber nama zona waktu seperti Amerika / Los_Angeles (dan sinonim seperti AS / Pasifik).

Jika Anda perlu melacak zona yang berbeda, maka Anda memerlukan database Olson. Seperti yang disarankan orang lain, Anda juga ingin menyimpan data dalam format tetap - UTC biasanya yang dipilih - bersama dengan catatan zona waktu di mana data dihasilkan. Anda mungkin ingin membedakan antara offset dari UTC pada waktu dan nama zona waktu; yang bisa membuat perbedaan nanti. Juga, mengetahui bahwa saat ini 2010-03-28T23: 47: 00-07: 00 (AS / Pasifik) mungkin atau mungkin tidak membantu Anda dengan menafsirkan nilai 2010-11-15T12: 30 - yang mungkin ditentukan dalam PST ( Waktu Standar Pasifik) daripada PDT (Waktu Hemat Siang Pasifik).

Antarmuka C library standar tidak terlalu membantu dengan hal-hal semacam ini.


Data Olson telah dipindahkan, sebagian karena AD Olson akan segera pensiun, dan sebagian karena ada (sekarang diberhentikan) gugatan hukum terhadap pengelola atas pelanggaran hak cipta. Database zona waktu sekarang dikelola di bawah naungan IANA , Otoritas Angka yang Ditugaskan Internet, dan ada tautan di halaman depan ke 'Database Zona Waktu' . Milis diskusi sekarang tz@iana.org; daftar pengumumannya adalah tz-announce@iana.org.


12
Basis data Olson juga berisi data historis , yang membuatnya sangat berguna untuk menangani DST. Misalnya, ia tahu bahwa nilai UTC yang sesuai dengan 31 Maret 2000 di AS tidak dalam DST, tetapi nilai UTC yang sesuai dengan 31 Maret 2008 di AS adalah.
Josh Kelley

3
Konsorsium Unicode memelihara pemetaan antara ID zona tome Olson dan ID zona waktu Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Josh Kelley

Tautan yang diperbarui untuk halaman Konsorsium Unicode: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Span

Di mana orang dapat menemukan informasi tentang penguraian file Olson? Saya ingin mengkompilasinya ke dalam tabel db, tetapi tidak tahu bagaimana saya harus membaca file
shealtiel

@ gidireich: informasi utama ditemukan dengan data, dan tidak mudah dimengerti. Dokumentasi utama untuk itu ada di zic.8halaman manual (atau zic.8.txt). Anda akan memerlukan tzcode2011i.tar.gzfile daripada, atau juga, tzdata2011i.tar.gzfile untuk mendapatkan informasi ini.
Jonathan Leffler

26

Secara umum, sertakan offset waktu lokal (termasuk offset DST) dalam stempel waktu tersimpan: UTC saja tidak cukup jika Anda nanti ingin menampilkan stempel waktu di zona waktu aslinya (dan pengaturan DST).

Perlu diingat bahwa offset tidak selalu merupakan jumlah jam bilangan bulat (mis. Waktu Standar India adalah UTC + 05: 30).

Misalnya, format yang sesuai adalah tuple (waktu unix, offset dalam hitungan menit) atau ISO 8601 .


5
Untuk tampilan, offsetnya sempurna. Jika Anda ingin melakukan perubahan, offset masih belum cukup. Anda juga harus mengetahui zona waktu karena nilai baru mungkin memerlukan offset yang berbeda.
Matt Johnson-Pint

23

Melintasi batas "waktu komputer" dan "waktu orang" adalah mimpi buruk. Yang utama adalah bahwa tidak ada semacam standar untuk aturan yang mengatur zona waktu dan waktu musim panas. Negara bebas mengubah zona waktu dan aturan DST kapan saja, dan mereka melakukannya.

Beberapa negara misalnya Israel, Brasil, memutuskan setiap tahun kapan memiliki waktu musim panas, sehingga tidak mungkin untuk mengetahui sebelumnya kapan (jika) DST akan berlaku. Yang lain telah memperbaiki (ish) aturan kapan DST berlaku. Negara-negara lain tidak menggunakan DST sama sekali.

Zona waktu tidak harus menjadi perbedaan jam penuh dari GMT. Nepal adalah +5,45. Bahkan ada zona waktu yang +13. Itu berarti:

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

semuanya bersamaan, namun 3 hari berbeda!

Juga tidak ada standar yang jelas tentang singkatan zona waktu, dan bagaimana mereka berubah ketika di DST sehingga Anda berakhir dengan hal-hal seperti ini:

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

Saran terbaik adalah menjauhi waktu setempat sebanyak mungkin dan tetaplah pada UTC di mana Anda bisa. Konversi hanya ke waktu lokal pada saat terakhir yang mungkin.

Saat pengujian pastikan Anda menguji negara di belahan bumi Barat dan Timur, dengan DST sedang berlangsung dan tidak dan negara yang tidak menggunakan DST (total 6).


Mengenai Israel - ini setengah benar. Meskipun waktu untuk perubahan DST bukan tanggal spesifik dalam kalender Julian - ada aturan berdasarkan kalender Ibrani (ada perubahan pada 2014). Pokoknya, ide umumnya benar - hal ini mungkin dan sesekali berubah
Yaron U.

1
Juga, AST = Waktu Standar Atlantik. Adapun 'saran terbaik', tidak apa-apa sebagai titik awal, tetapi Anda perlu membaca sisa halaman ini, dan mengucapkan sedikit doa, dan Anda mungkin akan melakukannya dengan benar untuk sementara waktu.
DavidWalley

20

Untuk PHP:

Kelas DateTimeZone di PHP> 5.2 sudah didasarkan pada Olson DB yang disebutkan orang lain, jadi jika Anda melakukan konversi zona waktu dalam PHP dan bukan dalam DB, Anda dibebaskan untuk bekerja dengan file Olson (yang sulit dipahami).

Namun, PHP tidak diperbarui sesering Olson DB, jadi hanya menggunakan konversi zona waktu PHP dapat membuat Anda dengan informasi DST yang ketinggalan zaman dan memengaruhi kebenaran data Anda. Meskipun hal ini tidak diharapkan sering terjadi, ini mungkin terjadi, dan akan terjadi jika Anda memiliki basis pengguna yang besar di seluruh dunia.

Untuk mengatasi masalah di atas, gunakan paket peczon timezonedb . Fungsinya untuk memperbarui data zona waktu PHP. Instal paket ini sesering diperbarui. (Saya tidak yakin apakah pembaruan pada paket ini mengikuti persis pembaruan Olson, tetapi tampaknya diperbarui pada frekuensi yang setidaknya sangat dekat dengan frekuensi pembaruan Olson.)


18

Jika desain Anda dapat menampungnya, hindari konversi waktu setempat secara bersamaan!

Saya tahu beberapa hal ini mungkin terdengar gila tetapi pikirkan tentang UX: proses pengguna dekat, tanggal relatif (hari ini, kemarin, Senin depan) lebih cepat daripada tanggal absolut (2010.09.17, Jumat 17 September) secara sekilas. Dan ketika Anda memikirkannya lebih lanjut, keakuratan zona waktu (dan DST) lebih penting semakin dekat tanggalnya now(), jadi jika Anda dapat mengekspresikan tanggal / waktu dalam format relatif untuk +/- 1 atau 2 minggu, sisa dari tanggal dapat UTC dan itu tidak masalah terlalu banyak untuk 95% pengguna.

Dengan cara ini Anda dapat menyimpan semua tanggal dalam UTC dan melakukan perbandingan relatif dalam UTC dan hanya menunjukkan tanggal UTC pengguna di luar Ambang Batas Tanggal Relatif Anda.

Ini juga dapat berlaku untuk input pengguna (tetapi umumnya dengan cara yang lebih terbatas). Memilih dari drop-down yang hanya memiliki {Yesterday, Today, Tomorrow, Monday Next, Thursday Next} jauh lebih sederhana dan lebih mudah bagi pengguna daripada pemilih tanggal. Pemetik tanggal adalah beberapa komponen pengisian formulir yang paling menyakitkan. Tentu saja ini tidak akan bekerja untuk semua kasus tetapi Anda dapat melihat bahwa hanya dibutuhkan sedikit desain yang pintar untuk membuatnya sangat kuat.


16

Meskipun saya belum mencobanya, pendekatan penyesuaian zona waktu yang menurut saya menarik adalah sebagai berikut:

  1. Simpan semuanya dalam UTC.

  2. Buat tabel TZOffsetsdengan tiga kolom: RegionClassId, StartDateTime, dan OffsetMinutes (int, dalam menit).

Di tabel, simpan daftar tanggal dan waktu ketika waktu setempat berubah, dan seberapa banyak. Jumlah wilayah dalam tabel dan jumlah tanggal akan tergantung pada kisaran tanggal dan wilayah mana yang perlu Anda dukung. Pikirkan ini seolah-olah itu adalah tanggal "historis", meskipun tanggal harus mencakup masa depan hingga batas praktis.

Ketika Anda perlu menghitung waktu lokal setiap waktu UTC, lakukan saja ini:

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

Anda mungkin ingin men-cache tabel ini di aplikasi Anda dan menggunakan LINQ atau cara serupa untuk melakukan kueri daripada memukul database.

Data ini dapat disaring dari domain publik tz basis data .

Keuntungan dan catatan kaki dari pendekatan ini:

  1. Tidak ada aturan yang dimasukkan ke dalam kode, Anda dapat menyesuaikan offset untuk wilayah baru atau rentang tanggal dengan mudah.
  2. Anda tidak harus mendukung setiap rentang tanggal atau wilayah, Anda dapat menambahkannya sesuai kebutuhan.
  3. Wilayah tidak harus berhubungan langsung dengan batas geopolitik, dan untuk menghindari duplikasi baris (misalnya, sebagian besar negara bagian di AS menangani DST dengan cara yang sama), Anda dapat memiliki entri RegionClass luas yang menautkan dalam tabel lain ke daftar yang lebih tradisional dari daftar negara bagian, negara, dll.
  4. Untuk situasi seperti AS di mana tanggal mulai dan berakhir DST telah berubah selama beberapa tahun terakhir, ini cukup mudah untuk ditangani.
  5. Karena bidang StartDateTime dapat menyimpan waktu juga, waktu penggantian standar 2:00 pagi ditangani dengan mudah.
  6. Tidak di mana pun di dunia ini menggunakan DST 1 jam. Ini menangani kasus-kasus itu dengan mudah.
  7. Tabel data adalah lintas-platform dan dapat berupa proyek open-source terpisah yang dapat digunakan oleh pengembang yang menggunakan hampir semua platform basis data atau bahasa pemrograman.
  8. Ini dapat digunakan untuk offset yang tidak ada hubungannya dengan zona waktu. Misalnya, penyesuaian 1 detik yang terjadi dari waktu ke waktu untuk menyesuaikan rotasi Bumi, penyesuaian historis ke dan dalam kalender Gregorian, dll.
  9. Karena ini ada dalam tabel database, permintaan laporan standar, dll. Dapat memanfaatkan data tanpa melakukan perjalanan melalui kode logika bisnis.
  10. Ini menangani offset zona waktu juga jika Anda menginginkannya, dan bahkan dapat menjelaskan kasus historis khusus di mana suatu wilayah ditugaskan ke zona waktu lain. Yang Anda butuhkan hanyalah tanggal awal yang menetapkan offset zona waktu untuk setiap wilayah dengan tanggal mulai minimal. Ini membutuhkan pembuatan setidaknya satu wilayah untuk setiap zona waktu, tetapi akan memungkinkan Anda untuk mengajukan pertanyaan menarik seperti: "Apa perbedaan waktu lokal antara Yuma, Arizona dan Seattle, Washington pada 2 Februari 1989 pukul 5:00 pagi?" (Cukup kurangi satu SUM () dari yang lain).

Sekarang, satu-satunya kelemahan dari pendekatan ini atau yang lain adalah bahwa konversi dari waktu setempat ke GMT tidak sempurna, karena perubahan DST yang memiliki offset negatif ke jam mengulangi waktu setempat yang diberikan. Tidak ada cara mudah untuk berurusan dengan yang itu, saya khawatir, yang merupakan salah satu alasan menyimpan waktu lokal adalah berita buruk di tempat pertama.


8
Gagasan basis data Anda telah diterapkan sebagai Olson Database. Sementara daylight saving time menciptakan tumpang tindih yang menentukan zona waktu spesifik siang hari dapat membantu menyelesaikan masalah. 2:15 EST dan 2:15 EDT adalah waktu yang berbeda. Sebagaimana dicatat dalam posting lain yang menentukan offset juga menyelesaikan ambiguitas.
BillThor

5
Masalah besar dengan menjaga database Anda sendiri adalah menjaganya agar tetap diperbarui. Olson dan Windows dikelola untuk Anda. Saya memiliki lebih dari satu kasus mengalami transisi DST yang buruk karena tabel sudah ketinggalan zaman. Merobek mereka sepenuhnya dan mengandalkan kerangka kerja atau basis data tingkat OS jauh lebih dapat diandalkan.
Matt Johnson-Pint

4
Jangan membuat database Anda sendiri : selalu mengandalkan API sistem!
Alex

15

Saya baru-baru ini memiliki masalah dalam aplikasi web di mana pada post-back Ajax datetime kembali ke kode sisi server saya berbeda dari datetime dilayani.

Kemungkinan besar itu berkaitan dengan kode JavaScript saya pada klien yang membangun tanggal untuk memposting kembali ke klien sebagai string, karena JavaScript menyesuaikan zona waktu dan penghematan siang hari, dan di beberapa browser perhitungan untuk kapan menerapkan penghematan siang hari tampaknya berbeda dari yang lain.

Pada akhirnya saya memilih untuk menghapus perhitungan tanggal dan waktu pada klien sepenuhnya, dan diposting kembali ke server saya pada kunci integer yang kemudian diterjemahkan ke waktu tanggal di server, untuk memungkinkan transformasi yang konsisten.

Pembelajaran saya dari ini: Jangan gunakan perhitungan tanggal dan waktu JavaScript dalam aplikasi web kecuali Anda benar-benar harus melakukannya.


Javascript berjalan di mesin klien, bukan di mesin server. Datetime dasar Javascript adalah waktu klien, bukan waktu server.
BalusC

Hai BalusC. Saya mengerti ini (dari posting asli saya: "skrip javacode pada klien yang membuat tanggal ..."). Masalah saya adalah bahwa mesin klien tertentu memproses DST dengan satu cara, dan beberapa lainnya dengan cara lain. Oleh karena itu saya memindahkan semua sisi server pemrosesan untuk mencegah keanehan browser
Joon

@ Joon — dan ada bug dalam implementasi javascript yang tidak dapat Anda deteksi atau izinkan. Jadi ya, jangan pernah menggunakan perhitungan tanggal ECMAScript sisi klien untuk hal-hal yang penting (meskipun Anda bisa melakukan pekerjaan yang cukup baik sebaliknya).
RobG

14

Saya telah mencapai ini pada dua jenis sistem, “sistem perencanaan shift (misalnya pekerja pabrik)” dan “sistem manajemen ketergantungan gas)…

23 dan 25 jam hari yang panjang adalah rasa sakit untuk mengatasinya, demikian juga shift 8 jam yang memakan waktu 7 jam atau 9 jam. Masalahnya adalah Anda akan menemukan bahwa setiap pelanggan, atau bahkan departemen pelanggan memiliki aturan berbeda yang mereka buat (seringkali tanpa mendokumentasikan) tentang apa yang mereka lakukan dalam kasus khusus ini.

Beberapa pertanyaan sebaiknya tidak ditanyakan kepada pelanggan sampai mereka membayar perangkat lunak "off the shelf" Anda. Sangat jarang menemukan pelanggan yang memikirkan masalah seperti ini di muka saat membeli perangkat lunak.

Saya pikir dalam semua kasus Anda harus mencatat waktu dalam UTC dan mengkonversi ke / dari waktu setempat sebelum menyimpan tanggal / waktu. Namun, bahkan tahu yang memerlukan waktu tertentu bisa sulit dengan Daylight saving dan zona waktu.


6
Pacar saya, seorang perawat, bekerja malam dan mereka harus menulis zona waktu selama pergantian DST. Misalnya, 2AM CST vs 2AM CDT
Joe Phillips

1
Ya, ini biasa: ketika Anda menghitung rata-rata harian (sipil), Anda harus menghadapi hari-hari 23, 24, atau 25 jam. Akibatnya, ketika Anda menghitung tambahkan 1 hari itu tidak menambah 24 jam ! Kedua, jangan mencoba membangun kode zona waktu Anda sendiri; hanya menggunakan sistem API. Dan jangan lupa untuk memperbarui setiap sistem yang digunakan untuk mendapatkan basis data zona waktu terbaru .
Alex

12

Untuk web, aturannya tidak rumit ...

  • Sisi server, gunakan UTC
  • Sisi klien, gunakan Olson
    • Alasan: UTC-offsets tidak aman siang hari (misalnya New York adalah EST (UTC - 5 Jam) bagian dari tahun ini, EDT (UTC - 4 Jam) sepanjang tahun).
    • Untuk penentuan zona waktu sisi klien, Anda memiliki dua opsi:
      • 1) Memiliki zona pengaturan pengguna (Lebih aman)
      • 2) Zona deteksi otomatis

Sisanya hanya konversi UTC / lokal menggunakan perpustakaan datetime sisi server Anda. Baik untuk pergi...


2
Ini adalah saran yang bagus sebagai titik awal, tetapi ini sepenuhnya tergantung pada aplikasi. Ini mungkin baik untuk situs web yang ramah, tetapi jika ada aspek hukum / yurisdiksi / keuangan untuk aplikasi Anda yang mungkin dituntut seseorang (saya telah mengerjakan beberapa), maka ini adalah penyederhanaan yang berlebihan karena ada berbagai jenis ' waktu ', sebagaimana dicatat di tempat lain di halaman ini.
DavidWalley

12

Ketika datang ke aplikasi yang berjalan di server , termasuk situs web dan layanan back-end lainnya, pengaturan zona waktu server harus diabaikan oleh aplikasi.

Saran umum adalah mengatur zona waktu server ke UTC. Ini memang praktik terbaik yang baik, tetapi ada sebagai bantuan band untuk aplikasi yang tidak mengikuti praktik terbaik lainnya. Misalnya, suatu layanan mungkin menulis untuk mencatat file dengan stempel waktu lokal alih-alih stempel waktu berbasis UTC, sehingga menciptakan ambiguitas selama transisi musim gugur dari waktu mundur. Pengaturan zona waktu server untuk UTC akan memperbaiki bahwa aplikasi. Namun perbaikan sebenarnya adalah aplikasi untuk login menggunakan UTC untuk memulai.

Kode sisi server, termasuk situs web, tidak boleh mengharapkan zona waktu lokal server menjadi sesuatu yang khusus.

Dalam beberapa bahasa, zona waktu lokal dapat dengan mudah masuk ke kode aplikasi. Misalnya, DateTime.ToUniversalTimemetode dalam .NET akan dikonversi dari zona waktu lokal ke UTC, dan DateTime.Nowproperti mengembalikan waktu saat ini di zona waktu lokal. JugaDate konstruktor dalam JavaScript menggunakan zona waktu lokal komputer. Ada banyak contoh lain seperti ini. Penting untuk berlatih pemrograman defensif, menghindari kode apa pun yang menggunakan pengaturan zona waktu lokal komputer.

Cadangan menggunakan zona waktu lokal untuk kode sisi klien, seperti aplikasi desktop, aplikasi seluler, dan JavaScript sisi klien.


11

Tetap atur server Anda ke UTC, dan pastikan semuanya dikonfigurasi untuk ntp atau yang setara.

UTC menghindari masalah penghematan waktu siang hari, dan server yang tidak sinkron dapat menyebabkan hasil yang tidak terduga yang memerlukan waktu untuk didiagnosis.


9

Hati-hati ketika berhadapan dengan stempel waktu yang disimpan dalam sistem file FAT32 - ini selalu bertahan dalam koordinat waktu lokal (yang mencakup DST - lihat artikel msdn ). Terbakar yang itu.


Poin yang bagus. NTFS tidak memiliki masalah ini, tetapi beberapa orang masih menggunakan FAT32 - terutama pada kunci USB.
Matt Johnson-Pint

7

Satu hal lagi, pastikan server menerapkan patch tabungan siang hari yang terkini.

Kami memiliki situasi tahun lalu di mana waktu kami secara konsisten habis satu jam untuk periode tiga minggu untuk pengguna di Amerika Utara, meskipun kami menggunakan sistem berbasis UTC.

Ternyata pada akhirnya itu adalah server. Mereka hanya membutuhkan patch terbaru yang diterapkan ( Windows Server 2003 ).


6

DateTimeZone::listAbbreviations()Output PHP

Metode PHP ini mengembalikan array asosiatif yang mengandung beberapa zona waktu 'utama' (seperti CEST), yang dengan sendirinya mengandung zona waktu 'geografis' yang lebih spesifik (seperti Eropa / Amsterdam).

Jika Anda menggunakan zona waktu ini dan informasi offset / DST mereka, sangat penting untuk menyadari hal-hal berikut:

Sepertinya semua konfigurasi offset / DST yang berbeda (termasuk konfigurasi historis) dari masing-masing zona waktu disertakan!

Misalnya, Eropa / Amsterdam dapat ditemukan enam kali dalam output fungsi ini. Dua kejadian (offset 1172/4772) adalah untuk waktu Amsterdam digunakan sampai 1937; dua (1200/4800) untuk waktu yang digunakan antara 1937 dan 1940; dan dua (3600/4800) untuk waktu yang digunakan sejak 1940.

Oleh karena itu, Anda tidak dapat mengandalkan informasi offset / DST yang dikembalikan oleh fungsi ini karena saat ini benar / sedang digunakan!

Jika Anda ingin mengetahui offset / DST saat ini dari zona waktu tertentu, Anda harus melakukan sesuatu seperti ini:

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>

5

Jika Anda kebetulan memelihara sistem basis data yang berjalan dengan DST aktif, periksa dengan cermat apakah mereka perlu dimatikan selama transisi di musim gugur. Mandy DBS (atau sistem lain juga) tidak suka melewati titik yang sama dalam waktu (lokal) dua kali, yang persis apa yang terjadi ketika Anda memutar kembali jam di musim gugur. SAP telah memecahkan ini dengan solusi (IMHO benar-benar rapi) - alih-alih memutar kembali jam, mereka hanya membiarkan jam internal berjalan pada setengah kecepatan biasa selama dua jam ...


4

Apakah Anda menggunakan .NET framework ? Jika demikian, izinkan saya memperkenalkan Anda dengan tipe DateTimeOffset , ditambahkan dengan .NET 3.5.

Struktur ini menampung a DateTimedan Offset ( TimeSpan), yang menentukan perbedaan antara DateTimeOffsettanggal dan waktu instance dan Waktu Universal Terkoordinasi (UTC).

  • The DateTimeOffset.Nowmetode statis akan mengembalikan DateTimeOffset instance yang terdiri dari arus waktu (lokal), dan lokal offset (sebagaimana didefinisikan dalam Info daerah sistem operasi).

  • The DateTimeOffset.UtcNowmetode statis akan mengembalikan DateTimeOffsetinstance yang terdiri dari waktu saat ini dalam UTC (seolah-olah Anda berada di Greenwich).

Jenis bermanfaat lainnya adalah kelas TimeZone dan TimeZoneInfo .


Ini bukan solusi untuk masalah yang disajikan.
caradrye

4

Bagi mereka yang berjuang dengan ini di . NET , lihat apakah menggunakan DateTimeOffsetdan / atau TimeZoneInfobernilai saat Anda.

Jika Anda ingin menggunakan zona waktu IANA / Olson , atau menemukan tipe bawaan tidak cukup untuk kebutuhan Anda, periksa Noda Time , yang menawarkan API tanggal dan waktu yang jauh lebih cerdas untuk .NET.


4

Aturan bisnis harus selalu bekerja pada waktu sipil (kecuali ada undang-undang yang mengatakan sebaliknya). Sadarilah bahwa waktu sipil berantakan, tetapi itulah yang digunakan orang-orang sehingga itu yang penting.

Secara internal, simpan cap waktu dalam sesuatu seperti waktu-sipil-detik-dari-zaman. The zaman tidak peduli terutama (saya mendukung zaman Unix ) tetapi melakukan hal-hal make lebih mudah daripada alternatif. Berpura-puralah bahwa detik kabisat tidak ada kecuali Anda melakukan sesuatu yang benar - benar membutuhkannya (misalnya, pelacakan satelit). Pemetaan antara cap waktu dan waktu yang ditampilkan adalah satu-satunya titik di mana aturan DST harus diterapkan; peraturan sering berubah (di tingkat global, beberapa kali setahun; menyalahkan politisi) sehingga Anda harus memastikan bahwa Anda tidak melakukan hard-code pemetaan. Basis data TZ Olson sangat berharga.


3
Masalahnya di sini adalah waktu sipil (alias waktu kalender) tidak mewakili satu momen waktu dengan tepat. Jika Anda mengambil pendekatan detik-dari-zaman, apakah Anda benar-benar akan memperhitungkan setiap momen yang dilewati atau diulangi untuk transisi penghematan siang hari? Mungkin tidak. Basis zaman hanya bekerja melawan UTC atau referensi waktu tertentu yang tetap dan instan lainnya.
Matt Johnson-Pint

@MattJohnson Karenanya bagian "aturan bisnis". Jika aturan mengatakan sesuatu terjadi pada jam 2:30 pagi (atau waktu yang mana saja), itu akan terjadi dua kali dalam satu hari setahun dan tidak pernah pada satu hari setahun. Itulah yang diharapkan pelanggan terjadi jika mereka tidak mengklarifikasi aturan.
user253751

Mempertahankan cap waktu internal di waktu sipil bisa sangat sulit. Menyimpannya sebagai detik sejak zaman masih lebih sulit, saya katakan benar-benar berbahaya. Saya yakin ada orang yang melakukannya, dan mungkin bisa membuatnya berfungsi dengan baik sebagian besar waktu jika Anda sangat berhati-hati, tetapi itu tidak dapat dianggap sebagai praktik terbaik atau rekomendasi umum.
Steve Summit

2

Hanya ingin menunjukkan dua hal yang tampaknya tidak akurat atau setidaknya membingungkan:

Selalu bertahan waktu sesuai dengan standar terpadu yang tidak terpengaruh oleh penghematan siang hari. GMT dan UTC telah disebutkan oleh orang yang berbeda, meskipun UTC tampaknya paling sering disebutkan.

Untuk (hampir) semua tujuan komputasi praktis, UTC sebenarnya adalah GMT. Kecuali jika Anda melihat cap waktu dengan pecahan detik, Anda berurusan dengan GMT yang membuat perbedaan ini berlebihan.

Masukkan offset waktu setempat apa adanya (termasuk offset DST) saat menyimpan stempel waktu.

Stempel waktu selalu diwakili dalam GMT dan karenanya tidak memiliki offset.


1
Offset waktu lokal akan memungkinkan Anda untuk membuat ulang "waktu dinding" asli acara. Jika Anda tidak menyimpan bidang tambahan ini, data ini hilang.
nogridbag

Ya, kecuali offset UTC dan GMT terbalik. Misalnya UTC-0700 sama dengan GMT + 0700. Sungguh, semua digital harus menggunakan UTC hari ini.
Matt Johnson-Pint

1
@ Mat: apakah Anda yakin tentang offset UTC dan GMT terbalik? di mana saya bisa membaca tentang itu?
Reto Höhener

Sebenarnya, saya pikir saya salah sebelumnya. GMT dan UTC tidak terbalik sendiri. Itu ada implementasi yang menunjukkan mereka terbalik, seperti database IANA / Olson / TZDB. Lihat di sini . Area lain yang Anda lihat offsetnya terbalik adalah pada fungsi getTimezoneOffset () javascript.
Matt Johnson-Pint

@MattJohnson: Itu adalah retasan dan harus dihapuskan.
Alix Axel

2

Inilah pengalaman saya: -

(Tidak memerlukan perpustakaan pihak ketiga)

  • Di sisi server, simpan waktu dalam format UTC sehingga semua nilai tanggal / waktu dalam database berada dalam satu standar terlepas dari lokasi pengguna, server, zona waktu atau DST.
  • Pada lapisan UI atau dalam email yang dikirim ke pengguna, Anda harus menunjukkan waktu sesuai dengan pengguna. Dalam hal ini, Anda perlu memiliki zona waktu offset pengguna sehingga Anda dapat menambahkan offset ini ke nilai UTC basis data Anda yang akan menghasilkan waktu lokal pengguna. Anda dapat mengambil zona waktu pengguna saat mendaftar atau Anda dapat secara otomatis mendeteksi mereka di platform web dan seluler. Untuk situs web, fungsi fungsi getTimezoneOffset () JavaScript adalah standar sejak versi 1.0 dan kompatibel dengan semua browser. (Ref: http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp )

Ini tidak berfungsi ketika Anda mempertimbangkan perubahan DST. getTimezoneOffsetmengembalikan offset untuk tanggal dan waktu Anda menyebutnya. Offset itu dapat berubah ketika zona waktu transisi masuk atau keluar dari waktu musim panas. Lihat "zona waktu! = Offset" di wiki tag zona waktu .
Matt Johnson-Pint

1
Jika Anda ingin menyimpan alarm seperti "lakukan sesuatu pada pukul 10:00", Anda tidak dapat menyimpannya di UTC, karena pergeseran DST. Anda harus menyimpannya relatif terhadap waktu setempat.
Alex

2

Video Tom Scott tentang zona waktu di YouTube pada saluran Computerphile juga memiliki deskripsi topik yang bagus dan menghibur. Contohnya termasuk:

  • Samoa (sebuah pulau di Samudra Pasifik) menggeser zona waktu ke depan 24 jam untuk mempermudah perdagangan dengan Australia dan Selandia Baru,
  • Tepi Barat , di mana 2 populasi orang mengikuti zona waktu yang berbeda,
  • Abad ke-18 berubah dari kalender Julian ke kalender Gregorian (yang terjadi pada abad ke-20 di Rusia).

1

Sebenarnya, kernel32.dll tidak mengekspor SystemTimeToTzSpecificLocation. Namun mengekspor dua berikut: SystemTimeToTzSpecificLocalTime dan TzSpecificLocalTimeToSystemTime ...


1

Jangan hanya mengandalkan konstruktor seperti

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

Mereka dapat melempar pengecualian ketika waktu tanggal tertentu tidak ada karena DST. Alih-alih, bangun metode Anda sendiri untuk membuat tanggal seperti itu. Di dalamnya, tangkap setiap pengecualian yang terjadi karena DST, dan sesuaikan waktu yang diperlukan dengan peralihan transisi. DST dapat terjadi pada tanggal dan waktu yang berbeda (bahkan di tengah malam untuk Brasil) menurut zona waktu.


1

Hanya satu contoh untuk membuktikan bahwa waktu penanganan adalah kekacauan besar yang dijelaskan, dan Anda tidak akan pernah bisa berpuas diri. Di beberapa tempat di halaman ini, lompatan detik telah diabaikan.

Beberapa tahun yang lalu, sistem operasi Android menggunakan satelit GPS untuk mendapatkan referensi waktu UTC, tetapi mengabaikan fakta bahwa satelit GPS tidak menggunakan leap-detik. Tidak ada yang memperhatikan sampai ada kebingungan di Malam Tahun Baru, ketika pengguna ponsel Apple dan pengguna ponsel Android melakukan hitung mundur sekitar 15 detik.

Saya pikir itu sudah diperbaiki, tetapi Anda tidak pernah tahu kapan 'detail kecil' ini akan kembali menghantui Anda.


1
  • Jangan pernah menyimpan waktu lokal tanpa offset UTC-nya (atau referensi ke zona waktu) —contoh bagaimana tidak melakukannya termasuk FAT32 dan struct tmdalam C.¹
  • Memahami bahwa zona waktu adalah kombinasi dari
    • satu set offset UTC (mis. +0100 di musim dingin, +0200 di musim panas)
    • aturan ketika peralihan terjadi (yang dapat berubah dari waktu: misalnya, pada 1990-an Uni Eropa menyelaraskan peralihan tersebut pada hari Minggu terakhir di bulan Maret dan Oktober, pukul 02:00 waktu standar / 03:00 DST; sebelumnya ini berbeda antar negara anggota).

¹ Beberapa implementasi struct tmdo store of offset UTC, tetapi ini belum membuatnya menjadi standar.


-4

Dalam berurusan dengan basis data (khususnya MySQL , tetapi ini berlaku untuk sebagian besar basis data), saya merasa kesulitan untuk menyimpan UTC.

  • Database biasanya berfungsi dengan datetime server secara default (yaitu, CURRENT_TIMESTAMP).
  • Anda mungkin tidak dapat mengubah zona waktu server.
  • Bahkan jika Anda dapat mengubah zona waktu, Anda mungkin memiliki kode pihak ketiga yang mengharapkan zona waktu server menjadi lokal.

Saya merasa lebih mudah untuk hanya menyimpan datetime server dalam database, lalu biarkan database mengkonversi datetime yang disimpan kembali ke UTC (yaitu, UNIX_TIMESTAMP ()) dalam pernyataan SQL. Setelah itu Anda dapat menggunakan datetime sebagai UTC dalam kode Anda.

Jika Anda memiliki kontrol 100% atas server dan semua kode, mungkin lebih baik mengubah zona waktu server ke UTC.


Waktu lokal (waktu server) dapat menjadi ambigu selama transisi tabungan siang hari gaya "mundur". Tidak dapat diandalkan untuk digunakan seperti yang Anda gambarkan. Mungkin ada lebih dari satu waktu UTC yang dapat mewakili waktu lokal server.
Matt Johnson-Pint

Waktu lokal sangat baik jika server terletak di zona waktu yang waras, yaitu yang tidak melakukan DST.
sayap
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.