SQL Server'ın zaman damgası sütununu tarih saat biçimine dönüştürme


93

SQL Server zaman damgası döndürdüğünde 'Nov 14 2011 03:12:12:947PM', dizeyi 'Ymd H: i: s' gibi tarih biçimine dönüştürmenin kolay bir yolu var mı?

Şimdiye kadar kullanıyorum

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

Yanıtlar:


256

SQL Server'ın TIMESTAMPveri türünün tarih ve saatle ilgisi yoktur!

Bu sadece ardışık 8 baytlık bir tamsayının onaltılık bir temsilidir - yalnızca bir satırın okunduğundan beri değişmediğinden emin olmak için iyidir.

Onaltılık tamsayıyı okuyabilir veya bir BIGINT. Örnek olarak:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Sonuç

400756068

SQL Server'ın daha yeni sürümlerinde buna denir RowVersion- çünkü gerçekte olan budur. ROWVERSION üzerindeki MSDN belgelerine bakın :

Bir veritabanı içinde otomatik olarak oluşturulan, benzersiz ikili sayıları ortaya çıkaran bir veri türüdür. rowversion genellikle tablo satırlarının sürüm damgalama mekanizması olarak kullanılır. Rowversion veri türü yalnızca artan bir sayıdır ve bir tarihi veya saati korumaz . Bir tarih veya saati kaydetmek için bir datetime2 veri türü kullanın.

Eğer Yani olamaz bir SQL Server dönüştürmek TIMESTAMPtarih / zaman - bu sadece bir tarih / zaman değil.

Ancak zaman damgası diyor ancak gerçekten bir DATETIMEsütunu kastediyorsanız - o zaman CAST ve CONVERT'te açıklanan geçerli tarih formatlarından herhangi birini kullanabilirsiniz. , MSDN yardımındaki konusunda . Bunlar SQL Server tarafından "kullanıma hazır" olarak tanımlanır ve desteklenir. Başka hiçbir şey desteklenmez, örneğin çok sayıda manuel döküm ve birleştirme yapmanız gerekir (önerilmez).

Aradığınız format biraz ODBC kanonikine benziyor (stil = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

verir:

2011-11-14 10:29:00.470

SQL Server 2012 sonundaFORMAT özel biçimlendirme yapmak için bir işleve sahip olacak ......


7
Muhtemelen SQL Server ile en büyük deneyimim. Onunla saati söyleyemiyorsam neden ona zaman damgası diyorsun?
BelgoCanadian

1
@BelgoCanadian: Sybase'e sorun - bu, Sybase / SQL Server'da sonsuza kadar olan bir özellik .....
marc_s

1
@BelgoCanadian Artık adı rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

1
orada TIMESTAMPtipi kolonlar
Ghilteras

3

İş arkadaşlarım bu konuda bana yardımcı oldu:

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

veya

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

3

Bunu yapmanın en basit yolu şudur:

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

Bu, tarih sütununu en azından okunabilir bir biçimde verir. Ayrıca, formatını değiştirmek istiyorsanız buraya tıklayın .


11
soru SQLServer, MySQL değil
Mike M

3

Cast'ı kullanarak bir zaman damgası alanından tarih alabilirsiniz:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
Bu işe yaramıyor gibi görünüyor:Explicit conversion from data type timestamp to date is not allowed.
jocull

Kötü bir fikir. Zaman damgası alanı yalnızca bir dizidir. Şanslı olabilir ve bir randevu alabilirsin ama tarihin bir anlamı olmayacak. Onaltılık yerine ondalık bir sayı istiyorsanız BIGINT'e çevirmelisiniz. Zaman damgasının adı artık rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

3

Bu mesaj dışında iyi çalışıyor:

Varchar veri türünden zaman damgasına örtük dönüşüme izin verilmiyor. Bu sorguyu çalıştırmak için CONVERT işlevini kullanın

Yani evet, TIMESTAMP( RowVersion) TARİH DEĞİLDİR :)

Dürüst olmak gerekirse, bunu bir tarihe çevirmenin bir yolunu bulmak için epey bir zaman uğraştım.

En iyi yol, onu dönüştürmek INTve karşılaştırmaktır. Bu tür olması gereken şey bu.

Bir tarih istiyorsanız - sadece bir Datetimesütun ekleyin ve sonsuza dek mutlu yaşayın :)

şerefe mac


1
Veya 8 bayt olduğu için BIGINT
Jason S

2

