2008-10-16 15 views
120

Quiero convertir una cadena como esta:cadena de SQL Server para la conversión de fechas

'10/15/2008 10:06:32 PM' 

en el valor DATETIME equivalente en SQL Server.

En Oracle, quiero decir lo siguiente:

TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM') 

This question implica que debo analizar la cadena en uno de los standard formats, y luego convertir el uso de uno de esos códigos. Eso parece ridículo para una operación tan mundana. hay una manera mas facil?

+0

http://stackoverflow.com/a/15121053/1217045 – hajili

Respuesta

27

SQL Server (2005, 2000, 7.0) no tiene ninguna forma flexible, o incluso no flexible, de tomar una fecha y hora estructurada arbitrariamente en formato de cadena y convertirla al tipo de datos de fecha y hora.

Por "arbitrariamente", me refiero a "una forma que la persona que la escribió, aunque tal vez no usted, yo o alguien del otro lado del planeta, la consideraría intuitiva y completamente obvia". Francamente, no estoy seguro de que exista tal algoritmo.

+27

existe tal algoritmo, Oracle ya lo ha implementado, y la falta de un equivalente de SQL Server es un dolor constante. – matao

+16

@matao, así que por favor infórmenos, ¿cómo Oracle determina mágicamente si un usuario que escribió '9/6/12' significó el 6 de septiembre de 2012, el 9 de junio de 2012, el 6 de diciembre de 2009 o alguna otra cosa? –

+10

no se preocupe, aquí: http://www.techonthenet.com/oracle/functions/to_date.php Obviamente tiene que ser un formato coherente que especifique el desarrollador, pero mucho más flexible que el puñado de máscaras de formato MS da usted, lo que resulta en doloroso análisis personalizado. – matao

10

Para este problema, la mejor solución que uso es tener una función CLR en Sql Server 2005 que use una de las funciones DateTime.Parse o ParseExact para devolver el valor de DateTime con un formato especificado.

36

Ejecutar esto a través de su procesador de consultas. Da formato a las fechas y/o horarios de ese modo y una de ellas debería darle lo que está buscando. No será difícil adaptarse:

Declare @d datetime 
select @d = getdate() 

select @d as OriginalDate, 
convert(varchar,@d,100) as ConvertedDate, 
100 as FormatValue, 
'mon dd yyyy hh:miAM (or PM)' as OutputFormat 
union all 
select @d,convert(varchar,@d,101),101,'mm/dd/yy' 
union all 
select @d,convert(varchar,@d,102),102,'yy.mm.dd' 
union all 
select @d,convert(varchar,@d,103),103,'dd/mm/yy' 
union all 
select @d,convert(varchar,@d,104),104,'dd.mm.yy' 
union all 
select @d,convert(varchar,@d,105),105,'dd-mm-yy' 
union all 
select @d,convert(varchar,@d,106),106,'dd mon yy' 
union all 
select @d,convert(varchar,@d,107),107,'Mon dd, yy' 
union all 
select @d,convert(varchar,@d,108),108,'hh:mm:ss' 
union all 
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)' 
union all 
select @d,convert(varchar,@d,110),110,'mm-dd-yy' 
union all 
select @d,convert(varchar,@d,111),111,'yy/mm/dd' 
union all 
select @d,convert(varchar,@d,12),12,'yymmdd' 
union all 
select @d,convert(varchar,@d,112),112,'yyyymmdd' 
union all 
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)' 
union all 
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)' 
union all 
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)' 
union all 
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)' 
union all 
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)' 
1

Si desea SQL Server para tratar de entenderlo, sólo tiene que utilizar REPARTO CAST ('lo que sea' AS fecha y hora) Sin embargo esto es una mala idea en general. Hay problemas con fechas internacionales que podrían surgir. Entonces, como ha descubierto, para evitar esos problemas, desea utilizar el formato canónico ODBC de la fecha. Ese es el formato número 120, 20 es el formato para solo dos dígitos. No creo que SQL Server tenga una función integrada que le permita proporcionar un formato dado por el usuario. Puede escribir el suyo e incluso puede encontrar uno si realiza una búsqueda en línea.

2

