2010-02-11 31 views
22

Cuando selecciono desde SQL Server, quiero obtener una fecha, pero omito el valor de milisegundos, y quiero que sea como un tipo de fecha. Entonces, si tengo un valor 1/1/2009 1:23:11.923, quiero omitir el milisegundo pero retener el tipo de fecha, de modo que sea el valor 1/1/2009 1:23:11.000 (sé que realmente no se puede omitir el valor de milisegundos con una fecha, solo quiero que sea cero)Omitir los milisegundos en una fecha

¿Hay una función en SQL Server para hacer esto? ¿O tengo que escribir mi propia función? De nuevo, no lo quiero como un tipo varchar, sino un tipo datetime.

Respuesta

9

Si no desea utilizar la conversión de series , he aquí una solución:

DECLARE @TheDate datetime, @Today datetime 
SET @TheDate = GetDate() 

SET @Today = DateAdd(dd, DateDiff(dd, 0, @TheDate), 0) 
SELECT DateAdd(s, DateDiff(s, @Today, @TheDate), @Today) 
+0

Esto funciona perfectamente sin redondear a los segundos. Me ayudó. Gracias :) –

+0

Para aquellos que están buscando respuestas sin parte de milisegundos, entonces esto no es para ti, esto da '000' en milisegundos, puedes probar el enfoque de @Peter Radocchia. Si estás de acuerdo con '000', es perfecto para ti. Pero más limpio mejor – Gaurravs

4
SELECT GETDATE(), 
     CONVERT(DATETIME, CONVERT(VARCHAR(MAX), GETDATE(), 120), 120) 
+0

no es el ', 120' en el CONVERTIR más externa redundante? –

+0

@OMGPonies: vamos a votar uno al otro :) – Quassnoi

+0

el estilo de formato CONVERTIR (120) se ignora al convertir de cadena a fecha y hora. BOL dice: _el estilo del formato de fecha utilizado para convertir datos de fecha y hora o de hora pequeña a datos de caracteres (tipos de datos nchar, nvarchar, char, varchar, nchar o nvarchar); o el formato de cadena utilizado para convertir datos float, real, money o smallmoney a datos de caracteres (tipos de datos nchar, nvarchar, char, varchar, nchar o nvarchar). Cuando style es NULL, el resultado devuelto también es NULL._ –

10

Uso:

SELECT CONVERT(DATETIME, CONVERT(VARCHAR(19), GETDATE(), 120)) 

Este:

CONVERT(VARCHAR(19), GETDATE(), 120) 

... omite los milisegundos, devolviendo un VARCHAR. Entonces, VUELVA A CONVERTIRLO en un DATETIME para que funcione con el tipo de datos deseado.

Ver this link for a list of various date/time formats you can work with.

+0

Convertir el número a cadena, y luego nuevamente es muy ineficiente. Use las funciones de fecha y hora proporcionadas dentro de SQL – TFD

6

probar este

declare @DATE datetime 
select @DATE = '1/1/2009 1:23:11.923' 



SELECT convert(datetime,CONVERT(char(35),@DATE,120)) 

o con funciones de fecha solamente

DECLARE @DATE DATETIME 
SELECT @DATE = '1/1/2009 1:23:11.923' 

SELECT DATEADD(SECOND, DATEDIFF(SECOND, 39000, @DATE), 39000) 
+0

Convertir el número a cadena, y luego nuevamente es muy ineficiente. Use las funciones de fecha y hora provistas en SQL – TFD

+0

obtendrá un desbordamiento con milisegundos – SQLMenace

+1

Todo lo que tiene que hacer es restar los milisegundos w/DATEADD(). No es necesario agregar desde 0. –

2
DATEADD(SECOND, DATEDIFF(SECOND, 0, < your datetime column >), 0) 

posible que tenga que cambiar el 0 a otra cosa para evitar un error de desbordamiento. No tiene un Servidor SQL a la mano en este momento para verificar.

Si bien este método no parece ser intuitiva a primera vista, echar un vistazo aquí por la razón de que: http://www.karaszi.com/SQLServer/info_datetime.asp#GettingRidOfTimePortion

EDIT: véanse los comentarios

+0

Frank, creo que quieres SEGUNDO, no MILLISECOND. –

+0

Lol. Buena captura, Aaron. Cambiado. –

43

uso DATETIME2, un nuevo tipo de datos en SQL Server 2008 que es compatible con la precisión fraccionaria:

SELECT 
    CONVERT(DATETIME2(0),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss] 
, CONVERT(DATETIME2(1),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.f] 
, CONVERT(DATETIME2(2),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.ff] 
, CONVERT(DATETIME2(3),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.fff] 
, CONVERT(DATETIME2(4),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.ffff] 
, CONVERT(DATETIME2(5),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.fffff] 
, CONVERT(DATETIME2(6),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.ffffff] 
, CONVERT(DATETIME2(7),SYSDATETIME()) [yyyy-mm-dd hh:mm:ss.fffffff] 

La conversión redondeará a la unidad más cercana, por ejemplo:

2014-09-04 09:35:47.0162993 as DATETIME2(4) -> 
2014-09-04 09:35:47.0163 

Alternativamente, en SQL 2005 y eariler:

SELECT 
    original = GETDATE() 
, [floor] = DATEADD(ms,-DATEPART(ms,GETDATE()),GETDATE()) 
, [ceiling] = DATEADD(ms,1000-DATEPART(ms,GETDATE()),GETDATE()) 
, [rounded] = DATEADD(ms,CASE WHEN DATEPART(ms,GETDATE()) < 500 THEN 0 ELSE 1000 END-DATEPART(ms,GETDATE()),GETDATE()) 

Esto es un poco más rápido que la conversión hacia y desde una representación de cadena .

+1

Guau, eso es genial, pero desafortunadamente, SQL Server 2005 :-( –

+0

Agregué una versión de SQL 2005. –

+1

Brian, eliminé la etiqueta de SQL Server 2008. Si necesita una solución que solo funciona en 2005, no debe etiquetar con una versión que no es correcta. –

Cuestiones relacionadas