DateTime2 vs DateTime di SQL Server

762

Yang mana:

adalah yang cara yang direkomendasikan untuk tanggal menyimpan dan waktu di SQL Server 2008+?

Saya menyadari perbedaan dalam presisi (dan kemungkinan ruang penyimpanan), tetapi mengabaikannya untuk saat ini, apakah ada dokumen praktik terbaik tentang kapan harus menggunakan apa, atau mungkin sebaiknya kita hanya menggunakan datetime2saja?

Mikeon
sumber

Jawaban:

641

Dokumentasi MSDN untuk datetime merekomendasikan penggunaan datetime2 . Berikut rekomendasi mereka:

Gunakan time, date, datetime2dan datetimeoffsettipe data untuk pekerjaan baru. Jenis-jenis ini sejajar dengan SQL Standard. Mereka lebih portabel. time, datetime2dan datetimeoffset memberikan lebih banyak presisi detik. datetimeoffsetmemberikan dukungan zona waktu untuk aplikasi yang digunakan secara global.

datetime2 memiliki rentang tanggal yang lebih besar, presisi fraksional default yang lebih besar, dan presisi opsional yang ditentukan pengguna. Juga tergantung pada presisi yang ditentukan pengguna mungkin menggunakan lebih sedikit penyimpanan.

Adam Porad
sumber
46
sementara ada peningkatan presisi dengan datetime2, beberapa klien tidak mendukung tanggal, waktu, atau datetime2 dan memaksa Anda untuk mengonversi ke string literal. Jika Anda lebih peduli tentang kompatibilitas daripada presisi, gunakan datetime
FistOfFury
4
Pilihan lain adalah menggunakan tampilan yang diindeks dengan kolom dikonversi sebagai datetime untuk kompatibilitas. Anda harus dapat mengarahkan aplikasi ke tampilan.
TamusJRoyce
9
Dukungan zona waktu dengan DATETIMEOFFSET adalah keliru. Ini hanya menyimpan offset UTC untuk waktu instan tertentu, bukan zona waktu.
Suncat2000
6
@Porad: Apa sebenarnya manfaat dalam praktik menjadi "" lebih portabel "karena menjadi" SQL Standard "? Selain itu membuat Anda menulis lebih banyak kode secara signifikan yang secara signifikan kurang dapat dibaca / dipelihara untuk" port "ke RDBMS lain yang kemungkinan tidak pernah terjadi selama masa pakai kode itu. Selain alat dan Driver SQL Server yang disediakan Microsoft (jika ada), apakah ada aplikasi yang benar-benar mengandalkan representasi Bit-level spesifik dari DateTime2Tipe tersebut (atau SQL Server lainnya Ketik untuk hal ini)? Lihat Kontra di 7/10/17 Jawaban saya di bawah ini untuk alasan saya bertanya
Tom
2
@Adam Porad: Juga, semua manfaat tersebut kemungkinan tidak diperlukan (di luar aplikasi teknik atau ilmiah) dan oleh karena itu tidak sepadan dengan kehilangan banyak manfaat, JAUH lebih mungkin dibutuhkan: kemampuan yang jauh lebih mudah (meskipun mempertimbangkan penyelesaian masalah) untuk secara implisit / eksplisit dikonversi ke nilai floating-point numerik (# hari termasuk jika appl., hari fraksional sejak waktu tanggal minimum) untuk penambahan, pengurangan, minimum, maksimum, dan rata-rata. Lihat Kontra di 7/10/17 Jawaban saya di bawah untuk rincian.
Tom
493

DATETIME2memiliki rentang tanggal "0001/01/01" hingga " DATETIME9999/12/31 " sedangkan jenisnya hanya mendukung tahun 1753-9999.

Juga, jika perlu, DATETIME2bisa lebih tepat dalam hal waktu; DATETIME terbatas pada 3 1/3 milidetik, sementara DATETIME2dapat akurat hingga 100ns.

Kedua jenis peta untuk System.DateTimedi. NET - tidak ada perbedaan di sana.

Jika Anda punya pilihan, saya akan merekomendasikan menggunakan DATETIME2sedapat mungkin. Saya tidak melihat manfaat menggunakan DATETIME(kecuali untuk kompatibilitas mundur) - Anda akan memiliki lebih sedikit masalah (dengan tanggal di luar jangkauan dan kerumitan seperti itu).

Plus: jika Anda hanya perlu tanggal (tanpa waktu), gunakan DATE - itu sama baiknya DATETIME2dan menghemat ruang Anda juga! :-) Hal yang sama berlaku hanya untuk waktu - gunakan TIME. Untuk itulah jenis-jenis ini ada!

