Jawaban yang Diperbarui
Saya telah menulis utilitas yang saya bicarakan dalam jawaban asli, yang dapat Anda temukan di sini .
Juga, pada SQL Server 2016 (dan Azure SQL Database), Anda sekarang dapat menggunakan AT TIME ZONE
kata kunci untuk mengkonversi antar zona waktu.
Jawaban Asli
Sayangnya, tidak ada solusi yang bagus untuk bekerja dengan zona waktu di SQL Server.
Saya menyelidiki secara mendalam masalah yang Anda tautkan, bersama dengan yang ini
juga. Tidak ada fungsi zona waktu bawaan, dan penggunaan TimeZoneInfo
di SQLCLR mengharuskan Majelis untuk didaftarkan sebagai "tidak aman". Ini biasanya tidak diinginkan.
Saya juga menyelidiki menggunakan Noda Time dari SQLCLR. Anda dapat membacanya di masalah ini . Itu juga harus didaftarkan sebagai "tidak aman" karena cara item tertentu di-cache secara internal.
Pada akhirnya, dengan salah satu item, masalahnya adalah tidak ada cara untuk men-cache apa pun di SQLCLR. Anda tidak dapat menggunakan variabel statis dengan cara yang aman untuk utas, dan Anda tidak dapat melakukan sinkronisasi utas atau menggunakan kelas seperti ConcurrentDictionary
. SQL ingin memiliki kontrol penuh dari model threading dari Majelis. Hanya kode gaya sekali pakai dan buang satu utas yang berfungsi di rakitan "aman". Saya menggali jauh ke dalam pertanyaan ini:Caching multithreaded di SQL CLR
Semoga, akhirnya menjadi build dari Noda Time yang akan bekerja di SQLCLR, tetapi ini akan menjadi build khusus yang tidak melakukan caching. Jadi tidak akan bekerja secepat itu, tetapi akan menyelesaikan pekerjaan sambil tetap aman.
TimeZoneInfo
tidak mungkin berubah. Jadi kecuali tim SQL Server pernah membawa fungsi zona waktu langsung ke SQL Server dengan benar (seperti yang dilakukan Oracle dan Postgres), maka Anda hanya punya beberapa opsi:
-
Jangan mencoba konversi zona waktu di lapisan data. Bekerja dengan
datetime
ataudatetime2
nilai dalam UTC, atau gunakandatetimeoffset
nilai dengan offset apa pun. Tetapi lakukan semua konversi antar zona waktu di lapisan aplikasi. Ini adalah rekomendasi terbaik saya untuk saat ini. -
Salin semua data untuk zona waktu ke dalam tabel SQL yang sebenarnya, dan tulis fungsi yang bekerja dengan data tersebut. Ini bukan ide terbaik, karena data sering berubah sehingga pemeliharaan tabel bisa menjadi tantangan. Juga mendapatkan fungsi yang akurat, termasuk semua aturan perubahan waktu musim panas, dapat menjadi tantangan. Saya tidak mengetahui proyek apa pun yang memiliki paket yang bagus dan rapi ini, tetapi jika ada - beri tahu saya di komentar.
-
Aktifkan
xp_regread
dan bekerja dengan data zona waktu langsung dari kunci registri windows. Pembaruan akan dilakukan untuk Anda, tetapi Anda masih memiliki tantangan yang sama dalam menulis fungsi-fungsi ini. Dan mengaktifkan pembacaan registri mungkin memiliki risiko keamanan yang sama besarnya dengan mengaktifkan rakitan CLR yang tidak aman.
Ide lain yang saya pertimbangkan adalah menulis IANA/Olson TZDB parser dan fungsi khusus untuk SQL Server. Ini akan mirip dengan opsi 2 di atas, tetapi dilakukan dengan cara yang dapat dipelihara, dan dengan data standar IANA alih-alih zona waktu Windows. Mungkin saya akan mencapai ini suatu hari nanti, atau mungkin seseorang akan mengalahkan saya untuk itu. Sekali lagi, saya tidak mengetahui adanya proyek saat ini yang melakukan ini, tetapi jika seseorang mengetahuinya, beri tahu saya di komentar. (selesai - lihat pembaruan di atas )
Mengenai SWITCHOFFSET
- itu hanya berfungsi jika Anda sudah mengetahui target offset. Itu setengah dari pertempuran, dan mungkin mengapa Microsoft masih menandai datetimeoffset
karena tidak "mewaspadai musim panas" di dokumen
.