Este page tiene algunas referencias para todas las conversiones de fecha y hora especificadas disponibles para la función CONVERTIR. Si sus valores no entran en uno de los patrones aceptables, entonces creo que lo mejor es ir a la ruta ParseExact.

5

por qué no tratar

select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY] 

formatos de fecha se pueden encontrar en SQL Server Helper > SQL Server Date Formats

+0

Su ejemplo de código no funciona. "La conversión falló al convertir la fecha y/o hora de la cadena de caracteres". –

+0

Debe ser 'select convert (date, '10/15/2011 00: 00: 00 ', 101)'.Más detalles sobre el formato y por qué 101, en https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql – jNick

201

probar este

Cast('7/7/2011' as datetime) 

y

Convert(varchar(30),'7/7/2011',102) 

Ver CAST and CONVERT (Transact-SQL) para obtener más detalles.

+3

Esto funcionó de mí, mientras que el más popular las respuestas en este hilo no. – Maxx

+0

Sí. Combinar esto es lo que funcionó para mí. 'convert (varchar (30), cast ('7/7/2011' como datetime), 102)' ¡Gracias gauravg! – ckpepper02

+8

Esta es la forma correcta de hacerlo, y debe marcarse como la respuesta correcta. Tenga en cuenta que 'Cast ('2011-07-07' como datetime)' también funciona, y elimina la ambigüedad con respecto al orden de mes y día. –

30

En SQL Server Denali, podrá hacer algo que se aproxime a lo que está buscando. Pero aún no puede pasar cualquier cadena de fecha extravagante definida arbitrariamente y esperar que SQL Server se acomode. Aquí hay un ejemplo que usa algo que publicó en su propia respuesta. La función FORMAT() y también puede aceptar configuraciones regionales como un argumento opcional, se basa en.El formato de Net, por lo que la mayoría, si no todos, los formatos de tokens que esperaría ver estarán allí.

DECLARE @d DATETIME = '2008-10-13 18:45:19'; 

-- returns Oct-13/2008 18:45:19: 
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss'); 

-- returns NULL if the conversion fails: 
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME); 

-- returns an error if the conversion fails: 
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME); 

Le recomiendo encarecidamente que tome más control y desinfecte las entradas de fecha. Los días de permitir que las personas escriban las fechas usando el formato que deseen en un campo de formulario de texto libre deberían estar muy lejos de nosotros ahora. Si alguien ingresa el 8/9/2011, ¿es ese 9 de agosto o 8 de septiembre? Si les haces elegir una fecha en un control de calendario, entonces la aplicación puede controlar el formato. No importa cuánto intente predecir el comportamiento de sus usuarios, ellos siempre encontrarán una manera más tonta de ingresar una fecha que no planeó.

Hasta Denali, creo que @Ovidiu tiene el mejor consejo hasta ahora ... esto se puede hacer bastante trivial al implementar su propia función CLR. Luego puede escribir una caja/interruptor para tantos formatos extravagantes como quiera.


UPDATE para @dhergert:

SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us'); 
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb'); 

Resultados:

2008-10-15 22:06:32.000 
2008-10-15 22:06:32.000 

Usted todavía tiene que tener esa otra pieza crucial de información en primer lugar. No puede usar T-SQL nativo para determinar si 6/9/2012 es el 9 de junio o el 6 de septiembre.

+1

Creo que la pregunta fue cómo convertir una cadena en una fecha y no una fecha y hora en una cadena. –

+0

Esto era exactamente lo que necesitaba, gracias a un montón – CWitty

+1

TRY_PARSE era perfecto. Tuvimos un problema con el análisis de una fecha 'Thu Sep 22 2016', ¡gracias por compartir! – Simon

2

Personalmente si se trata de formatos arbitrarios o totalmente fuera de la pared, siempre que sepa lo que están por delante o van a ser, entonces simplemente use regexp para extraer las secciones de la fecha que desee y formar una fecha válida/componente de fecha y hora

+1

SQL Server no tiene soporte RegExp nativo. – RichardTheKiwi

-1

Utilice esta:

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm 

y se refieren a la tabla en el official documentation de los códigos de conversión.

Cuestiones relacionadas