Cara mengonversi kolom cap waktu SQL Server ke format datetime

90

Karena SQL Server mengembalikan stempel waktu seperti 'Nov 14 2011 03:12:12:947PM', apakah ada cara mudah untuk mengonversi string ke format tanggal seperti 'Ymd H: i: s'.

Sejauh ini saya gunakan

date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))
Jayson
sumber

Jawaban:

252

SQL Server TIMESTAMPdatatype memiliki apa-apa hubungannya dengan tanggal dan waktu!

Ini hanyalah representasi heksadesimal dari bilangan bulat 8 byte berturut-turut - ini hanya bagus untuk memastikan baris tidak berubah sejak dibaca.

Anda dapat membaca bilangan bulat heksadesimal atau jika Anda menginginkan file BIGINT. Sebagai contoh:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Hasilnya adalah

400756068

Di versi SQL Server yang lebih baru, ini disebut RowVersion- karena memang seperti itulah. Lihat dokumen MSDN di ROWVERSION :

Adalah tipe data yang mengekspos bilangan biner unik yang dibuat secara otomatis dalam database. rowversion umumnya digunakan sebagai mekanisme untuk baris tabel cap versi. Tipe data rowversion hanyalah sebuah angka yang bertambah dan tidak menyimpan tanggal atau waktu . Untuk merekam tanggal atau waktu, gunakan tipe data datetime2.

Jadi, Anda tidak dapat mengubah SQL Server TIMESTAMPmenjadi tanggal / waktu - ini bukan tanggal / waktu.

Tetapi jika Anda mengatakan stempel waktu tetapi yang Anda maksud adalah DATETIMEkolom - maka Anda dapat menggunakan salah satu format tanggal valid yang dijelaskan dalam topik CAST dan CONVERT di bantuan MSDN. Mereka didefinisikan dan didukung "di luar kotak" oleh SQL Server. Ada lagi yang tidak didukung, misalnya Anda harus melakukan banyak casting manual dan penggabungan (tidak disarankan).

Format yang Anda cari terlihat seperti kanonik ODBC (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

SELECT CONVERT(VARCHAR(50), @today, 121)

memberikan:

2011-11-14 10:29:00.470

SQL Server 2012 akhirnya akan memiliki FORMATfungsi untuk melakukan pemformatan kustom ......

marc_s
sumber
5
Mungkin kekesalan terbesar saya dengan SQL Server. Mengapa menyebutnya stempel waktu jika saya tidak dapat memberi tahu waktu dengannya?
BelgoCanadian
1
@BelgoCanadian: tanya Sybase - itu adalah fitur yang ada di Sybase / SQL Server selamanya .....
marc_s
1
@BelgoCanadian Anda seharusnya senang mengetahui bahwa sekarang disebut rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S
ada TIMESTAMPjenis kolom
Ghilteras
4

Cara termudah untuk melakukannya adalah:

SELECT id,name,FROM_UNIXTIME(registration_date) FROM `tbl_registration`;

Ini memberikan kolom tanggal setidaknya dalam format yang dapat dibaca. Selanjutnya jika Anda ingin mengubah format te klik di sini .

Sudeep nayak
sumber
11
pertanyaannya adalah SQLServer, bukan MySQL
Mike M
4

Dengan menggunakan cast Anda bisa mendapatkan tanggal dari kolom timestamp:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Ali
sumber
18
Ini sepertinya tidak berhasil:Explicit conversion from data type timestamp to date is not allowed.
jocull
Ide buruk. Bidang cap waktu hanyalah sebuah urutan. Anda mungkin beruntung dan mendapatkan kencan, tetapi tanggal itu tidak ada artinya. Anda harus mentransmisikan ke BIGINT jika Anda menginginkan angka desimal, bukan hex. Stempel waktu
Jason S
3

Rekan kerja saya membantu saya dengan ini:

select CONVERT(VARCHAR(10), <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(VARCHAR(10), <tms_column>, 112);

atau

select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);
Jadwiga
sumber
3

Berfungsi dengan baik, kecuali pesan ini:

Konversi implisit dari tipe data varchar ke timestamp tidak diperbolehkan. Gunakan fungsi CONVERT untuk menjalankan kueri ini

Jadi ya, TIMESTAMP( RowVersion) BUKAN TANGGAL :)

Sejujurnya, saya mengotak-atik beberapa waktu sendiri untuk menemukan cara mengubahnya menjadi kencan.

Cara terbaik adalah mengonversinya menjadi INTdan membandingkan. Untuk itulah tipe ini dimaksudkan.

Jika Anda ingin kencan - cukup tambahkan Datetimekolom dan hidup bahagia selamanya :)

cheers mac

Mac
sumber
1
Atau BIGINT karena 8 byte
Jason S
2

"Anda tetap menggunakan kata itu. Saya tidak berpikir itu berarti apa yang Anda pikirkan." - Inigo Montoya

Stempel waktu sama sekali tidak memiliki hubungan dengan waktu seperti yang awalnya dikatakan marc_s.

declare @Test table (
     TestId int identity(1,1) primary key clustered
    ,Ts     timestamp
    ,CurrentDt datetime default getdate()
    ,Something varchar(max)
)