marc_s
sumber
158
Hati-hati saat menambahkan nilai .NET DateTime sebagai parameter ke SqlCommand, karena suka menganggap itu tipe datetime lama, dan Anda akan mendapatkan kesalahan jika Anda mencoba untuk menulis nilai DateTime yang di luar rentang 1753-9999 tahun itu kecuali jika Anda secara eksplisit menentukan jenisnya sebagai System.Data.SqlDbType.DateTime2 untuk SqlParameter. Bagaimanapun, datetime2 sangat bagus, karena ia dapat menyimpan nilai apa pun yang dapat disimpan dalam tipe .NET DateTime.
Triynko
10
@marc_s - Bukankah itu tujuan null?
JohnFx
8
@ JohnFX - agak terlambat di sini - tetapi Anda tidak akan menetapkan datetime menjadi nol. Anda akan menggunakan Nullable <datetime> atau datetime? yang menangani null baik-baik saja - dan dalam pemetaan ke proc hanya akan melakukan param.value = someDateTime ?? DBValue.Null Its disayangkan kita terjebak dengan datatype dengan angka setelah - sepertinya begitu 'generik':)
Adam Tuliper - MSFT
69
Lol, saya baru saja mencoba untuk meningkatkan komentar saya sendiri (di atas), sebelum saya menyadari itu adalah komentar saya sendiri (dibuat lebih dari setahun yang lalu). Saya masih berurusan dengan keputusan desain .NET framework untuk TRUNCATE semua nilai DateTime secara default ketika dilewatkan sebagai SqlParameters kecuali Anda secara eksplisit mengaturnya ke SqlDbType.DateTime2 yang lebih tepat. Begitu banyak untuk secara otomatis menyimpulkan jenis yang benar. Sungguh, mereka seharusnya membuat perubahan itu transparan, mengganti implementasi yang kurang tepat, kurang efisien, jangkauan terbatas, dan mempertahankan nama tipe "datetime" yang asli. Lihat juga stackoverflow.com/q/8421332/88409
Triynko
5
@marc_s Bukankah itu untuk apa Nullable<DateTime>?
ChrisW
207

datetime2 menang di sebagian besar aspek kecuali (Kompatibilitas aplikasi lama)

  1. rentang nilai yang lebih besar
  2. Akurasi yang lebih baik
  3. ruang penyimpanan yang lebih kecil (jika presisi yang ditentukan pengguna opsional ditentukan)

SQL Tanggal dan waktu membandingkan tipe data - datetime, datetime2, date, TIME

harap perhatikan poin-poin berikut

  • Sintaksis
    • datetime2 [(presisi pecahan detik => Lihat Di Bawah Ukuran Penyimpanan)]
  • Presisi, skala
    • 0 hingga 7 digit, dengan akurasi 100ns.
    • Ketepatan standar adalah 7 digit.
  • Ukuran penyimpanan
    • 6 byte untuk presisi kurang dari 3;
    • 7 byte untuk presisi 3 dan 4.
    • Semua presisi lainnya membutuhkan 8 byte .
  • DateTime2 (3) memiliki jumlah digit yang sama dengan DateTime tetapi menggunakan 7 byte penyimpanan, bukan 8 byte ( SQLHINTS- DateTime Vs DateTime2 )
  • Temukan lebih lanjut tentang datetime2 (Artikel Transact-SQL MSDN)

sumber gambar: MCTS Self-Paced Training Kit (Ujian 70-432): Microsoft® SQL Server® 2008 - Implementasi dan Pemeliharaan Bab 3: Tabel -> Pelajaran 1: Membuat Tabel -> halaman 66

