Come convertire la colonna timestamp di SQL Server nel formato datetime


90

Poiché SQL Server restituisce il timestamp 'Nov 14 2011 03:12:12:947PM', esiste un modo semplice per convertire una stringa in un formato di data come "Ymd H: i: s".

Finora uso

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

Risposte:


252

Il TIMESTAMPtipo di dati di SQL Server non ha nulla a che fare con una data e un'ora!

È solo una rappresentazione esadecimale di un numero intero di 8 byte consecutivi: è utile solo per assicurarsi che una riga non sia cambiata da quando è stata letta.

Puoi leggere l'intero esadecimale o se vuoi un file BIGINT. Come esempio:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

Il risultato è

400756068

Nelle versioni più recenti di SQL Server, viene chiamato RowVersion, poiché è davvero quello che è. Vedi i documenti MSDN su ROWVERSION :

Tipo di dati che espone numeri binari univoci generati automaticamente all'interno di un database. rowversion viene generalmente utilizzato come meccanismo per l'indicazione della versione delle righe della tabella. Il tipo di dati rowversion è solo un numero crescente e non conserva una data o un'ora . Per registrare una data o un'ora, utilizzare un tipo di dati datetime2.

Quindi non è possibile convertire un SQL Server TIMESTAMPin una data / ora, semplicemente non è una data / ora.

Ma se stai dicendo timestamp ma in realtà intendi una DATETIMEcolonna, puoi utilizzare uno qualsiasi dei formati di data validi descritti nell'argomento CAST e CONVERT nella guida di MSDN. Questi sono definiti e supportati "out of the box" da SQL Server. Qualsiasi altra cosa non è supportata, ad esempio devi fare molti casting e concatenazioni manuali (non consigliato).

Il formato che stai cercando assomiglia un po 'al canonico ODBC (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

dà:

2011-11-14 10:29:00.470

SQL Server 2012 avrà finalmente una FORMATfunzione per eseguire la formattazione personalizzata ...


5
Probabilmente il mio più grande problema con SQL Server. Perché chiamarlo un timestamp se non posso dire l'ora con esso?
BelgoCanadian

1
@ BelgoCanadian: chiedi a Sybase - questa è una funzionalità che è stata in Sybase / SQL Server da sempre .....
marc_s

1
@BelgoCanadian Dovresti essere felice di sapere che ora si chiama rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

ci sono TIMESTAMPcolonne di tipo
Ghilteras

4

Il modo più semplice per farlo è:

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

Ciò fornisce la colonna della data almeno in un formato leggibile. Inoltre se vuoi cambiare il formato clicca qui .


11
la domanda è SQLServer, non MySQL
Mike M

4

Usando Cast puoi ottenere la data da un campo timestamp:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
Questo non sembra funzionare:Explicit conversion from data type timestamp to date is not allowed.
jocull

Cattiva idea. Il campo timestamp è solo una sequenza. Potresti essere fortunato e ottenere un appuntamento, ma l'appuntamento non avrà alcun significato. Dovresti eseguire il cast su BIGINT se desideri un numero decimale, anziché esadecimale. Il timestamp è ora chiamato rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

3

I miei colleghi mi hanno aiutato in questo:

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

o

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

3

Funziona bene, tranne questo messaggio:

La conversione implicita dal tipo di dati varchar al timestamp non è consentita. Utilizzare la funzione CONVERT per eseguire questa query

Quindi sì, TIMESTAMP( RowVersion) NON è una DATA :)

Ad essere onesto, ho giocherellato un po 'di tempo io stesso per trovare un modo per convertirlo in una data.

Il modo migliore è convertirlo in INTe confrontare. Questo è ciò che dovrebbe essere questo tipo.

Se vuoi un appuntamento, aggiungi una Datetimecolonna e vivi felici e contenti :)

saluti mac


1
O BIGINT poiché è di 8 byte
Jason S

2

