Ada jawaban yang panjang dan cukup menjelaskan tentang perbedaan di antara keduanya
TIMESTAMP WITH TIME ZONE
-vs-TIMESTAMP WITHOUT TIME ZONE
tersedia di pos SO ini . Yang ingin saya ketahui adalah: apakah ada kasus penggunaan yang valid untuk benar-benar menggunakan TIMESTAMP WITHOUT TIME ZONE
atau harus dianggap sebagai anti-pola.
postgresql
Marcus Junius Brutus
sumber
sumber
Jawaban:
Hal ini dinyatakan dalam banyak tempat, tapi saya pikir itu layak disebut selalu ketika kita membandingkan
timestamp with time zone
dengantimestamp without time zone
jenis: yangtimestamp WITH time zone
tidak menyimpan zona waktu informasi bersama dengan stempel waktu . Apa yang dilakukannya adalah menyimpan setiap data dalam zona waktu UTC, sebagaimana dinyatakan dalam dokumen :Itu dianggap valid untuk digunakan
timestamp WITHOUT time zone
dalam situasi di mana (1) semuanya berada di zona waktu yang sama atau (2) lapisan aplikasi menangani zona waktu dan hanya menyimpan segala sesuatu di zona waktu tertentu (biasanya UTC). Tetapi itu juga dianggap sebagai anti-pola, sederhana karena solusi yang tepat untuk (1) adalah mengkonfigurasi pengaturan TimeZone ke zona waktu yang diberikan untuk sistem dan (2) sudah dipecahkan, karena PostgreSQL sudah menyimpan semuanya di zona waktu yang sama (UTC).Sekarang, dengan kedua down, saya bisa datang hanya dengan satu alasan untuk digunakan
timestamp WITHOUT time zone
. Saat itulah Anda ingin menyimpan acara di masa depan dan semacam peringatan harus dipicu ketika kita sampai pada waktu itu. Itu bisa baik untuktimestamp WITH time zone
jika, dan hanya jika, aturan yang ditetapkan oleh undang-undang kawasan tentang zona waktu tidak pernah berubah. Aturan paling umum yang berubah adalah tentang adopsi atau tidak, Day Light saving Time (DST).Misalnya, bayangkan Anda berada di, katakanlah,
2013-06-15
(belum dalam DST) jadwalkan beberapa acara terjadi2013-01-15 10:00
(yang sudah ada di DST), dan di2013-06-15
wilayah Anda telah ditunjuk untuk mengadopsi DST; tetapi, beberapa saat setelah itu, pemerintah mengubah aturan dan mengatakan wilayah Anda tidak akan lagi menggunakan DST, dan tiba-tiba waktu terjadwal Anda menjadi2013-01-15 11:00
(alih-alih10:00
), bahwa jika Anda menggunakantimestamp WITH time zone
, dan menjaga agar konfigurasi TZ Anda tetap terbarui. Tentu saja Anda juga dapat memperhatikan bahwa ada kemungkinan untuk menangani kasus-kasus seperti itu juga dengan zona waktu, jika Anda melacak perubahan aturan di wilayah / zona waktu yang Anda minati, dan memperbarui catatan yang terpengaruh.Patut disebutkan bahwa beberapa kawasan sering mengubah aturan ini (seperti di Brasil, beberapa negara bagian - bukan seluruh negara - sering berubah), tetapi dalam kebanyakan kasus itu mengubahnya lebih awal, sehingga pengguna Anda akan terpengaruh hanya oleh acara yang dijadwalkan sangat jauh dari waktu saat ini.
Dengan semua itu, saya hanya punya satu saran lagi. Jika Anda memiliki pengguna, log, atau apa pun di zona waktu yang berbeda, simpan zona waktu tempat mereka berasal dari suatu tempat dan pilih dan gunakan
timestamp with time zone
. Dengan cara itu Anda dapat (1) lintas peristiwa yang terjadi lebih dekat satu sama lain untuk sumber yang berbeda (terlepas dari zona waktu mereka) dan (2) menunjukkan waktu asli (waktu jam) peristiwa tersebut terjadi.sumber
Iya nih. Ada kasus penggunaan untuk
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
, bukanWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
nilai bukan titik pada timeline, bukan momen aktual. Mereka mewakili ide kasar tentang momen potensial , kemungkinan poin pada timeline sepanjang kisaran sekitar 26-27 jam (rentang zona waktu di seluruh dunia). Mereka tidak memiliki arti yang nyata sampai Anda menerapkan zona waktu atau mengimbangi dari UTC .Mis: Natal
Misalnya, Anda perlu mencatat awal liburan / hari suci.
Untuk mencatat fakta bahwa Natal dimulai setelah tengah malam pada 25 Desember tahun ini, kita perlu mengatakan
2016-12-25 00:00:00
tanpa zona waktu. Di awal hari Santa, dia mengunjungi Auckland NZ tepat setelah tengah malam, karena itu adalah salah satu malam paling awal di dunia. Kemudian dia bekerja ke arah barat, saat tengah malam berikutnya, segera mencapai Filipina. Kemudian rusa itu bergerak ke arah barat, mencapai India pada tengah malam yang terjadi beberapa jam setelah tengah malam Auckland itu. Jauh kemudian masih tengah malam di Paris FR, dan masih kemudian tengah malam di Montreal CA. Semua kunjungan Santa ini terjadi pada saat-saat yang berbeda adalah waktu , namun semua terjadi tak lama setelah tengah malam, per tengah malam masing-masing daerah.Jadi merekam
2016-12-25 00:00:00
tanpa zona waktu sebagai awal Natal adalah informatif dan sah, tetapi hanya samar-samar. Sampai Anda mengatakan "Natal di Auckland" atau "Natal di Montréal", kami tidak memiliki momen khusus dalam waktu. Jika Anda merekam momen aktual setiap kali giring mendarat, Anda akan menggunakanTIMESTAMP WITH TIME ZONE
daripadaWITHOUT
tipe.Mirip dengan Natal adalah Malam Tahun Baru. Ketika Times Square Ball jatuh di New York , orang-orang di Seattle masih mendinginkan sampanye mereka dan menyiapkan tanduk pesta mereka . Namun kami akan merekam ide momen Tahun Baru seperti
2017-01-01 00:00:00
pada aTIMESTAMP WITHOUT TIME ZONE
. Sebaliknya, jika kita ingin merekam ketika bola jatuh di New York, atau ketika orang-orang di Seattle meniup terompet mereka, kita lebih suka menggunakanTIMESTAMP WITH TIME ZONE
(tidakWITHOUT
) untuk merekam momen aktual itu, masing-masing berjarak tiga jam dari yang lain.Mis: Pergeseran Pabrik
Contoh lain mungkin merekam kebijakan yang melibatkan waktu jam dinding di berbagai lokasi. Katakanlah kita memiliki pabrik di Detroit, Düsseldorf, dan Delhi. Jika kita mengatakan bahwa di ketiga pabrik, shift pertama dimulai pada jam 6 pagi dengan istirahat makan siang pada jam 11:30, yang dapat dicatat sebagai a
TIMESTAMP WITHOUT TIME ZONE
. Sekali lagi, informasi ini berguna secara samar-samar tetapi tidak menunjukkan saat tertentu dalam waktu sampai kita menerapkan zona waktu. Hari baru baru sadar di timur. Jadi pabrik Delhi akan menjadi yang pertama dibuka pada pukul 6 pagi. Beberapa jam kemudian, pabrik Düsseldorf mulai bekerja pukul 6 pagi. Tetapi pabrik Detroit tidak akan benar-benar terbuka sampai enam jam kemudian, ketika 6:00 terjadi.Bandingkan ide ini (tentang kapan shift pabrik umumnya dimulai) dengan fakta historis kapan setiap pekerja pabrik jam-in untuk memulai shift mereka pada hari tertentu. Clock-in adalah momen nyata, titik aktual di timeline. Jadi kami akan mencatatnya dalam kolom tipe
TIMESTAMP WITH TIME ZONE
bukanWITHOUT
tipe.Jadi, ya, ada kasus penggunaan yang sah untuk
TIMESTAMP WITHOUT TIME ZONE
. Tetapi dalam pengalaman saya dengan aplikasi bisnis, mereka relatif jarang. Dalam bisnis, kita cenderung peduli pada saat-saat aktual: kapan faktur benar-benar tiba, kapan tepatnya kontrak itu berlaku, pada saat apa transaksi bank itu dilaksanakan. Jadi dalam situasi umum seperti itu, kami menginginkanTIMESTAMP WITH TIME ZONE
tipenya.Untuk diskusi lebih lanjut, lihat Jawaban saya untuk Pertanyaan serupa, Haruskah saya menyimpan stempel waktu UTC atau waktu lokal untuk shift
Postgres
Perhatikan bahwa Postgres khusus tidak pernah menyimpan informasi zona waktu yang ditentukan saat memasukkan stempel waktu.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
sebagaiTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
Standar SQL hampir tidak menyentuh pada masalah tipe dan perilaku data tanggal-waktu. Sehingga database bervariasi secara luas dalam penanganan tanggal-waktu.
sumber
21:00
)Saya ingin menambahkan pandangan lain untuk ini, yang bertentangan dengan banyak dari apa yang telah ditulis dalam jawaban lain. Menurut pendapat saya
timestamp with time zone
memiliki sangat sedikit kasus penggunaan yang valid, dantimestamp without time zone
secara umum lebih disukai.Pertama, Anda harus memahami pola "UTC di mana-mana", yang umumnya direkomendasikan untuk semua aplikasi yang tidak memiliki persyaratan khusus. Ini berarti bahwa aplikasi Anda harus mewakili semua cap waktu di UTC, di mana saja, sepanjang waktu. Tentu saja, Anda akan menunjukkan tanggal / waktu setempat kepada pengguna, tetapi idenya adalah untuk mengonversikannya di tepi program Anda, saat menampilkan tampilan. Ini adalah tempat yang tepat untuk menggabungkan timestamp UTC (yang mungkin Anda muat dari database) dan zona waktu pengguna (yang mungkin berasal dari browser) ke cap waktu lokal.
Jika Anda mengikuti pola ini, maka
timestamp with time zone
merupakan pola anti. Semua jenis ini dilakukan adalah membuat PostgreSQL melakukan konversi zona waktu saat membaca dan menulis stempel waktu, berdasarkanTimeZone
variabel sesi PostgreSQL Anda . Alih-alih berurusan dengan zona waktu di bagian paling tepi dari aplikasi Anda, Anda telah memperkenalkannya ke dalam inti, ke dalam komunikasi dengan database Anda. Anda harus berhati-hati untuk selaluTimeZone
mengonfigurasi PostgreSQL dengan benar setiap saat, menambahkan titik kegagalan dan kebingungan yang tidak perlu.Dan untuk apa? Jika Anda mengikuti pola UTC di mana-mana, aplikasi Anda hanya memiliki stempel waktu UTC; jadi mengapa meminta database Anda untuk melakukan konversi zona waktu? Anda bisa menyimpannya dalam
timestamp without time zone
kolom, dan memperlakukannya seperti itu selalu UTC. Tidak ada konversi, tidak ada zona waktu, tidak ada komplikasi.sumber
Instance
di NodaTime / JodaTime). Anda pada dasarnya menggambarkan situasi di mana "UTC di mana-mana" hampir diikuti, atau agak diikuti ...timestamptz
. Inti dari tipe ini adalah untuk melakukan konversi zona waktu sebagai nilai yang dibaca dan ditulis ke PostgreSQL (secara internal dalam database, stempel waktu selalu disimpan sebagai UTC). Selalu mengatur zona waktu sesi ke UTC secara efektif menonaktifkan konversi itu, jadi mengapa menggunakantimestamptz
sama sekali? Dengan kata lain, jika nilai-nilai dalam database adalah UTC, dan nilai-nilai yang masuk dan keluar dari database selalu UTC, lalu mengapa memiliki kesadaran zona waktu sama sekali dalam database Anda?The
date
timestamp juga tidak termasuk zona waktu, namun banyak orang menggunakannya.Tentu saja, itu sendiri bukanlah jawaban.
Ini berlaku untuk menggunakan
timestamp
dandate
untuk cap waktu dan tanggal yang selalu dalam zona waktu yang sama, atau disimpan relatif terhadap beberapa zona waktu yang diketahui.Jika zona waktu selalu sama atau implisit, maka lebih baik untuk memindahkannya daripada tidak menyimpannya (informasi yang berlebihan).
Stempel waktu juga dapat digunakan untuk menyimpan informasi teknis seperti yang digunakan dalam log aplikasi atau untuk pengukuran kinerja. Dalam hal ini, zona waktu juga tidak penting.
Sebaliknya, jika Anda merancang atau bekerja pada sistem terdistribusi atau di sistem mana pun di mana bagian-bagian sistem akan didistribusikan di berbagai zona waktu, itu mungkin dianggap sebagai anti-pola untuk tidak menggunakan
timestamp with timezone
, meskipun beberapa sistem mungkin dirancang untuk dijalankan dalam satu zona waktu, mis. UTC. Dalam hal ini logika zona waktu mungkin didorong ke dalam lapisan aplikasi - tapi saya akan menganggap ini sebagai anti-pola, ya.sumber
timestamp without timezone
, tetapi apakah pernah membeli saya apa pun? Kalau tidak, mengapa saya harus repot-repot jikatimestamp with timezone data
jenisnya selalu sama atau lebih sesuai?timestamp without timezone
akan lebih cepat juga, tetapi itu mungkin hanya penting jika Anda memproses miliaran baris ...timestamp
dantimestamptz
keduanya disimpan dengan cara yang sama. Tidak ada informasi zona waktu yang disimpan dalam atimestamptz
, tetapi sebaliknya dikonversi ke UTC untuk penyimpanan. Menurut saya, selalu gunakantimestamptz
ketika cap waktu yang dimaksud menunjukkan waktu absolut . Itu semuatimestamptz
artinya. Saya sudah menulis tentang ini di sini .Tampaknya menggoda untuk menyimpan dan memproses tanggal / waktu dalam waktu lokal jika aplikasi Anda terbatas pada zona waktu tunggal tetapi saya yakin ini adalah kesalahan.
Ketika beralih dari waktu penghematan siang hari ke waktu standar satu jam di waktu lokal diulangi (dengan asumsi perbedaannya adalah satu jam). Tempat saya tinggal ini biasanya terjadi sekitar jam 2 pagi sehingga waktu setempat berjalan 01:58, 01:59, 01:00 dan hanya naik menjadi 02:00 pada akhir jam yang diulang.
Jika Anda mencoba untuk memesan acara berdasarkan waktu menggunakan waktu setempat, itu berarti acara dari dua jam yang terpisah berbaur bersama dan tidak muncul dalam urutan di mana mereka benar-benar terjadi.
Sebagai perbandingan, UTC tidak memiliki masalah ini dan memesannya dengan bersih. Jadi, bahkan ketika bekerja dengan hanya satu zona waktu, Anda ingin DB menyimpan dan memproses waktu dalam UTC dan mengonversikan ke / dari waktu lokal untuk input / tampilan. Ini adalah perilaku TIMESTAMP DENGAN ZONA WAKTU.
sumber