Cómo convertir la columna de marca de tiempo de SQL Server al formato de fecha y hora

90

Como SQL Server devuelve una marca de tiempo como 'Nov 14 2011 03:12:12:947PM', ¿hay alguna manera fácil de convertir cadenas a formato de fecha como 'Ymd H: i: s'?

Hasta ahora uso

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

Respuestas:

252

¡El TIMESTAMPtipo de datos de SQL Server no tiene nada que ver con la fecha y la hora!

Es solo una representación hexadecimal de un entero consecutivo de 8 bytes; solo es bueno para asegurarse de que una fila no haya cambiado desde que se leyó.

Puede leer el entero hexadecimal o si desea un BIGINT. Como ejemplo:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

El resultado es

400756068

En las versiones más recientes de SQL Server, se llama RowVersion, ya que eso es realmente. Consulte los documentos de MSDN en ROWVERSION :

Es un tipo de datos que expone números binarios únicos generados automáticamente dentro de una base de datos. rowversion se usa generalmente como un mecanismo para las filas de la tabla de estampación de versiones. El tipo de datos de rowversion es solo un número creciente y no conserva una fecha ni una hora . Para registrar una fecha u hora, use un tipo de datos datetime2.

Por lo tanto, no puede convertir un SQL Server TIMESTAMPen una fecha / hora, simplemente no es una fecha / hora.

Pero si está diciendo marca de tiempo, pero en realidad se refiere a una DATETIMEcolumna, puede usar cualquiera de los formatos de fecha válidos descritos en el tema CAST y CONVERT en la ayuda de MSDN. Estos son definidos y soportados "listos para usar" por SQL Server. Cualquier otra cosa no es compatible, por ejemplo, tiene que hacer una gran cantidad de conversión y concatenación manual (no recomendado).

El formato que está buscando se parece un poco al canónico de ODBC (estilo = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

da:

2011-11-14 10:29:00.470

SQL Server 2012 finalmente tendrá una FORMATfunción para hacer un formato personalizado ...

marc_s
fuente
5
Probablemente mi mayor molestia con SQL Server. ¿Por qué llamarlo una marca de tiempo si no puedo decir la hora con él?
BelgoCanadian
1
@BelgoCanadian: pregúntele a Sybase - esa es una característica que ha estado en Sybase / SQL Server desde siempre .....
marc_s
1
@BelgoCanadian Debería estar contento de saber que ahora se llama rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S
hay TIMESTAMPcolumnas de tipo
Ghilteras
4

La forma más sencilla de hacerlo es:

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

Esto le da a la columna de fecha al menos un formato legible. Además, si desea cambiar el formato, haga clic aquí .

Sudeep nayak
fuente
11
la pregunta es SQLServer, no MySQL
Mike M
4

Con Cast, puede obtener la fecha de un campo de marca de tiempo:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Ali
fuente
18
Esto no parece funcionar:Explicit conversion from data type timestamp to date is not allowed.
jocull
Mala idea. El campo de marca de tiempo es solo una secuencia. Puede que tengas suerte y consigas una cita, pero la fecha no tendrá ningún significado. Debe lanzar a BIGINT si desea un número decimal, en lugar de hexadecimal. La marca de tiempo ahora se llama rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S
3

Mis compañeros de trabajo me ayudaron con esto:

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);
Jadwiga
fuente
3

Funciona bien, excepto este mensaje:

No se permite la conversión implícita del tipo de datos varchar a la marca de tiempo. Utilice la función CONVERT para ejecutar esta consulta

Entonces sí, TIMESTAMP( RowVersion) NO es una FECHA :)

Para ser honesto, yo mismo jugueteé bastante tiempo para encontrar la manera de convertirlo en una cita.

La mejor manera es convertirlo INTy compararlo. Eso es lo que debe ser este tipo.

Si quieres una cita, solo agrega una Datetimecolumna y vive feliz para siempre :)

salud mac

Mac
fuente
1
O BIGINT ya que tiene 8 bytes
Jason S
2

"Sigues usando esa palabra. No creo que signifique lo que tú crees que significa". - Íñigo Montoya

La marca de tiempo no tiene absolutamente ninguna relación con el tiempo como dijo originalmente 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

