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'))
Respuestas:
¡El TIMESTAMP
tipo 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 TIMESTAMP
en una fecha / hora, simplemente no es una fecha / hora.
Pero si está diciendo marca de tiempo, pero en realidad se refiere a una DATETIME
columna, 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 FORMAT
función para hacer un formato personalizado ...
TIMESTAMP
columnas de tipo
Con Cast, puede obtener la fecha de un campo de marca de tiempo:
SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Explicit conversion from data type timestamp to date is not allowed.
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);
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 INT
y compararlo. Eso es lo que debe ser este tipo.
Si quieres una cita, solo agrega una Datetime
columna y vive feliz para siempre :)
salud mac
"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.
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
para mí funciona: TO_DATE ('19700101', 'aaaammdd') + (HORA / 24/60/60) (Oracle DB)
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.
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).
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
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:000
pero he encontrado algunos que en realidad no se asignan a una fecha y hora.
¿Por qué no intentarlo FROM_UNIXTIME(unix_timestamp, format)
?
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)