2009-05-01 6 views
40

Я получил спецификацию, которая требует формата ISO 8601 даты, делает любой знает коду преобразования или способ получения этих 2 примера:TSQL DATETIME ISO 8601

ISO 8601 Extended Date 2000-01-14T13:42Z 
ISO 8601 Basic Date 20090123T105321Z 
+0

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

ответ

72

При работе с датами в SQL Server , формат ISO-8601, вероятно, лучший способ, поскольку он работает независимо от ваших настроек языка и культуры.

Для того, чтобы вставить данные в таблицу SQL Server, вам не нужны никакие коды преобразования или вообще ничего - просто указать ваши даты в виде текстовых строк

INSERT INTO MyTable(DateColumn) VALUES('20090430 12:34:56.790') 

и вы сделали.

Если вам нужно преобразовать столбец даты в формат ISO-8601 на SELECT, вы можете использовать код преобразования 126 или 127 (с информацией о часовом поясе) для достижения формата ISO.

SELECT CONVERT(VARCHAR(33), DateColumn, 126) FROM MyTable 

должен дать вам:

2009-04-30T12:34:56.790 
+0

-1. Вы должны вставить их в следующем формате: 2009-04-30T00: 00: 00, иначе вы можете получить проблему месяца против дня. – Guillermo

+0

@Guillermo: формат, который я использую сейчас (исправил его), '20090430' будет ** также ** работать на любом SQL Server независимо от языковых и региональных настроек. Отлично работает, если вам не нужно/не заботится о временной части вашей DATE, или если вы используете тип данных DATE в SQL Server 2008 .... –

+0

Я получаю место, где «T» должен быть: 2004-12-14 10: 05: 59.000 –

13

Это

SELECT CONVERT(NVARCHAR(30), GETDATE(), 126) 

будет производить этот

2009-05-01T14:18:12.430 

И еще некоторые детали об этом можно найти на MSDN.

+1

Упрощенный ответ, потому что NVARCHAR не возвращает пробел. –

+1

Вам не нужно включать часть (30). –

+1

@PhillipSenn Я настоятельно рекомендовал оставить его, даже если он технически избыточен здесь. 'nvarchar' без явного размера по умолчанию' 30' в некоторых контекстах и ​​'1' в других, что ухудшает читаемость. Просто попробуйте 'select convert (nvarchar, getdate(), 126); declare @v nvarchar = convert (nvarchar, getdate(), 126); ': первый оператор показывает, что это не усекает. Второй оператор выглядит так, как если бы это значение хранилось в переменной того же типа. Я бы сказал, это очень неинтуитивный аспект SQL Server. – hvd

5

Gosh, NO !!! Вы запрашиваете мир ранений, если вы сохраняете отформатированные даты в SQL Server. Всегда сохраняйте свои даты и время и один из типов данных даты и времени SQL Server (DATETIME, DATE, TIME, DATETIME2, что угодно). Пусть код переднего конца разрешает метод отображения и сохраняет только даты форматирования, когда вы создаете промежуточную таблицу для создания файла. Если вы абсолютно должны отображать форматы даты и времени ISO с SQL Server, делайте это только во время отображения. Я не могу подчеркнуть достаточно ... НЕ сохраняйте отформатированные даты/время в SQL Server.

{Edit}. Причин для этого много, но наиболее очевидным является то, что даже при хорошем формате ISO (который можно сортировать), все будущие вычисления и поиски даты (для поиска всех строк в конкретном месяце, например) потребуют, по крайней мере, неявного преобразование (которое занимает дополнительное время), и если сохраненная форматированная дата не соответствует формату, который вам в настоящее время нужен, вам нужно сначала преобразовать его в дату, а затем в нужный формат.

То же самое относится и к коду переднего конца. Если вы сохраняете отформатированную дату (которая является текстом), она требует, чтобы одни и те же символы отображали локальный формат даты, определенный либо окнами, либо приложением.

Моя рекомендация - всегда хранить дату/время в виде DATETIME или другого временного типа данных и форматировать только дату во время отображения.

+10

Я думаю, что вы неправильно поняли - вставка «20121001» в столбец DateTime всегда будет конвертировать то же самое независимо от региональных настроек. Марк не предполагал, что тип столбца должен быть строкой. –

+2

-1 ОП просил * как * выполнить что-то, а не советовать о том, следует ли это делать. Это не ответ на исходный вопрос, а мнение, основанное на незначительном понимании того, почему пользователь задал вопрос в первую очередь. У ОП вполне может быть жесткое требование сделать это, и ваш ответ ему совсем не помог. Такие вещи следует размещать в виде комментариев. Ответы всегда должны давать ответ. – blockloop

+1

@Blockloop, Если кто-то спрашивает, как застрелиться в голове, вы бы так же не считаете, что это не очень хорошая идея, как не сказать кому-то, кто спрашивает, как сделать что-то не так в SQL Server. Другие в спешке могут не тратить время на чтение простых комментариев. ;-) –

6

Если вам просто нужно вывести дату в ISO8601 формате, включая задней Z, и вы по крайней мере SQL Server 2012, то вы можете использовать FORMAT:

SELECT FORMAT(GetUtcDate(),'yyyy-MM-ddTHH:mm:ssZ')

Это даст вам что-то вроде :

2016-02-18T21:34:14Z

+0

это чище и проще, спасибо! – ideAvi

+0

Как получить миллион секунд 'SELECT FORMAT (GetUtcDate(), 'yyyy-MM-ddTHH: mm: ss.SSSZ')' не работает для 'SSS' – Xin

+1

Использует ли SELECT FORMAT (GetUtcDate(), 'yyyy-MM -ddTHH: mm: ss.fffZ ') 'работает для вас? –

0

Вы технически есть два варианта, когда речь идет о датах ISO.

В общем, если вы фильтруетесь специально на Дата значений в одиночку ИЛИ хотите сохранить дату в нейтральном режиме. Корпорация Майкрософт рекомендует использовать формат нейтрального языка ymd или y-m-d. Каковы оба действительных формата ISO.

Обратите внимание, что форма «2007-02-12» считается языком нейтральным только для типов данных DATE, Datetime2 и DateTimeOffset.

Из-за этого, ваша самая безопасная ставка должна сохраняться/фильтр, основанный на всегда формате нейтральным уровнем ymd.

Код:

select convert(char(10), getdate(), 126) -- ISO YYYY-MM-DD 
select convert(char(8), getdate(), 112) -- ISO YYYYMMDD (safest) 
Смежные вопросы