Observe en la salida que Ts (hex) se incrementa en uno para cada registro, pero el tiempo real tiene un intervalo de 10 segundos. Si estuviera relacionado con el tiempo, habría un espacio en la marca de tiempo para corresponder con la diferencia en el tiempo.

user432532
fuente
0

Después de la impelemtación de conversión a entero CONVERT (BIGINT, [marca de tiempo]) como marca de tiempo, obtuve el resultado como

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Sí, esta no es una fecha y hora, son números de serie

usuario1575120
fuente
0

para mí funciona: TO_DATE ('19700101', 'aaaammdd') + (HORA / 24/60/60) (Oracle DB)

Baidiuk Yevhen
fuente
0

Tuve el mismo problema con la marca de tiempo, por ejemplo: '29 -JUL-20 04.46.42.000000000 PM '. Quería convertirlo en formato 'aaaa-MM-dd'. La solución que finalmente me funciona es

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

cecchy
fuente
0

Asumiré que ha realizado un volcado de datos como declaraciones de inserción, y usted (o quienquiera que busque en Google esto) está intentando averiguar la fecha y la hora, o traducirlo para usarlo en otro lugar (por ejemplo: para convertir a inserciones de MySQL). Esto es realmente fácil en cualquier lenguaje de programación.

Trabajemos con esto:

CAST(0x0000A61300B1F1EB AS DateTime)

Esta representación hexadecimal es en realidad dos elementos de datos separados ... Fecha y hora. Los primeros cuatro bytes son la fecha, los segundos cuatro bytes son la hora.

  • La fecha es 0x0000A613
  • El tiempo es 0x00B1F1EB

Convierta ambos segmentos en números enteros usando el lenguaje de programación de su elección (es una conversión directa de hexadecimal a entero, que es compatible con todos los lenguajes de programación modernos, por lo que no desperdiciaré espacio con código que puede o no ser el lenguaje de programación en el que está trabajando).

  • La fecha de 0x0000A613 se convierte en 42515
  • El tiempo de 0x00B1F1EB se convierte en 11661803

Ahora, qué hacer con esos números enteros:

Fecha

La fecha es desde el 01/01/1900 y se representa como días. Entonces, agregue 42,515 días al 01/01/1900, y su resultado es 27/05/2016.

Hora

El tiempo es un poco más complejo. Tome ese INT y haga lo siguiente para obtener su tiempo en microsegundos desde la medianoche (pseudocódigo):

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

A partir de ahí, utilice las llamadas de función favoritas de su idioma para traducir microsegundos (38872676666,7 µs en el ejemplo anterior) a tiempo.

El resultado sería 10:47: 52.677

Robert Mauro
fuente
-1

Algunos de ellos en realidad se ocultan a una fecha y hora desde SQL Server 2008 en adelante.

Pruebe la siguiente consulta SQL y lo verá por sí mismo:

SELECT CAST (0x00009CEF00A25634 AS datetime)

Lo anterior dará como resultado, 2009-12-30 09:51:03:000pero he encontrado algunos que en realidad no se asignan a una fecha y hora.

ambodi
fuente
1
No hagas eso. Es posible que tenga suerte y obtenga una conversión, pero la fecha y hora no tendrá sentido y será engañosa. La marca de tiempo es solo un número de secuencia y ahora se llama versión de fila docs.microsoft.com/en-us/sql/t-sql/data-types/… . Si desea un número decimal, simplemente conviértalo en BIGINT
Jason S
-1

¿Por qué no intentarlo FROM_UNIXTIME(unix_timestamp, format)?

usuario3541554
fuente
23
Porque esta pregunta se refiere a SQL de Microsoft, no a MySQL.
Slogmeister Extraordinaire
-3

No estoy seguro de si me falta algo aquí, pero no puedes simplemente convertir la marca de tiempo de esta manera:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)
Daniel
fuente
¿Intentaste esto? TIMESTAMP no tiene relación con DATE.
Sean Pearce
Lo estoy usando en SQL Server 2008
Daniel
Nuevamente, no intente transmitir a la fecha y hora. Es simplemente una secuencia entera en forma hexadecimal. Solo envía a BIGINT.
Jason S