Artikel ini membahas perbedaan utama antara waktu-tanggal dan datetime2 tipe data di SQL Server.
Jika Anda tidak yakin yang mana yang akan digunakan, gunakan datetime2 (lihat kelebihannya di bawah).
Berikut tabel yang menjelaskan perbedaan utama antara kedua jenis ini.
Fitur | datetime | datetime2 |
---|---|---|
Sesuai dengan SQL (ANSI &ISO 8601) | Tidak | Ya |
Rentang Tanggal | 1753-01-01 sampai 9999-12-31 | 0001-01-01 hingga 9999-12-31 |
Rentang Waktu | 00:00:00 sampai 23:59:59,997 | 00:00:00 sampai 23:59:59.9999999 |
Panjang Karakter | Minimum 19 posisi maksimal 23 | Minimum 19 posisi maksimum 27 |
Ukuran Penyimpanan | 8 byte | 6 hingga 8 byte, tergantung pada presisi* * Ditambah 1 byte untuk menyimpan presisi |
Akurasi | Dibulatkan menjadi kelipatan .000, .003, atau .007 detik | 100 nanodetik |
Presisi pecahan detik yang ditentukan pengguna | Tidak | Ya |
Offset Zona Waktu | Tidak ada | Tidak ada |
Awas dan pelestarian zona waktu | Tidak | Tidak |
Mengingat musim panas | Tidak | Tidak |
Keuntungan dari 'datetime2'
Seperti yang terlihat pada tabel di atas, datetime2 type memiliki banyak keunggulan dibandingkan datetime , termasuk:
- rentang tanggal yang lebih besar
- presisi pecahan default yang lebih besar
- presisi yang ditentukan pengguna opsional
- akurasi lebih tinggi, bahkan saat menggunakan jumlah tempat desimal yang sama dengan datetime (yaitu 3)
- ukuran penyimpanan lebih kecil saat menggunakan jumlah desimal yang sama dengan waktu-tanggal , namun dengan akurasi yang lebih tinggi*
- opsi untuk menggunakan penyimpanan 2 byte lebih sedikit daripada datetime (walaupun dengan presisi yang lebih rendah)*
- sejajar dengan standar SQL (ANSI &ISO 8601)
* Dalam beberapa kasus datetime2 value menggunakan byte ekstra untuk menyimpan presisi, yang akan menghasilkan ukuran penyimpanan yang sama dengan datetime saat menggunakan jumlah tempat desimal yang sama. Baca terus untuk mengetahui lebih lanjut tentang ini.
Haruskah saya menggunakan 'datetime' atau 'datetime2'?
Microsoft merekomendasikan datetime2 melebihi waktu kencan untuk pekerjaan baru (dan untuk alasan yang sama seperti yang disebutkan di atas).
Oleh karena itu, Anda harus menggunakan datetime2 , kecuali Anda memiliki alasan khusus untuk tidak melakukannya (seperti bekerja dengan sistem lama).
Contoh 1 – Perbandingan Dasar
Berikut adalah contoh singkat untuk menunjukkan perbedaan mendasar antara datetime dan datetime2 .
DECLARE @thedatetime2 datetime2(7), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5555555'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Hasil:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.5555555 | 2025-05-21 10:15:30.557 | +-----------------------------+-------------------------+
Di sini, saya menetapkan waktu tanggal variabel dengan nilai yang sama dengan datetime2 variabel. Hal ini menyebabkan nilai dikonversi ke datetime dan kemudian kita dapat menggunakan SELECT
pernyataan untuk melihat hasilnya.
Dalam hal ini, datetime2 variabel menggunakan skala 7, yang berarti 7 tempat desimal. waktu kencan sebaliknya, hanya menggunakan 3 tempat desimal, dan digit pecahan terakhirnya dibulatkan ke atas (karena tipe data ini membulatkan pecahan detik menjadi kelipatan .000, .003, atau .007 detik).
Contoh 2 – Menggunakan 3 Tempat Desimal
Jika saya mengurangi datetime2 skala ke 3 (untuk mencocokkan tanggal waktu ), inilah yang terjadi.
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5555555'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Hasil:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.556 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
Jadi datetime2 nilai juga dibulatkan dalam kasus ini. Namun, hanya dibulatkan menjadi 556 – tidak melompat ke 557 seperti waktu kencan nilai tidak.
Tentu saja, satu-satunya alasan datetime2 nilai dibulatkan ke atas karena angka berikut adalah 5 atau lebih tinggi. Jika kita mengurangi angka berikut, tidak ada pembulatan yang dilakukan:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Hasil:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
Namun, waktu tanggal nilainya terus dibulatkan.
Contoh 3 – Menetapkan Nilai dari Literal String
Pada contoh sebelumnya, tanggal waktu nilai ditetapkan dengan menyetelnya ke nilai yang sama dengan datetime2 nilai. Ketika kami melakukannya, SQL Server melakukan konversi implisit agar data "sesuai" dengan tipe data baru.
Namun, jika kami mencoba menetapkan literal string yang sama ke datetime variabel yang kami tetapkan ke datetime2 , kami mendapatkan kesalahan:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = '2025-05-21 10:15:30.5554444'; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Hasil:
Msg 241, Level 16, State 1, Line 5 Conversion failed when converting date and/or time from character string.
Ini karena waktu kencan hanya menerima literal string yang memiliki 3 detik pecahan atau kurang.
Jadi untuk mengatasi masalah ini, kita perlu mengurangi bagian pecahan menjadi hanya 3 (atau kurang) tempat desimal.
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = '2025-05-21 10:15:30.555'; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Hasil:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
datetime2 type tidak memiliki batasan ini, bahkan saat menggunakan skala 3.
Contoh 4 – Ukuran Penyimpanan
waktu kencan tipe data memiliki ukuran penyimpanan tetap 8 byte.
datetime2 di sisi lain, dapat berupa 6, 7, atau 8 byte, tergantung pada presisinya.
Saat menggunakan 3 tempat desimal, datetime2 hanya menggunakan 7 byte, yang berarti menggunakan lebih sedikit ruang penyimpanan daripada datetime (dengan lebih akurat).
Namun, Microsoft menyatakan bahwa datetime2 type juga menggunakan 1 byte tambahan untuk menyimpan presisinya. Jadi dalam hal ini, itu akan menggunakan 8 byte. Oleh karena itu, kita dapat merevisi pernyataan sebelumnya dengan mengatakan bahwa pernyataan tersebut menggunakan 7, 8, atau 9 byte.
Namun, ini mungkin tergantung pada apakah kita menyimpannya dalam tabel atau variabel, dan apakah kita mengonversinya menjadi konstanta biner atau tidak.
Inilah yang terjadi jika kita menggunakan DATALENGTH()
fungsi untuk mengembalikan jumlah byte yang digunakan untuk setiap nilai kita:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT DATALENGTH(@thedatetime2) AS 'datetime2', DATALENGTH(@thedatetime) AS 'datetime';
Hasil
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 7 | 8 | +-------------+------------+
Tetapi jika kita mengonversinya menjadi varbinary , kita mendapatkan yang berikut:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT DATALENGTH(CONVERT(VARBINARY(16),@thedatetime2)) AS 'datetime2', DATALENGTH(CONVERT(VARBINARY(16),@thedatetime)) AS 'datetime';
Hasil
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 8 | 8 | +-------------+------------+
Jadi datetime2 menggunakan byte ekstra saat dikonversi ke varbinary , sehingga membawanya ke ukuran penyimpanan yang sama dengan datetime .
Namun, contoh berikut menunjukkan bahwa ketika data disimpan dalam kolom database, kita mendapatkan panjang 7 byte untuk datetime2 dan 8 byte untuk datetime .
Saat menyimpan datetime2 nilai dalam database, definisi kolom mencakup presisi. Dalam hal ini nilai di setiap baris tidak memerlukan byte tambahan untuk menyimpan presisi, dan kita dapat mengatakan bahwa datetime2 menggunakan lebih sedikit ruang penyimpanan daripada datetime saat menggunakan jumlah detik pecahan yang sama.
Contoh 5 – Ukuran Penyimpanan untuk Data Tersimpan
Dalam contoh ini, saya membuat database dan menggunakan COL_LENGTH
untuk mengembalikan panjang setiap kolom, dalam byte. Saya kemudian memasukkan datetime2 dan waktu kencan nilai ke dalamnya dan gunakan DBCC PAGE()
untuk menemukan panjang data aktual dalam file halaman. Ini menunjukkan kepada kita ruang penyimpanan yang digunakan setiap tipe data saat disimpan dalam database.
Buat basis data:
CREATE DATABASE CompareTypes;
Buat tabel:
USE CompareTypes; CREATE TABLE Datetime2vsDatetime ( TheDateTime datetime, TheDateTime2 datetime2(3) );
Dalam hal ini saya membuat dua kolom – satu adalah datetime kolom dan yang lainnya adalah datetime2 kolom.
Periksa Panjang Kolom
Periksa panjang (dalam byte) setiap kolom:
SELECT COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime2' ) AS 'datetime2', COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime' ) AS 'datetime';
Hasil:
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 7 | 8 | +-------------+------------+
Jadi kita melihat bahwa datetime2 kolom memiliki panjang 7 byte, dibandingkan dengan datetime panjangnya 8 byte.
Sisipkan Data
Sekarang mari kita lihat ukuran penyimpanan dari nilai tanggal dan waktu aktual saat disimpan di SQL Server. Kita dapat menggunakan DBCC PAGE()
untuk memeriksa halaman sebenarnya dalam file data.
Tapi pertama-tama, kita perlu memasukkan data ke dalam kolom kita.
Masukkan data:
DECLARE @thedatetime2 datetime2 = '2025-05-21 10:15:30.5554444'; INSERT INTO Datetime2vsDatetime ( TheDateTime, TheDateTime2 ) SELECT @thedatetime2, @thedatetime2;
Pilih data (hanya untuk memeriksanya):
SELECT * FROM Datetime2vsDatetime;
Hasil:
+-------------------------+-------------------------+ | TheDateTime | TheDateTime2 | |-------------------------+-------------------------| | 2025-05-21 10:15:30.557 | 2025-05-21 10:15:30.555 | +-------------------------+-------------------------+
Menggunakan DBCC PAGE()
Di sinilah kami menggunakan DBCC PAGE()
untuk memeriksa halaman sebenarnya dalam file data.
Pertama, kita akan menggunakan DBCC IND()
untuk menemukan PagePID:
DBCC IND('CompareTypes', 'dbo.Datetime2vsDatetime', 0);
Hasil (menggunakan keluaran vertikal):
-[ RECORD 1 ]------------------------- PageFID | 1 PagePID | 307 IAMFID | NULL IAMPID | NULL ObjectID | 885578193 IndexID | 0 PartitionNumber | 1 PartitionID | 72057594042974208 iam_chain_type | In-row data PageType | 10 IndexLevel | NULL NextPageFID | 0 NextPagePID | 0 PrevPageFID | 0 PrevPagePID | 0 -[ RECORD 2 ]------------------------- PageFID | 1 PagePID | 320 IAMFID | 1 IAMPID | 307 ObjectID | 885578193 IndexID | 0 PartitionNumber | 1 PartitionID | 72057594042974208 iam_chain_type | In-row data PageType | 1 IndexLevel | 0 NextPageFID | 0 NextPagePID | 0 PrevPageFID | 0 PrevPagePID | 0
Ini mengembalikan dua catatan. Kami tertarik dengan PageType dari 1 (catatan ke-2). Kami ingin PagePID dari catatan itu. Dalam hal ini PagePID adalah 320 .
Sekarang kita dapat mengambil PagePID itu dan menggunakannya sebagai berikut:
DBCC TRACEON(3604, -1); DBCC PAGE(CompareTypes, 1, 320, 3);
Ini menghasilkan banyak data, tetapi kami terutama tertarik pada bagian berikut:
Slot 0 Column 1 Offset 0x4 Length 8 Length (physical) 8 TheDateTime = 2025-05-21 10:15:30.557 Slot 0 Column 2 Offset 0xc Length 7 Length (physical) 7 TheDateTime2 = 2025-05-21 10:15:30.555
Ini menunjukkan bahwa waktu-tanggal menggunakan panjang 8 byte dan datetime2(3) menggunakan 7 byte saat disimpan dalam database.
Jadi ini memperkuat kasus untuk menggunakan datetime2 melebihi waktu kencan saat merancang database baru, terutama jika ukuran penyimpanan menjadi perhatian.