"Continui a usare quella parola. Non credo che significhi quello che pensi significhi." - Inigo Montoya

Il timestamp non ha assolutamente alcuna relazione con il tempo come diceva originariamente 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

Notare nell'output che Ts (hex) aumenta di uno per ogni record, ma il tempo effettivo ha un intervallo di 10 secondi. Se fosse correlato al tempo, ci sarebbe un intervallo nel timestamp per corrispondere alla differenza nel tempo.


0

Dopo l'impelemtation della conversione all'intero CONVERT (BIGINT, [timestamp]) come Timestamp ho ottenuto il risultato come

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Sì, questa non è una data e un'ora, sono numeri di serie


0

per me funziona: TO_DATE ('19700101', 'aaaammgg') + (TIME / 24/60/60) (Oracle DB)


0

Ho avuto lo stesso problema con il timestamp, ad esempio: '29 -JUL-20 04.46.42.000000000 PM '. Volevo trasformarlo nel formato "aaaa-MM-gg". La soluzione che finalmente funziona per me è

SELEZIONA TO_CHAR (mytimestamp, 'YYYY-MM-DD') FROM mytable;


0

Presumo che tu abbia eseguito un dump dei dati come istruzioni di inserimento e che tu (o chiunque lo usi su Google) stai tentando di capire la data e l'ora, o di tradurlo per usarlo altrove (ad esempio: per convertire in inserti MySQL). Questo è effettivamente facile in qualsiasi linguaggio di programmazione.

Lavoriamo con questo:

CAST(0x0000A61300B1F1EB AS DateTime)

Questa rappresentazione esadecimale è in realtà due elementi di dati separati ... Data e ora. I primi quattro byte sono la data, i secondi quattro byte sono l'ora.

  • La data è 0x0000A613
  • L'ora è 0x00B1F1EB

Converti entrambi i segmenti in numeri interi utilizzando il linguaggio di programmazione che preferisci (è una conversione diretta da esadecimale a intero, che è supportata in ogni linguaggio di programmazione moderno, quindi non sprecherò spazio con codice che può essere o meno il linguaggio di programmazione stai lavorando).

  • La data di 0x0000A613 diventa 42515
  • Il tempo di 0x00B1F1EB diventa 11661803

Ora, cosa fare con questi numeri interi:

Data

La data è dal 01/01/1900 ed è rappresentata come giorni. Quindi, aggiungi 42.515 giorni al 01/01/1900 e il risultato è 27/05/2016.

Tempo

Il tempo è un po 'più complesso. Prendi quell'INT e procedi come segue per ottenere il tuo tempo in microsecondi dalla mezzanotte (pseudocodice):

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

Da lì, usa le chiamate di funzione preferite della tua lingua per tradurre i microsecondi (38872676666,7 µs nell'esempio sopra) in tempo.

Il risultato sarebbe 10: 47: 52.677


-1

Alcuni di essi vengono effettivamente convertiti in una data e ora da SQL Server 2008 in poi.

Prova la seguente query SQL e vedrai di persona:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Quanto sopra risulterà 2009-12-30 09:51:03:000ma ne ho incontrati di quelli che in realtà non sono mappati su una data-ora.


1
Non farlo. Potresti essere fortunato e ottenere una conversione, ma la data e l'ora sarà priva di significato e fuorviante. Il timestamp è solo un numero di sequenza e ora è denominato versione riga docs.microsoft.com/en-us/sql/t-sql/data-types/… . Se vuoi un numero decimale, lancia semplicemente BIGINT
Jason S


-3

Non sono sicuro se mi manchi qualcosa qui, ma non puoi semplicemente convertire il timestamp in questo modo:

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

Hai provato questo? TIMESTAMP non ha alcuna relazione con DATE.
Sean Pearce

Lo sto usando su SQL Server 2008
Daniel

Di nuovo, non provare a trasmettere a datetime. È semplicemente una sequenza intera in forma esadecimale. Trasmetti a BIGINT.
Jason S
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.