insert into @Test (Something)
    select name from sys.tables
waitfor delay '00:00:10'

insert into @Test (Something)
    select name from sys.tables

select * from @Test

Perhatikan dalam output bahwa Ts (hex) bertambah satu untuk setiap record, tetapi waktu aktual memiliki jeda 10 detik. Jika dikaitkan dengan waktu maka akan ada celah di cap waktu untuk menyesuaikan dengan perbedaan waktu.

pengguna432532
sumber
0

Setelah melakukan konversi ke integer CONVERT (BIGINT, [timestamp]) sebagai Timestamp saya mendapatkan hasil seperti

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Ya, ini bukan tanggal dan waktu, Ini nomor seri

pengguna1575120
sumber
0

untuk saya bekerja: TO_DATE ('19700101', 'yyyymmdd') + (TIME / 24/60/60) (oracle DB)

Baidiuk Yevhen
sumber
0

Saya memiliki masalah yang sama dengan cap waktu misalnya: '29 -JUL-20 04.46.42.000000000 PM '. Saya ingin mengubahnya menjadi format 'yyyy-MM-dd'. Solusi yang akhirnya berhasil untuk saya adalah

PILIH TO_CHAR (stempel waktu saya, 'YYYY-MM-DD') DARI mytable;

cecchy
sumber
0

Saya akan berasumsi bahwa Anda telah melakukan dump data sebagai pernyataan masukkan, dan Anda (atau siapa pun Googles ini) mencoba untuk mencari tahu tanggal dan waktu, atau menerjemahkannya untuk digunakan di tempat lain (misalnya: untuk mengubah ke sisipan MySQL). Ini sebenarnya mudah dalam bahasa pemrograman apa pun.

Mari bekerja dengan ini:

CAST(0x0000A61300B1F1EB AS DateTime)

Representasi Hex ini sebenarnya adalah dua elemen data yang terpisah ... Tanggal dan Waktu. Empat byte pertama adalah tanggal, empat byte kedua adalah waktu.

  • Tanggalnya adalah 0x0000A613
  • Waktunya 0x00B1F1EB

Ubah kedua segmen menjadi bilangan bulat menggunakan bahasa pemrograman pilihan Anda (ini adalah konversi hex langsung ke bilangan bulat, yang didukung di setiap bahasa pemrograman modern, jadi, saya tidak akan menyia-nyiakan ruang dengan kode yang mungkin atau mungkin bukan bahasa pemrograman Anda sedang bekerja).

  • Tanggal 0x0000A613 menjadi 42515
  • Waktu 0x00B1F1EB menjadi 11661803

Sekarang, apa yang harus dilakukan dengan bilangan bulat tersebut:

Tanggal

Tanggal sejak 01/01/1900, dan direpresentasikan sebagai hari. Jadi, tambahkan 42.515 hari ke 01/01/1900, dan hasilnya adalah 05/27/2016.

Waktu

Waktu sedikit lebih kompleks. Ambil INT itu dan lakukan hal berikut untuk mendapatkan waktu Anda dalam mikrodetik sejak tengah malam (pseudocode):

TimeINT=Hex2Int(HexTime)
MicrosecondsTime = TimeINT*10000/3

Dari sana, gunakan panggilan fungsi favorit bahasa Anda untuk menerjemahkan mikrodetik (38872676666,7 µs pada contoh di atas) menjadi waktu.

Hasilnya akan menjadi 10: 47: 52.677

Robert Mauro
sumber
-1

Beberapa dari mereka benar-benar terselubung ke tanggal-waktu dari SQL Server 2008 dan seterusnya.

Coba kueri SQL berikut dan Anda akan melihatnya sendiri:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Di atas akan menghasilkan 2009-12-30 09:51:03:000tetapi saya telah menemukan yang sebenarnya tidak memetakan ke tanggal-waktu.

ambodi
sumber
1
Jangan lakukan itu. Anda mungkin beruntung dan mendapatkan konversi tetapi waktu tanggal akan menjadi tidak berarti dan menyesatkan. Stempel waktu hanyalah nomor urut dan sekarang disebut versi baris docs.microsoft.com/en-us/sql/t-sql/data-types/… . Jika Anda menginginkan angka desimal, cukup masukkan ke BIGINT
Jason S
-1

Mengapa tidak mencobanya FROM_UNIXTIME(unix_timestamp, format)?

pengguna3541554
sumber
23
Karena pertanyaan ini mengacu pada Microsoft SQL, bukan MySQL.
Slogmeister Extraordinaire
-3

Tidak yakin apakah saya melewatkan sesuatu di sini tetapi tidak bisakah Anda mengonversi stempel waktu seperti ini:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)
Daniel
sumber
Apakah kamu sudah mencobanya? TIMESTAMP tidak ada hubungannya dengan DATE.
Sean Pearce
Saya menggunakannya di SQL Server 2008
Daniel
Sekali lagi, jangan mencoba mentransmisikan ke datetime. Ini hanyalah urutan integer dalam bentuk heksadesimal. Transmisikan ke BIGINT.
Jason S