"O kelimeyi kullanmaya devam ediyorsun. Düşündüğün anlamını ifade ettiğini sanmıyorum." - Inigo Montoya

Marc_s'in başlangıçta söylediği gibi, zaman damgasının zamanla kesinlikle hiçbir ilişkisi yoktur.

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

Çıktıda Ts (onaltılık) değerinin her kayıt için birer birer arttığına, ancak gerçek sürenin 10 saniyelik bir boşluğa sahip olduğuna dikkat edin. Zamanla ilişkili olsaydı, zaman damgasında zamandaki farka karşılık gelen bir boşluk olurdu.


0

Tam sayı CONVERT (BIGINT, [timestamp]) olarak Zaman Damgası olarak dönüşümün başlatılmasından sonra şu sonucu aldım:

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Evet, bu bir tarih ve saat değil, seri numaraları


0

benim için çalışır: TO_DATE ('19700101', 'yyyymmdd') + (TIME / 24/60/60) (oracle DB)


0

Zaman damgasıyla aynı sorunu yaşadım, örneğin: '29 -JUL-20 04.46.42.000000000 PM '. Bunu 'yyyy-MM-gg' formatına dönüştürmek istedim. Sonunda benim için işe yarayan çözüm

Mytable 'dan TO_CHAR (zaman damgası,' YYYY-AA-GG ') SEÇİN;


0

Ek ifadeler olarak bir veri dökümü yaptığınızı ve siz (veya bunu Google'ı yapan kişi) tarih ve saati bulmaya veya başka bir yerde kullanmak üzere tercüme etmeye çalıştığınızı varsayacağım (örneğin: MySQL eklerine dönüştürmek için). Bu aslında herhangi bir programlama dilinde kolaydır.

Bununla çalışalım:

CAST(0x0000A61300B1F1EB AS DateTime)

Bu Hex gösterimi aslında iki ayrı veri öğesidir ... Tarih ve Saat. İlk dört bayt tarih, ikinci dört bayt ise zamandır.

  • Tarih 0x0000A613
  • Saat 0x00B1F1EB

Seçtiğiniz programlama dilini kullanarak her iki segmenti de tamsayılara dönüştürün (bu, her modern programlama dilinde desteklenen, doğrudan onaltılıdan tamsayıya dönüşümdür, bu nedenle programlama dili olabilecek veya olmayabilecek kodla yer israf etmeyeceğim çalışıyorsun).

  • 0x0000A613 tarihi 42515 olur
  • 0x00B1F1EB zamanı 11661803 olur

Şimdi, bu tam sayılarla ne yapmalı?

Tarih

Tarih 01/01/1900'den beri ve gün olarak temsil ediliyor. Yani 01/01/1900 tarihine 42.515 gün ekleyin ve sonucunuz 27.05.2016 olur.

Zaman

Zaman biraz daha karmaşık. Bu INT'yi alın ve gece yarısından itibaren mikrosaniye cinsinden zamanınızı almak için aşağıdakileri yapın (sözde kod):

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

Oradan, mikrosaniyeleri (yukarıdaki örnekte 38872676666,7 µs) zamana çevirmek için dilinizin favori işlev çağrılarını kullanın.

Sonuç 10: 47: 52.677 olacaktır.


-1

Bazıları aslında SQL Server 2008'den itibaren bir tarih-saate gizliyor.

Aşağıdaki SQL sorgusunu deneyin ve kendiniz göreceksiniz:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Yukarıdakilerle sonuçlanacak, 2009-12-30 09:51:03:000ancak aslında bir tarih-saatle eşleşmeyenlerle karşılaştım.


1
Bunu yapma. Şansınız olabilir ve bir dönüşüm elde edebilirsiniz, ancak tarih zamanı anlamsız ve yanıltıcı olacaktır. Zaman damgası yalnızca bir sıra numarasıdır ve şimdi satır sürümü docs.microsoft.com/en-us/sql/t-sql/data-types/… olarak adlandırılmaktadır . Ondalık bir sayı istiyorsanız BIGINT
Jason S


-3

Burada bir şey eksik mi bilmiyorum ama zaman damgasını şu şekilde dönüştüremez misin:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)

Bunu denedin mi TIMESTAMP'ın DATE ile hiçbir ilişkisi yok.
Sean Pearce

Bunu SQL Server 2008'de kullanıyorum
Daniel

Yine, datetime'a çevirmeyi denemeyin. Bu basitçe onaltılık biçimde bir tamsayı dizisidir. Sadece BIGINT'e yayınlayın.
Jason S
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.