Server pengembangan lokal saya di Timur Tengah, tetapi server produksi saya di Inggris.
Saya perlu menunjukkan tanggal kepada pengguna di zona waktu mereka. Misalnya, jika pengguna di Arab Saudi maka saya harus menunjukkan waktu sesuai dengan format Arab Saudi.
Haruskah saya membuat tabel database baru yang disebut TimeZone dan menghemat waktu dalam UTC?
sql-server
sql-server-2008
timezone
pengguna960567
sumber
sumber
Jawaban:
Sayangnya, tidak ada perbaikan cepat untuk ini. Internasionalisasi suatu aplikasi harus menjadi bagian dari diskusi desain pertama, karena hal itu benar-benar menjadi inti dari banyak bidang yang berbeda, termasuk perbandingan tanggal / waktu dan format keluaran.
Ngomong-ngomong, untuk melacak Doing It Right, penting untuk menyimpan informasi zona waktu bersama waktu . Dengan kata lain, menyadari bahwa tanggal / waktu tidak
20130407 14:50
ada artinya tanpa (a) termasuk offset UTC saat itu zona waktu (catatan 1) , atau (b) memastikan bahwa semua logika yang memasukkan nilai-nilai ini pertama kali dikonversi ke offset tetap tertentu ( kemungkinan besar 0). Tanpa salah satu dari hal-hal itu, dua nilai waktu yang diberikan tidak dapat dibandingkan, dan datanya rusak . (Metode terakhir bermain dengan api (catatan 2) , omong-omong; jangan lakukan itu.)Di SQL Server 2008+, Anda dapat menyimpan offset dengan waktu secara langsung dengan menggunakan
datetimeoffset
tipe data. (Untuk kelengkapan, pada 2005 dan sebelumnya, saya akan menambahkan kolom kedua untuk menyimpan nilai offset UTC saat itu (dalam menit).)Ini memudahkan aplikasi jenis desktop, karena platform ini biasanya memiliki mekanisme untuk secara otomatis mengkonversi tanggal / waktu + zona waktu ke waktu lokal dan kemudian memformat untuk output, semua berdasarkan pada pengaturan regional pengguna.
Untuk web, yang merupakan arsitektur yang terputus secara inheren, bahkan dengan data back-end yang diatur dengan benar, itu lebih kompleks karena Anda memerlukan informasi tentang klien untuk dapat melakukan konversi dan / atau pemformatan. Ini biasanya dilakukan melalui pengaturan preferensi pengguna (aplikasi mengkonversi / memformat hal-hal sebelum output), atau hanya menampilkan hal-hal dengan format tetap yang sama dan offset zona waktu untuk semua orang (yang dilakukan oleh platform Stack Exchange saat ini).
Anda dapat melihat bagaimana jika data back-end tidak diatur dengan benar, sangat cepat itu akan menjadi rumit dan meretas. Saya tidak akan merekomendasikan salah satu dari jalan-jalan tersebut karena Anda hanya akan berakhir dengan lebih banyak masalah di telepon.
Catatan 1:
Offset UTC zona waktu tidak tetap: pertimbangkan penghematan siang hari di mana offset UTC zona bervariasi dengan plus atau minus satu jam. Juga tanggal penghematan siang hari zona bervariasi secara teratur. Jadi menggunakan
datetimeoffset
(atau gabungan darilocal time
danUTC offset at that time
) menghasilkan pemulihan informasi maksimum.Catatan 2:
Ini tentang mengendalikan input data. Meskipun tidak ada cara yang mudah untuk memvalidasi nilai yang masuk, lebih baik untuk menegakkan standar sederhana yang tidak melibatkan perhitungan. Jika API publik mengharapkan tipe data yang menyertakan offset, persyaratan itu akan jelas bagi pemanggil.
Jika bukan itu masalahnya, penelepon harus bergantung pada dokumentasi (jika mereka membacanya), atau perhitungannya dilakukan secara tidak benar, dll. Ada lebih sedikit mode kegagalan / bug saat memerlukan offset, khususnya untuk sistem terdistribusi ( atau bahkan hanya web / database pada server terpisah seperti yang terjadi di sini).
Menyimpan offset tetap membunuh dua burung dengan satu batu; dan bahkan jika itu tidak diperlukan sekarang , itu membuat kemungkinan tersedia nanti jika perlu. Benar itu membutuhkan lebih banyak penyimpanan, tapi saya pikir itu layak trade-off karena data hilang jika tidak pernah direkam sejak awal.
sumber
datetimeoffset
berarti "ini adalah waktu setempat pengguna / komputer ketika hal itu terjadi" - kita tidak perlu tahu apakah DST berlaku atau tidak, karena offset UTC yang diberikan selalu ada (tertanam dalamdatetimeoffset
nilai).Saya telah mengembangkan solusi komprehensif untuk konversi zona waktu di SQL Server. Lihat Dukungan Zona Waktu SQL Server di GitHub .
Itu benar menangani konversi antara zona waktu, dan ke dan dari UTC, termasuk waktu musim panas.
Ini serupa dalam konsep dengan solusi "T-SQL Toolbox" yang dijelaskan dalam jawaban iklan, tetapi menggunakan zona waktu IANA / Olson / TZDB yang lebih umum daripada Microsoft, dan itu mencakup utilitas untuk menjaga data tetap dipertahankan sebagai rilis baru dari TZDB keluar.
Contoh penggunaan (untuk menjawab OP):
Lihat readme di GitHub untuk API tambahan dan penjelasan terperinci.
Juga, perhatikan bahwa karena ini adalah solusi berbasis UDF, itu tidak dirancang dengan kinerja sebagai tujuan utama. Masih akan lebih baik jika fungsi ini dibangun ke SQL Server, mirip dengan bagaimana
CONVERT_TZ
fungsi itu ada di Oracle dan MySQL.sumber
SQL Server membuat modifikasi pada 2005 dan seterusnya di mana zona waktu internal disimpan dalam UTC. Ini sebagian besar disebabkan oleh replikasi-geo dan proyektor HA yang melibatkan pengiriman log, dan menghemat waktu pengiriman log di zona waktu yang berbeda membuat metode lama tidak dapat mengembalikannya.
Dengan demikian, menyimpan segala sesuatu secara internal dalam waktu UTC memungkinkan SQL Server berfungsi dengan baik secara global. Ini adalah salah satu alasan mengapa penghematan siang hari adalah jenis yang menyusahkan untuk ditangani di Windows, karena produk MS lainnya seperti Outlook juga menyimpan tanggal / waktu secara internal sebagai UTC dan membuat offset yang perlu ditambal.
Saya bekerja di sebuah perusahaan di mana kami memiliki ribuan server (bukan MS SQL Server, tetapi semua jenis server) tersebar di seluruh dunia, dan jika kami tidak secara spesifik memaksa semuanya untuk pergi dengan UTC, kami semua akan menjadi gila sangat cepat.
sumber
Saya telah mengembangkan dan menerbitkan proyek "T-SQL Toolbox" pada codeplex untuk membantu siapa saja yang berjuang dengan penanganan waktu dan zona waktu di SQL Server. Ini open source dan sepenuhnya gratis untuk digunakan.
Ini menawarkan UDFs konversi datetime mudah menggunakan T-SQL biasa dengan tabel konfigurasi tambahan di luar kotak.
Dalam contoh Anda, Anda dapat menggunakan sampel berikut:
Ini akan mengembalikan nilai datetime yang dikonversi untuk pengguna Anda.
Daftar semua zona waktu yang didukung dapat ditemukan dalam tabel "DateTimeUtil.Timezone" juga disediakan dalam database T-SQL Toolbox.
sumber
Saya mungkin kehilangan sesuatu yang jelas, tetapi jika semua yang Anda ingin lakukan adalah menampilkan tanggal menggunakan zona waktu pengguna dan format bahasa, cara paling sederhana adalah dengan selalu menyimpan tanggal dalam UTC dalam database dan membiarkan aplikasi klien mengkonversi dari UTC ke lokal zona waktu dan gunakan pengaturan regional pengguna untuk memformat tanggal sesuai.
sumber