Iman
sumber
7
Terima kasih telah menunjukkan statistik +1 untuk itu, datetime2mengagumkan (Pemenang)
Pankaj Parkar
2
@Iman Abidi: Menurut komentar Oskar Berggren tertanggal 10 September 2014 pukul 15:51 pada "SQLHINTS- DateTime Vs DateTime2" artikel yang Anda referensikan: "datetime2 (3) BUKAN sama dengan datetime. Mereka akan memiliki nomor yang sama digit, tetapi ketepatan datetime adalah 3,33 ms, sedangkan ketepatan datetime2 (3) adalah 1ms. "
Tom
1
@PankajParkar: Woah, jangan terlalu cepat. Anda mungkin ingin melihat bagian Kontra dari Jawaban saya tertanggal 7/10/17 di bawah ini.
Tom
Bagaimana cara datetime2menggunakan ruang penyimpanan yang lebih sedikit daripada datetimenamun menawarkan jangkauan yang lebih besar dan presisi yang lebih tinggi?
Dai
107

Saya setuju dengan @marc_s dan @Adam_Poward - DateTime2 adalah metode yang disukai untuk bergerak maju. Ini memiliki rentang tanggal yang lebih luas, presisi lebih tinggi, dan menggunakan penyimpanan yang sama atau kurang (tergantung pada presisi).

Satu hal diskusi terjawab, namun ...
@Marc_s menyatakan: Both types map to System.DateTime in .NET - no difference there. Ini benar, namun, kebalikannya tidak benar ... dan itu penting ketika melakukan pencarian rentang tanggal (mis. "Temukan saya semua catatan yang diubah pada 5/5/2010").

Versi .NET Datetimememiliki kisaran dan ketepatan yang mirip dengan DateTime2. Ketika pemetaan .net sebuah Datetimeturun ke SQL tua DateTimemerupakan pembulatan implisit terjadi . SQL lama DateTimeakurat hingga 3 milidetik. Ini berarti 11:59:59.997sedekat yang Anda bisa sampai pada akhir hari. Apa pun yang lebih tinggi dibulatkan ke hari berikutnya.

Coba ini :

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

Menghindari pembulatan tersirat ini adalah alasan penting untuk pindah ke DateTime2. Pembulatan tanggal secara implisit jelas menyebabkan kebingungan:

