T-SQL datetime dibulatkan ke menit terdekat dan jam terdekat dengan menggunakan fungsi

113

Di SQL server 2008, saya ingin mendapatkan kolom datetime dibulatkan ke jam terdekat dan menit terdekat sebaiknya dengan fungsi yang ada di 2008.

Untuk nilai kolom ini 2007-09-22 15:07:38.850, outputnya akan terlihat seperti:

2007-09-22 15:08 -- nearest minute
2007-09-22 15    -- nearest hour
pengguna219628
sumber
6
Bukankah contoh menit terdekat adalah pukul 15:08? Karena detik dalam satu menit adalah 60 ...
OMG Ponies
Apakah Anda sengaja tidak mengoreksi kesalahan itu ketika Anda mengedit pertanyaannya agar Anda dapat memberikan komentar itu?
Tuan Rabu
@MrWednesday Anda menyadari bahwa ada lebih dari 10 menit antara edit dan komentar itu. Saya membayangkan pikiran itu muncul sesudahnya.
lc.

Jawaban:

208
declare @dt datetime

set @dt = '09-22-2007 15:07:38.850'

select dateadd(mi, datediff(mi, 0, @dt), 0)
select dateadd(hour, datediff(hour, 0, @dt), 0)

akan kembali

2007-09-22 15:07:00.000
2007-09-22 15:00:00.000

Di atas hanya memotong detik dan menit, menghasilkan hasil yang diminta dalam pertanyaan. Seperti yang ditunjukkan @OMG Ponies, jika Anda ingin membulatkan ke atas / ke bawah, maka Anda dapat menambahkan masing-masing setengah menit atau setengah jam, lalu potong:

select dateadd(mi, datediff(mi, 0, dateadd(s, 30, @dt)), 0)
select dateadd(hour, datediff(hour, 0, dateadd(mi, 30, @dt)), 0)

dan Anda akan mendapatkan:

2007-09-22 15:08:00.000
2007-09-22 15:00:00.000

Sebelum tipe data tanggal ditambahkan di SQL Server 2008, saya akan menggunakan metode di atas untuk memotong bagian waktu dari datetime untuk hanya mendapatkan tanggal. Idenya adalah untuk menentukan jumlah hari antara tanggal waktu yang dimaksud dan titik waktu tetap ( 0, yang secara implisit ditransmisikan ke 1900-01-01 00:00:00.000):

declare @days int
set @days = datediff(day, 0, @dt)

lalu tambahkan jumlah hari tersebut ke titik waktu tetap, yang memberi Anda tanggal asli dengan waktu yang disetel ke 00:00:00.000:

select dateadd(day, @days, 0)

atau lebih singkatnya:

select dateadd(day, datediff(day, 0, @dt), 0)

Menggunakan bagian data yang berbeda (mis. hour, mi) Akan bekerja sesuai dengan itu.

Jeff Ogata
sumber
2
Saya ragu ada orang lain yang akan mengalami ini, tetapi jika Anda mencoba membulatkan ke atas ke detik terdekat dan menambahkan pada 500 milidetik, Anda akan ingin melakukan tanggalf (kedua, '1/1/2000', .... vs tanggal (kedua, 0 .... karena Anda akan mendapatkan kesalahan luapan. Detik dari 0 terlalu besar kurasa.
Eric Twilegar
'Tambahkan jumlah jam sejak 1 Jan 1900, ke 1 Jan 1900' - Saya menemukan ini di Java / SQL, yang terlihat jelek. Dalam kasus saya, ini seharusnya dilakukan di sisi Java.
Corwin Newall
Untuk perhitungan dengan datetimeoffset, saya harus menggantinya 0dengan TODATETIMEOFFSET('1900-01-01 00:00:00', 0)untuk menghindari memaksa zona waktu lokal ke hasil.
krlmlr
26

"Dibulatkan" ke bawah seperti pada contoh Anda. Ini akan mengembalikan nilai varchar dari tanggal tersebut.

DECLARE @date As DateTime2
SET @date = '2007-09-22 15:07:38.850'

SELECT CONVERT(VARCHAR(16), @date, 120) --2007-09-22 15:07
SELECT CONVERT(VARCHAR(13), @date, 120) --2007-09-22 15
Magnus
sumber
Mengubah varchar kembali ke datetime bisa dilakukan (untuk jam):CONVERT(datetime, CONVERT(VARCHAR(13), @date, 120)+':00:00')
Decula
10

Saya menyadari pertanyaan ini kuno dan ada jawaban yang diterima dan alternatif. Saya juga menyadari bahwa jawaban saya hanya akan menjawab setengah dari pertanyaan, tetapi bagi siapa pun yang ingin membulatkan ke menit terdekat dan masih memiliki nilai yang kompatibel dengan waktu hanya dengan menggunakan satu fungsi :

CAST(YourValueHere as smalldatetime);

Selama berjam-jam atau detik, gunakan jawaban Jeff Ogata (jawaban yang diterima) di atas.

Andrew Steitz
sumber
1
Jawaban yang sangat bagus, saya telah memverifikasi bahwa itu berputar dan tidak hanya memotong. Untuk orang lain yang mencari opsi ini, smalldatetimeditambahkan dalam SQL 2008.
BradC
Ini adalah opsi terbaik jika Anda perlu memperbaiki beberapa data di tabel Anda yang hanya membutuhkan waktu satu menit.
Enkripsi
-1

Select convert(char(8), DATEADD(MINUTE, DATEDIFF(MINUTE, 0, getdate), 0), 108) as Time

akan membulatkan detik ke bawah menjadi 00

Jam_Jam
sumber
Sangat lambat, dan tidak membulatkan seperti yang diminta OP, tetapi membulatkan ke bawah, yang tidak dia tanyakan. (Penafian - Saya tidak menolak Anda)
Reversed Engineer