Sql Server строка для преобразования даты - PullRequest
156 голосов
/ 16 октября 2008

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

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

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

Ответы [ 10 ]

262 голосов
/ 24 августа 2011

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

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

и

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

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

45 голосов
/ 16 октября 2008

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

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)'
40 голосов
/ 25 августа 2011

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

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

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


ОБНОВЛЕНИЕ для @ 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 сентября.

30 голосов
/ 29 октября 2008

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

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

10 голосов
/ 16 октября 2008

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

8 голосов
/ 23 августа 2011

почему бы не попробовать

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

Форматы даты можно найти в Помощник SQL Server> Форматы даты SQL Server

4 голосов
/ 29 января 2018

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

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

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

2 голосов
/ 01 апреля 2012

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

2 голосов
/ 16 октября 2008

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

0 голосов
/ 16 октября 2008

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

...