EBarr
sumber
14
Anda juga dapat menghindari pembulatan ini dengan tidak mencoba menemukan "akhir" sehari. > = 5 Mei DAN <6 Mei jauh lebih aman dan akan bekerja pada salah satu dari jenis tanggal / waktu (kecuali tentu saja WAKTU). Juga menyarankan untuk menghindari format regional yang ambigu seperti m / d / yyyy.
Aaron Bertrand
2
@AaronBertrand - sepenuhnya setuju, tetapi melihat sejumlah pertanyaan, kami memiliki masalah yang sepertinya layak untuk diuraikan.
EBarr
1
Mengapa Anda beralih dari 20100505ke 5/5/2010? Format sebelumnya akan bekerja dengan wilayah apa pun di SQL Server. Yang terakhir akan pecah: SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')oops:2015-07-01 00:00:00.000
ErikE
1
@EBarr: Re. "DateTime2 adalah metode yang disukai bergerak maju. Ini memiliki rentang tanggal yang lebih luas, presisi lebih tinggi, dan menggunakan penyimpanan yang sama atau kurang (tergantung pada presisi": Saya sangat tidak setuju. Lihat bagian Kontra dari Jawaban saya tanggal 7/10/17 di bawah ini Singkatnya, manfaat-manfaat tersebut kemungkinan tidak dibutuhkan (di luar rekayasa / aplikasi ilmiah) dan oleh karena itu tidak sepadan dengan kehilangan manfaat yang JAUH lebih mungkin dibutuhkan, kemampuan yang jauh lebih mudah (bahkan mempertimbangkan penyelesaian masalah) untuk secara implisit / eksplisit mengkonversi ke numerik titik-mengambang ( # of days termasuk jika appl., pecahan sejak min-time-date) nilai untuk +, - dan rata-rata
Tom
20

Hampir semua Jawaban dan Komentar berat di Pro dan ringan di Kontra. Berikut adalah ringkasan dari semua Pro dan Kontra sejauh ini ditambah beberapa Kontra penting (dalam # 2 di bawah) Saya hanya pernah melihat disebutkan sekali atau tidak sama sekali.

  1. PROS:

1.1. Lebih banyak ISO yang sesuai (ISO 8601) (walaupun saya tidak tahu bagaimana hal ini bisa dilakukan dalam praktiknya).

1.2. Lebih banyak rentang (1/1/0001 hingga 12/31/9999 vs. 1/1 / 1753-12 / 31/9999) (meskipun rentang ekstra, semua sebelum tahun 1753, kemungkinan tidak akan digunakan kecuali untuk mantan, dalam aplikasi historis, astronomi, geologi, dll.).

1.3. Persis cocok dengan rentang rentang .NET's DateTimeType (meskipun keduanya mengkonversi bolak-balik tanpa pengkodean khusus jika nilai-nilai berada dalam kisaran dan ketepatan jenis target kecuali untuk Con # 2.1 di bawah yang lain kesalahan / pembulatan akan terjadi).

1.4. Lebih presisi (100 nanosecond alias 0,000,000,1 dtk vs 3,33 milisecond alias 0,003,33 dtk) (walaupun presisi ekstra kemungkinan tidak akan digunakan kecuali untuk mantan, dalam rekayasa / aplikasi ilmiah).

1.5. Ketika dikonfigurasi untuk serupa (seperti dalam 1 milidetik tidak "sama" (seperti dalam 3,33 milidetik) seperti yang diklaim Iman Abidi) presisi DateTime, menggunakan lebih sedikit ruang (7 vs 8 byte), tetapi tentu saja, Anda akan kehilangan manfaat presisi yang kemungkinan merupakan salah satu dari dua (kisaran lainnya) yang paling dipuji meskipun kemungkinan manfaat yang tidak dibutuhkan).

  1. CONS:

2.1. Ketika melewati Parameter ke. NET SqlCommand, Anda harus menentukan System.Data.SqlDbType.DateTime2apakah Anda mungkin melewati nilai di luar DateTimerentang dan / atau presisi SQL Server , karena itu default untuk System.Data.SqlDbType.DateTime.

2.2. Tidak dapat secara implisit / mudah dikonversi ke nilai numerik floating-point (# hari sejak min date-time) untuk melakukan hal berikut ke / dengan itu dalam ekspresi SQL Server menggunakan nilai numerik dan operator:

2.2.1. tambahkan atau kurangi # hari atau sebagian hari. Catatan: Menggunakan DateAddFungsi sebagai solusi bukanlah hal yang sepele ketika Anda perlu mempertimbangkan banyak jika tidak semua bagian dari tanggal-waktu.

2.2.2. ambil perbedaan antara dua kali tanggal untuk keperluan perhitungan "usia". Catatan: Anda tidak bisa hanya menggunakan DateDiffFungsi SQL Server sebagai gantinya, karena itu tidak menghitung ageseperti yang diharapkan kebanyakan orang bahwa jika dua tanggal-waktu terjadi untuk melintasi batas kalender / jam tanggal-waktu dari unit yang ditentukan jika bahkan untuk sebagian kecil dari unit itu, ia akan mengembalikan selisih 1 dari unit itu vs 0. Misalnya, DateDiffdalam Daydua kali tanggal hanya terpisah 1 milidetik akan mengembalikan 1 vs 0 (hari) jika waktu-waktu tersebut adalah pada hari kalender yang berbeda (yaitu "1999-12-31 23: 59: 59.9999999" dan "2000-01-01 00: 00: 00.0000000"). Perbedaan waktu yang sama 1 milidetik jika dipindahkan sehingga tidak melewati hari kalender, akan mengembalikan "DateDiff" dalam Day0 (hari).

2.2.3. ambil Avgtanggal-waktu (dalam Kueri Agregat) dengan hanya mengonversi ke "Float" terlebih dahulu dan kemudian kembali lagi ke DateTime.

CATATAN: Untuk mengonversi DateTime2menjadi angka, Anda harus melakukan sesuatu seperti rumus berikut yang masih mengasumsikan nilai Anda tidak kurang dari tahun 1970 (yang berarti Anda kehilangan semua rentang tambahan ditambah 217 tahun lagi. Catatan: Anda dapat tidak dapat hanya menyesuaikan rumus untuk memungkinkan rentang tambahan karena Anda dapat mengalami masalah luapan numerik.

25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0- Sumber: " https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html "

Tentu saja, Anda bisa juga Castuntuk yang DateTimepertama (dan jika perlu kembali lagi ke DateTime2), tetapi Anda akan kehilangan ketepatan dan jangkauan (semua sebelum tahun 1753) manfaat DateTime2vs DateTimeyang merupakan 2 terbesar dan juga pada saat yang sama prolly 2 yang paling tidak mungkin diperlukan yang menimbulkan pertanyaan mengapa menggunakannya ketika Anda kehilangan konversi implisit / mudah ke angka floating-point (# hari) untuk tambahan / pengurangan / "usia" (vs DateDiff) / Avgmanfaat calc yang merupakan hal besar dalam pengalaman saya.

Btw, Avgtanggal-waktu adalah (atau setidaknya seharusnya ) kasus penggunaan yang penting. a) Selain digunakan dalam mendapatkan durasi rata-rata ketika tanggal-waktu (karena tanggal-waktu basis umum) digunakan untuk mewakili durasi (praktik umum), b) juga berguna untuk mendapatkan statistik tipe dasbor tentang apa yang rata-rata tanggal- waktu dalam kolom tanggal-waktu dari rentang / grup Baris. c) Standar (atau paling tidak harus standar) Permintaan ad-hoc untuk memantau / memecahkan masalah nilai-nilai dalam suatu Kolom yang mungkin tidak berlaku lagi / lebih lama dan / atau mungkin perlu dihentikan adalah mendaftar untuk setiap nilai hitungan kejadian dan (jika tersedia) perangko Min, Avgdan Maxtanggal-waktu yang terkait dengan nilai itu.

Tom
sumber
1
Seperti tampilan pelawan - ini menunjukkan sisi c # dari persamaan. Dikombinasikan dengan semua "pro" lainnya, itu akan memungkinkan orang untuk membuat pilihan yang baik berdasarkan di mana mereka ingin mengambil rasa sakit mereka.
EBarr
1
@EBarr: Hanya bagian # 1 Kontra dari "" pandangan pelawan "" saya menunjukkan sisi c # dari persamaan ". Sisanya (Kontra 2.2.1 - 2.2.3), yang seperti saya katakan adalah manfaat yang jauh lebih dibutuhkan DateTime, semuanya terkait dengan efek pada SQL Server Queries dan pernyataan.
Tom
Re 2.2.1 - dianggap praktik yang tidak aman untuk melakukan aritmatika pada tanggal, dan cara yang disukai adalah selalu menggunakan DateAdd dan fungsi terkait. Ini praktik terbaik. Ada kewajiban serius untuk melakukan aritmatika tanggal, tidak sedikit yang tidak bekerja untuk sebagian besar jenis tanggal. Beberapa artikel: sqlservercentral.com/blogs/… sqlblog.org/2011/09/20/…
RBerman
@Rerman: Re. "tidak aman": Ini hanya tidak aman dengan tipe tanggal tertentu (sepertiDateTime2 telah saya sebutkan (karena kemungkinan besar meluap)). Kembali. "tidak berfungsi untuk sebagian besar jenis tanggal": Anda hanya perlu bekerja dengan satu jenis tanggal, dan sebagian besar tanggal di sebagian besar aplikasi kemungkinan tidak perlu dikonversi ke jenis tanggal lain untuk seumur hidup mereka (kecuali mungkin, seperti yang saya sebutkan juga , DateTime2untuk DateTime(mis. untuk melakukan "aritmatika pada tanggal"; P). Mengingat bahwa, tidak layak semua pengkodean tambahan tidak hanya diprogram tetapi juga permintaan penelitian khusus untuk menggunakan jenis tanggal ramah non-aritmatika.
Tom
15

DateTime2 mendatangkan malapetaka jika Anda adalah seorang pengembang Access yang mencoba menulis Now () ke bidang yang dimaksud. Baru saja melakukan Access -> SQL 2008 R2 migrasi dan itu menempatkan semua bidang datetime sebagai DateTime2. Menambahkan catatan dengan Now () saat nilainya dibom. Tidak apa-apa pada 1/1/2012 14:53:04 PM, tetapi tidak pada 1/10/2012 14:53:04 PM.

Setelah karakter membuat perbedaan. Semoga ini bisa membantu seseorang.

Rhett A Brown
sumber
15

Berikut ini adalah contoh yang akan menunjukkan kepada Anda perbedaan dalam ukuran penyimpanan (byte) dan presisi antara waktu-kecil, waktu-waktu, datetime2 (0), dan datetime2 (7):

DECLARE @temp TABLE (
    sdt smalldatetime,
    dt datetime,
    dt20 datetime2(0),
    dt27 datetime2(7)
)

INSERT @temp
SELECT getdate(),getdate(),getdate(),getdate()

SELECT sdt,DATALENGTH(sdt) as sdt_bytes,
    dt,DATALENGTH(dt) as dt_bytes,
    dt20,DATALENGTH(dt20) as dt20_bytes,
    dt27, DATALENGTH(dt27) as dt27_bytes FROM @temp

yang kembali

sdt                  sdt_bytes  dt                       dt_bytes  dt20                 dt20_bytes  dt27                         dt27_bytes
2015-09-11 11:26:00  4          2015-09-11 11:25:42.417  8         2015-09-11 11:25:42  6           2015-09-11 11:25:42.4170000  8

Jadi jika saya ingin menyimpan informasi hingga detik - tetapi tidak ke milidetik - saya dapat menyimpan masing-masing 2 byte jika saya menggunakan datetime2 (0) alih-alih datetime atau datetime2 (7).

Baodad
sumber
10

sementara ada peningkatan presisi dengan datetime2 , beberapa klien tidak mendukung tanggal , waktu , atau datetime2 dan memaksa Anda untuk mengonversi ke string literal. Secara khusus Microsoft menyebutkan "down level" ODBC, OLE DB, JDBC, dan SqlClient masalah dengan tipe data ini dan memiliki bagan yang menunjukkan bagaimana masing-masing dapat memetakan jenis.

Jika kompatibilitas nilai lebih dari presisi, gunakan datetime

Tinjuan kemarahan
sumber
10

Pertanyaan Lama ... Tapi saya ingin menambahkan sesuatu yang belum dinyatakan oleh siapa pun di sini ... (Catatan: Ini adalah pengamatan saya sendiri, jadi jangan minta referensi apa pun)

Datetime2 lebih cepat bila digunakan dalam kriteria filter.

TLDR:

Di SQL 2016 saya punya tabel dengan ratusan ribu baris dan kolom datetime ENTRY_TIME karena itu diperlukan untuk menyimpan waktu yang tepat hingga detik. Saat menjalankan kueri yang kompleks dengan banyak gabungan dan sub kueri, saat saya menggunakan klausa mana sebagai:

WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'

Awalnya permintaan baik-baik saja ketika ada ratusan baris, tetapi ketika jumlah baris meningkat, permintaan mulai memberikan kesalahan ini:

Execution Timeout Expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.

Saya menghapus klausa tempat, dan tanpa terduga, kueri dijalankan dalam 1 detik, meskipun sekarang SEMUA baris untuk semua tanggal diambil. Saya menjalankan kueri batin dengan di mana klausa, dan butuh 85 detik, dan tanpa klausa mana butuh 0,01 detik.

Saya menemukan banyak utas di sini untuk masalah ini sebagai kinerja penyaringan datetime

Saya sedikit mengoptimalkan permintaan. Tapi kecepatan sebenarnya yang saya dapatkan adalah dengan mengubah kolom datetime ke datetime2.

Sekarang permintaan yang sama yang waktunya habis sebelumnya membutuhkan waktu kurang dari satu detik.

Bersulang

MJ Khan
sumber
9

Interpretasi string tanggal menjadi datetimedan datetime2bisa berbeda juga, saat menggunakan DATEFORMATpengaturan non-AS . Misalnya

set dateformat dmy
declare @d datetime, @d2 datetime2
select @d = '2013-06-05', @d2 = '2013-06-05'
select @d, @d2

Ini mengembalikan 2013-05-06(yaitu 6 Mei) untuk datetime, dan 2013-06-05(yaitu 5 Juni) untuk datetime2. Namun, dengan dateformatdisetel ke mdy, keduanya @ddan @d2kembali2013-06-05 .

The datetimeperilaku tampaknya bertentangan dengan dokumentasi MSDN dari SET DATEFORMATyang menyatakan: Beberapa format string karakter, misalnya ISO 8601, ditafsirkan secara independen dari pengaturan DateFormat . Jelas tidak benar!

Sampai saya digigit oleh ini, saya selalu berpikir bahwa yyyy-mm-ddtanggal hanya akan ditangani dengan benar, terlepas dari pengaturan bahasa / lokal.

Richard Fawcett
sumber
2
Nggak. Untuk ISO 8601, saya pikir maksud Anda YYYYMMDD (tanpa garis). SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;Coba lagi dengan tanda hubung.
Aaron Bertrand
1
Standar ini memungkinkan untuk format YYYY-MM-DD dan YYYYMMDD untuk representasi tanggal kalender. Saya pikir MSDN harus lebih spesifik tentang subset spesifikasi ISO 8601 mana yang ditafsirkan secara independen!
Richard Fawcett
1
Saya tahu itu tetapi dalam SQL Server hanya sintaks no-dash aman.
Aaron Bertrand
6

Menurut artikel ini , jika Anda ingin memiliki ketepatan DateTime yang sama menggunakan DateTime2 Anda cukup menggunakan DateTime2 (3). Ini akan memberi Anda presisi yang sama, mengambil satu byte lebih sedikit, dan memberikan rentang yang diperluas.

jKlaus
sumber
Agar lebih jelas, ini adalah presisi yang sama dengan datetime SQL, bukan .NET DateTime.
Sam Rueby
Itu benar, saya berasumsi semua orang akan memahami konteksnya tetapi nilainya secara khusus menyatakan.
jKlaus
4

Saya hanya menemukan satu keuntungan lagi untuk DATETIME2: ia menghindari bug dalam adodbapimodul Python , yang meledak jika datetimenilai pustaka standar dilewatkan yang memiliki mikrodetik bukan nol untuk DATETIMEkolom tetapi berfungsi dengan baik jika kolom didefinisikan sebagai DATETIME2.

Bob Kline
sumber
0
Select ValidUntil + 1
from Documents

SQL di atas tidak akan berfungsi dengan bidang DateTime2. Ini kembali dan kesalahan "Operan tipe clash: datetime2 tidak kompatibel dengan int"

Menambahkan 1 untuk mendapatkan hari berikutnya adalah sesuatu yang telah dilakukan pengembang dengan tanggal selama bertahun-tahun. Sekarang Microsoft memiliki bidang datetime2 super baru yang tidak dapat menangani fungsi sederhana ini.

"Mari kita gunakan tipe baru ini yang lebih buruk daripada yang lama", kurasa tidak!

Paul McCarthy
sumber
2
Hanya supaya kita jelas di sini datetimedan datetime2tipe data keduanya diperkenalkan di SQL Server 2008. Anda juga mendapatkan Operand type clash: date is incompatible with intdari datetipe yang sudah ada sejak hari dot. Ketiga tipe data berfungsi dengan baik dateadd(dd, 1, ...).
AlwaysLearning
2
Ini tidak jelas. Saya memiliki database SQLServer 2005 dengan bidang datetime di dalamnya.
Paul McCarthy
0

Saya pikir DATETIME2ini adalah cara yang lebih baik untuk menyimpan date, karena memiliki efisiensi lebih dari DATETIME. Dalam SQL Server 2008Anda dapat menggunakan DATETIME2, menyimpan tanggal dan waktu, dibutuhkan 6-8 bytesuntuk menyimpan dan memiliki presisi 100 nanoseconds. Jadi siapa pun yang membutuhkan ketepatan waktu yang lebih besar akan menginginkannya DATETIME2.

James
sumber