Преобразование строки Sql сервера в дату

Я хочу преобразовать строку следующим образом:

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

в эквивалентное значение DATETIME на сервере Sql.

В Oracle я бы сказал следующее:

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

Этот вопрос подразумевает, что я должен разобрать строку в один из стандартных форматов , а затем конвертировать с использованием одного из этих кодов. Это кажется смехотворным для такой мирской операции. Есть ли более простой способ?

Ответ 1

SQL Server (2005, 2000, 7.0) не имеет гибкого или даже негибкого способа принятия произвольно структурированного datetime в строчном формате и преобразования его в тип данных datetime.

Под "произвольно" я имею в виду "форму, которую человек, который ее написал, хотя, возможно, и вы, или я или кто-то другой, с другой стороны планеты, считали бы интуитивным и совершенно очевидным". Честно говоря, я не уверен, что есть такой алгоритм.

Ответ 2

Попробуйте это

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

и

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

Подробнее см. CAST и CONVERT (Transact-SQL).

Ответ 3

Запустите это через процессор запросов. Он форматирует даты и/или такие времена, и один из них должен дать вам то, что вы ищете. Его трудно адаптировать:

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)'

Ответ 4

В SQL Server Denali вы сможете сделать что-то, что подходит к тому, что вы ищете. Но вы по-прежнему не можете просто передать произвольно определенную дурацкую строку даты и ожидать, что SQL Server сможет разместиться. Вот один пример, используя то, что вы отправили в своем собственном ответе. Функция FORMAT() также может принимать локали в качестве необязательного аргумента - она ​​основана на формате .Net, поэтому большинство, если не все форматы токенов, которые вы ожидаете увидеть, будут там.

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);

Я настоятельно рекомендую вам больше контролировать и дезинфицировать свои входы даты. Дни, позволяющие людям вводить даты, используя любой формат, который они хотят в поле формы freetext, должны быть позади. Если кто-то входит 8/9/2011 - это то, что 9 августа или 8 сентября? Если вы заставите их выбрать дату в элементе управления календарем, приложение сможет контролировать формат. Независимо от того, насколько вы пытаетесь предсказать поведение своих пользователей, они всегда будут определять более простой способ ввода даты, на которую вы не планировали.

До Денали, однако, я думаю, что у @Ovidiu есть лучший совет до сих пор... это можно сделать довольно тривиальным, реализовав собственную функцию CLR. Тогда вы можете написать case/switch для как можно большего количества дурацких нестандартных форматов.


UPDATE для @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');

Результаты:

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

Прежде всего вам нужно иметь эту важную важную информацию. Вы не можете использовать собственный T-SQL, чтобы определить, есть ли 6/9/2012 9 или 6 сентября.

Ответ 5

Для этой проблемы лучшим решением, которое я использую, является функция CLR в Sql Server 2005, которая использует одну из функций DateTime.Parse или ParseExact, чтобы вернуть значение DateTime в указанном формате.

Ответ 7

Используйте это:

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

И обратитесь к таблице в официальной документации для получения кодов конверсии.

Ответ 8

Эта страница содержит некоторые ссылки для всех указанных преобразований даты и времени, доступных для функции CONVERT. Если ваши значения не попадают в один из приемлемых шаблонов, то я думаю, что лучше всего идти по маршруту ParseExact.

Ответ 9

Лично, если вы имеете дело с произвольными или полностью удаленными форматами стены, если вы знаете, что они впереди времени или собираетесь просто использовать регулярное выражение, чтобы вытащить разделы нужной даты и сформировать действительную дату/дату компонент.

Ответ 10

Если вы хотите, чтобы SQL Server попытался понять это, просто используйте CAST CAST ( "независимо" AS datetime) Однако это плохая идея в целом. Есть проблемы с международными датами, которые возникнут. Итак, как вы обнаружили, чтобы избежать этих проблем, вы хотите использовать канонический формат ODBC даты. Это формат номер 120, 20 - формат только двухзначных лет. Я не думаю, что у SQL Server есть встроенная функция, которая позволяет вам предоставить пользовательский формат. Вы можете написать свой собственный и даже найти его, если будете искать в Интернете.

Ответ 11

Мне потребовалась минута, чтобы понять это, так что вот в случае, если это может кому-то помочь:

В SQL Server 2012 и выше вы можете использовать эту функцию:

SELECT DATEFROMPARTS(2013, 8, 19);

Вот как я в итоге извлек части даты для добавления в эту функцию:

select
DATEFROMPARTS(right(cms.projectedInstallDate,4),left(cms.ProjectedInstallDate,2),right( left(cms.ProjectedInstallDate,5),2)) as 'dateFromParts'
from MyTable