Типы данных date, time и datetime. Типы данных столбцов

Даты и времени YEAR, TIME, TIMESTAMP, DATE и DATETIME имеют собственный интервал допустимых значений, среди которых и значение «ноль», использующееся при введении пользователем действительно недопустимого значения.

Заметим, что MySQL может хранить некоторые не совсем достоверные значения даты, к примеру, 1999-11-31. Причиной тому является то, что управлять проверкой даты должно конкретное приложение, а не SQL-сервер. Чтобы ускорить проверку правильности даты, MySQL проверяет попадание месяца в интервал 0–12 и дня в интервал 0–31. Эти интервалы начинаются с 0 с той целью, чтобы MySQL мог хранить в столбцах DATETIME или DATE даты с днем и месяцем равным 0. Такой вариант полезен, например, для приложений, предполагающих хранение даты рождения, когда не всегда известен месяц или день рождения. Тогда хранение даты происходит в виде 1999-00-00 или 1999-01-00 (для таких дат функции DATE_ADD или DATE_SUB() могут дать неправильные значения).

MySQL интерпретирует значения в нескольких форматах, но всегда ожидается, что даты задаются в порядке год-месяц-день (к примеру, "99-08-05"). Значение, которое имеет тип даты или времени, автоматически преобразуется MySQL в число, когда данную величину используют в виде числа, и наоборот.

Значение, которое имеет тип даты или времени и выходит за границы указанного интервала или недопустимо для данного типа данных, MySQL преобразует в значение «ноль». Исключением являются величины типа TIME, которые выходят за границы установленного интервала и усекаются до граничной точки заданного интервала TIME.

В таблице рассмотрены форматы значения «ноль» для каждого типа столбцов:

Проблема 2000 года для типов данных

MySQL устойчив к «проблеме 2000 года», но некоторые входные величины могут стать источниками ошибок. Например, если ввести двухразрядное значение года, то оно будет интерпретироваться неоднозначно, т.к. не указано столетие. Такие значения должны переводиться в четырехразрядную форму, поскольку MySQL для представления года использует 4 разряда.

Даты с неоднозначным годом в MySQL для типов YEAR, TIMESTAMP, DATE и DATETIME интерпретируются согласно правилам:

  • значение года от 00 до 69 конвертируется в 2000–2069;
  • значение года от 70 до 99 конвертируется в 1970–1999.

Тип TIMESTAMP

Тип TIMESTAMP обеспечивает автоматическую запись текущей даты и времени при использовании операции INSERT или UPDATE. Если используется несколько столбцов типа TIMESTAMP, то автоматически обновляется лишь первый из них.

Тип DATE

Тип DATE содержит величины с информацией о дате в формате "YYYY-MM-DD". Для данного типа год может изменяться в пределах диапазона 1000–9999, а значения месяца и числа в пределах года. Т.е. данные обрабатываются в диапазоне "1000-01-01"–"9999-12-31".

Тип DATETIME

Тип DATETIME используется для величин, которые содержат значения даты и времени. MySQL обрабатывает значения в формате "YYYY-MM-DD HH:MM:SS", которые соответствуют диапазону "1000-01-01 00:00:00"–"9999-12-31 23:59:59".

Тип TIME

MySQL обрабатывает значения данного типа в формате "HH:MM:SS". Для больших значений часа (при указании временного интервала) используется формат "HHH:MM:SS". Значения TIME должны попадать в диапазон от "-838:59:59" до "838:59:59".

Тип YEAR

Тип данных YEAR является однобайтным и содержит значение года.

MySQL обрабатывает значения в формате YYYY и диапазоне от 1901 до 2155.

Недопустимые значения YEAR преобразуются в 0000.

Вначале краткая характеристика каждого из типов:

  • TIMESTAMP - тип данных для хранения даты и времени. Данные хранятся в виде количества секунд, прошедших с начала «эпохи Юникса». Диапазон значений: 1970-01-01 00:00:00 - 2038-12-31 00:00:00. Занимает 4 байта.
  • YEAR - тип данных для хранения года. Диапазон значений: 1901 - 2155. Занимает 1 байт.
  • DATE - тип данных для хранения даты. Диапазон значений: 1000-01-01 - 9999-12-31. Занимает 3 байта.
  • TIME - тип данных для хранения времени. Диапазон значений: −828:59:59 - 828:59:59. Занимает 3 байта.
  • DATETIME - тип данных для хранения даты и времени. Диапазон значений: 1000-01-01 00:00:00 - 9999-12-31 00:00:00. Занимает 8 байт.

Хозяйке на заметку . Интересно то, что большинство программистов полагают, что понятие «timestamp» - это и есть Unix-время. На самом же деле, timestamp - это метка, которая представляет собой последовательность символов, обозначающих дату и / или время, когда определенное событие произошло. А «время Юникса » (Unix time) или POSIX time - это количество секунд, прошедших с полуночи 1 января 1970 года по UTC. Понятие timestamp шире, чем Unix time.

Проанализировав описание типов, представленное выше, можно сделать практически все выводы о достоинствах и недостатках тех или иных типов. Все довольно просто и очевидно.

Но прежде, чем рассказать об использовании этих типов, хочу заметить, что на практике часто используется другой тип для хранения даты и времени: целочисленное значение (для хранения даты - INT (4 байта), даты и времени - BIGINT (8 байт)). Отличие использования целочисленных типов от DATE и DATETIME лишь в том, что при выводе данные не форматируются, а в вычислениях с датами и временем целые числа требуется преобразовывать в соответствующий календарный тип. Кроме того, не производится проверка на валидность представленного значения перед сохранением. Возможности сортировки сохраняются. Поэтому INT и BIGINT имеет смысл использовать в тех же случаях, как DATE и DATETIME, с целью максимизации переносимости и независимости от СУБД. Других преимуществ я не вижу, если они есть, предлагаю указать в комментах.

Использование календарных типов данный в MySQL

Начнем с самого простого - тип YEAR . Единственное его достоинство - малый размер - всего-то 1 байт. Но из-за этого действует строгое ограничение по диапазону допустимых значений (тип может хранить только 255 разных значений). Мне сложно представить практическую ситуацию, когда может потребоваться хранить года строго в диапазоне от 1901 до 2155. Кроме того, тип SMALLINT (2 байта) дает диапазон, достаточный в большинстве ситуаций для хранения года. А экономить 1 байт на строке в таблице БД в наше время смысла нет.

Типы DATE и DATETIME можно объединить в одну группу. Они хранят дату или дату и время с довольно широким диапазоном допустимых значений, независимую от установленной на сервере временной зоны. Их использование определенно имеет практический смысл. Но если требуется хранить даты исторических событий, уходящие в прошлое за Нашу эру, придется выбрать другие типы данных. Для хранения дат неких событий, потенциально выходящих за рамки диапазона типа TIMESTAMP (дни рождений, даты выпуска продуктов, избрания президентов, запуски космических ракет и т.д.), отлично подойдут эти типы. При использовании этих типов нужно учитывать один важный нюанс, но об этом ниже.

Тип TIME можно использовать для хранения промежутка времени, когда не нужна точность меньше 1 секунды, и промежутки времени меньше 829 часов. Добавить тут больше нечего.

Остался самый интересный тип - TIMESTAMP . Рассматривать его надо в сравнении с DATE и DATETIME: TIMESTAMP тоже предназначен для хранения даты и/или времени происхождения неких событий. Важное отличие между ними в диапазонах значений: очевидно, что TIMESTAMP не годится для хранения исторических событий (даже таких, как дни рождений), но отлично подходит для хранения текущих (логирование, даты размещения статей, добавления товаров, оформления заказов) и предстоящих в обозримом будущем событий (выходы новых версий, календари и планировщики и т.д).

Основное удобство использования типа TIMESTAMP состоит в том, что для столбцов этого типа в таблицах можно задавать значение по умолчанию в виде подстановки текущего времени, а так же установки текущего времени при обновлении записи. Если вам требуется эти возможности, то с вероятностью 99% TIMESTAMP — именно то, что вам нужно. (Как этоделать, смотрите в мануале.)

Не стоит бояться того, что с приближением к 2038 году ваш софт перестанет работать. Во-первых, до этого времени вашим софтом, скорее всего, просто перестанут пользоваться (особенно версиями, которые пишутся сейчас). Во-вторых, с приближением к этой дате разработчики MySQL обязательно что-нибудь придумают для сохранения работоспособности вашего софта. Все решится так же хорошо, как проблема Y2K.

Итак, тип TIMESTAMP используем для хранения дат и времени свершения событий нашего времени, а DATETIME и DATE - для хранения дат и времени свершения исторических событий, или событий глубокого будущего.

Диапазоны значений - это важное отличие между типами TIMESTAMP, DATETIME и DATE, но не главное. Главное то, что TIMESTAMP хранит значение в UTC . При сохранении значения оно переводится из текущего временной зоны в UTC, а при его чтении - во время текущей временной зоны из UTC. DATETIME и DATE хранят и выводят всегда одно и то же время, независимо от временных зон.

Временные зоны устанавливаются в СУБД MySQL глобально или для текущего подключения .Последнее можно использовать для обеспечения работы разных пользователей в разных временных зонах на уровне СУБД . Все значения времени физически будут храниться в UTC, а приниматься от клиента и отдаваться клинту - в значениях его временной зоны. Но только при использовании типа данных TIMESTAMP. DATE и DATETIME всегда принимают, хранят и отдают одно и то же значение.

Функция NOW() и ее синонимы возвращают значение времени в текущей временной зоне пользователя.

Учитывая все эти обстоятельства, необходимо быть крайне внимательными при изменении временной зоны в пределах подключения к серверу и использовании типов DATE и DATETIME. Если надо хранить дату (например, дату рождения), то никаких проблем не будет. Дата рождения в любой зоне одинаковая. Т.е. если вы родились 1 января в 0:00 UTC/GMT+0, то это не значит, что в Америке будут праздновать ваш день рождения 31 декабря. Но если вы решите хранить время события в столбце DATETIME, то тут уже построить работу с пользовательскими временными зонами на уровне СУБД просто не выйдет. Поясню на примере:

Пользователь X работает в зоне UTC/GMT+2, Y - в зоне UTC/GMT+3. Для соединений пользователей с MySQL установлена соответствующая (у каждого своя) временная зона. Пользователь размещает сообщение на форуме, нас интересует дата написания сообщения.

Вариант 1: DATETIME. Пользователь X пишет сообщение в 14:00 UTC/GMT+2. Значение в поле «дата» сообщения подставляется как результат выполнения функции NOW() - 14:00. Пользователь Y считывает время написания сообщения и видит те же 14:00. Но у него в настройках стоитзона UTC/GMT+3, и он думает, что сообщение было написано не только что, а час назад.

Вариант 2: TIMESTAMP. Пользователь X пишет сообщение в 14:00 UTC/GMT+2. В поле «дата» попадает результат выполнения функции NOW() - в данном случае - 12:00 UTC/GMT+0. ПользовательY считывает время написания сообщения и получает (UTC/GMT+3)(12:00 UTC/GMT+0) = 15:00 UTC/GMT+3. Все получается ровно так, как мы хотим. И главное - пользоваться этим крайне удобно: для поддержки пользовательских временных зон не нужно писать никакой код приведения времени.

Возможности подстановки текущего времени и работы с временными зонами в типе TIMESTAMP настолько весомы, что если вам в неком логе надо хранить дату без времени, все равно стоит использовать TIMESTAMP, вместо DATE, не экономя 1 байт разницы между ними. При этом на «00:00:00» просто не обращать внимания.

Если же вы не можете использовать TIMESTAMP из-за относительно малого диапазона его значений (а обычно это 1-2 случая против 10-15 в базе сайта), придется использовать DATETIME и аккуратно его корректировать значения в нужных местах (т.е. при записи в это поле переводить дату в UTC, а при чтении - во время в зоне считывающего пользователя). Если вы храните только дату, то скорее всего не важно, какая у вас временная зона: новый год все празднуют 1 января по локальному времени, ничего переводить тут не понадобится.

Типы данных date, time и datetime используются для хранения соответственно даты, времени и даты и времени одновременно. Гораздо удобнее хранить дату и время в формате одного из предназначенных для этого типов данных, а не в виде строки символов. Если вы храните дату и время таким образом, то их проще выводить на экран, поскольку SQL Server автоматически придает им привычный формат. Для этих типов данных можно также использовать специальные функции обработки значений типа дата и время.

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

Следует заметить, что все настройки («по умолчанию») зависят от настроек сервера , поэтому перед внесением каких-либо данных в свою базу следует проверить настройки сервера.

Тип datetime . Позволяет определить для хранения в столбце таблицы дату и время 15.04.00 13:05.

Для отображения значений, хранящихся в виде данных типа datetime, чаще всего (по умолчанию) используется формат: Д ММММ ГГГГ ’г’ (или кратко Д. ММ. ГГ) Ч:мм:сс, например, 12 июня 2000 (или 12.06.00) 22:33:50 . При употреблении значений типа datetime в инструкции INSERT или любой другой их надо ставить в одинарные кавычки. Допускается ввести сначала дату, а потом время, или наоборот, поскольку SQL Server может отличить одно значение от другого и сохранить все так, как нужно.

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

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

Если пропустить часть года, обозначающую век, то декада, меньшая пятидесяти, будет представлена с двадцать первым веком, а декада, большая пятидесяти – с двадцатым. Год необходимо вводить полностью в том случае, если в дате пропущено число. Когда вы вводите дату без числа, это значение будет равно первому числу (по умолчанию).

Время должно вводиться в следующем порядке: часы, минуты, секунды и миллисекунды (если они предусмотрены настройками). Между блоками времени в обязательном порядке должен ставиться разделитель (двоеточие). Он необходим, чтобы распознавать вводимые цифры как время, а не как дату.

В следующей таблице показаны различные интерпретации даты и времени в значении типа datetime.

Я не рекомендую использовать ни поле DATETIME, ни TIMESTAMP. Если вы хотите представить определенный день в целом (например, день рождения), используйте тип DATE, но если вы более конкретны, вы, вероятно, заинтересованы в записи фактического момента, а не единицы время (день, неделя, месяц, год). Вместо использования DATETIME или TIMESTAMP используйте BIGINT и просто сохраните количество миллисекунд с эпохи (System.currentTimeMillis (), если вы используете Java). Это имеет ряд преимуществ:

  1. Вы избегаете блокировки поставщика. Практически каждая база данных поддерживает целые числа относительно похожим образом. Предположим, вы хотите перейти в другую базу данных. Хотите ли вы беспокоиться о различиях между значениями DATETIME MySQL и том, как Oracle их определяет? Даже среди разных версий MySQL, TIMESTAMPS имеют разный уровень точности. Совсем недавно MySQL поддерживал миллисекунды в метках времени.
  2. Нет проблем с часовым поясом. Здесь были некоторые проницательные комментарии о том, что происходит с часовыми поясами с разными типами данных. Но разве это общее знание, и ваши коллеги все время будут учиться этому? С другой стороны, довольно сложно перепутать BigINT в java.util.Date. Использование BIGINT приводит к множеству проблем с часовыми поясами, которые падают на обочину.
  3. Не беспокойтесь о диапазонах или точности. Вам не нужно беспокоиться о том, что будет сокращено будущими диапазонами дат (TIMESTAMP - только 2038).
  4. Интеграция сторонних инструментов. Используя целое число, тривиально для сторонних инструментов (например, EclipseLink) для взаимодействия с базой данных. Не каждый сторонний инструмент будет иметь такое же представление о «datetime», как это делает MySQL. Хотите попытаться выяснить в Hibernate, следует ли использовать объект java.sql.TimeStamp или java.util.Date, если вы используете эти настраиваемые типы данных? Использование базовых типов данных делает использование с сторонними инструментами тривиальным.

Эта проблема тесно связана с тем, как вы должны хранить денежную стоимость (т.е. 1,99 доллара США) в базе данных. Должны ли вы использовать Decimal или тип денег в базе данных, или, что хуже всего, Double? Все 3 из этих вариантов ужасны, по многим причинам, перечисленным выше. Решение заключается в том, чтобы хранить стоимость денег в центах с помощью BIGINT, а затем конвертировать центы в доллары, когда вы показываете значение для пользователя. Задача базы данных состоит в том, чтобы хранить данные и НЕ собирать данные. Все эти причудливые типы данных, которые вы видите в базах данных (особенно Oracle), мало добавляют и запускают вас по пути к блокировке поставщика.

2018-12-04T00:00Z

TIMESTAMP - 4 байта с 8 байтами для DATETIME.

Но, подобно тому, как скронид сказал, что он имеет нижний предел 1970 года. Это здорово для всего, что может произойти в будущем, хотя;)

2018-12-11T00:00Z

Основное различие заключается в том, что DATETIME является постоянным, а TIMESTAMP зависит от установки time_zone .

Поэтому это имеет значение только тогда, когда у вас есть - или может быть в будущем - синхронизированные кластеры во временных зонах.

В более простых словах: если у меня есть база данных в Австралии и я беру дамп этой базы данных для синхронизации / заполнения базы данных в Америке, тогда TIMESTAMP будет обновляться, чтобы отражать реальное время события в новом часовом поясе, тогда как DATETIME по-прежнему отражают время события в часовом поясе .

Отличным примером DATETIME, используемым там, где TIMESTAMP должен был использоваться, является Facebook, где их серверы никогда не могут быть уверены в том, что произошло во время часовых поясов. Однажды у меня был разговор, в котором время говорило, что я отвечаю на сообщения, прежде чем сообщение действительно отправлено. (Это, конечно, также могло быть вызвано неправильным переводом в часовом поясе в программном обеспечении для обмена сообщениями, если время было отправлено, а не синхронизировано).

2018-12-18T00:00Z

Я всегда использую поля DATETIME для чего-либо другого, кроме метаданных строк (дата создана или изменена).

Цель этой статьи заключается в разъяснении особенностей работы с типами DATETIME в SQL Server, в том числе часто встречающихся заблуждений и общих рекомендаций по их преодолению. Благодаря Frank Kalis эта статья переведена на немецкий язык.

Благодарности:

Я хочу поблагодарить следующих людей за их ценные предложения и материалы для этой статьи: Steve Kass, Aaron Bertrand, Jacco Schalkwijk, Klaus Oberdalhoff, Hugo Kornelis, Dan Guzman и Erland Sommarskog.

Версии SQL Server

Данная статья применима к SQL Server 7.0, 2000, 2005 и 2008, если не указано иначе.

Типы даты и времени в SQL Server

До SQL Server 2008 в SQL Server имелось два типа данных для обработки даты и времени. Поскольку в этой статье мы очень часто будем ссылаться на эти типы, введем сокращенную аббревиатуру для каждого типа в двух представленных ниже таблицах (колонка СК):

Название

Мин. значение

Макс. значение

Точность

Используемая память

smalldatetime sdt 1900-01-01 00:00:00 2079-06-06 23:59:00 минута 4 байта
datetime dt 1753-01-01 00:00:00.000 9999-12-31 23:59:59.997 3.33 мс 8 байт

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

Если задавать только ту часть что касается даты, то SQL Server сохранит время в виде 00:00:00.000.
А если устанавливать значение только времени, SQL Server будет хранить дату как 01.01.1900.
Это очень важно. Прочтите снова.

SELECT CAST(‘20041223’ AS datetime)

———————–
2004-12-23 00:00:00.000

SELECT CAST(’14:23:58′ AS datetime)

———————–
1900-01-01 14:23:58.000

С появлением SQL Server 2008 было получено несколько новых типов данных связанных со значениями даты и времени:

Название

Мин. значение

Макс. значение

Точность

Используемая память

datetime2 dt2 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 нс 6-8 байт
date d 0001-01-01 9999-12-31 день 3 байта
time t 00:00:00.0000000 23:59:59.9999999 100 нс 3-5 байта
datetimeoffset dto 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 нс 8-10 байт
  • Как вы можете видеть, мы наконец-то получили типы данных только для даты (date ) и только для времени (time ).
  • Datetime2 это “лучшее DATETIME” по ряду причин, и занимает не многим больше памяти, чем datetime и потенциально даже меньше!
  • Для нового типа включающего величину времени, вы можете задать “точность до дробных секунд” определяя используемый порядок цифр в секундах после запятой. Так, time(3) может хранить значения наподобие 14:23:12.567, которые при вводе значения 14:23:12:5677 округляются до 14:23:12:568.
  • Новый тип datetimeoffset содержит в себе часть смещения местного часового пояса.

Форматы даты и времени

Распространенное заблуждение – то, что SQL Server хранит эти типы данных в некотором специфическом удобном для чтения формате. Это не так. SQL Server хранит такие значения в своем внутреннем формате (например, два целых числа для datetime и smalldatetime ). При этом, когда используется T-SQL для установки значения (например, в выражении INSERT) вы выражаете его как текстовую строку. Существуют также правила для интерпретации SQL Server-ом различных форматов даты-строки. Но заметим, что в любом случае SQL Server не запомнит этот формат.

Входные форматы для даты и времени

Есть много доступных форматов для приведения значений к виду date/time/datetime. Некоторые из них “лучше”, чем другие, и далее вы поймете почему “лучше”. Примечательно, что все эти форматы применимы для всех типов. Так даже формат “только время” применимо для типа “только дата” и т.д. (В статье игнорируется часть смещения местного часового пояса, которая используется только в типе данных datetimeoffset – более подробно о котором в Books Online.)

Название

Формат

SET DATEFORMAT зависимость

SET LANGUAGE зависимость

Нейтральность к языку

Unseparated u ‘19980223 14:23:05’ нет нет для всех
Separated s ’02/23/1998 14:23:05′ для всех для всех нет
ANSI SQL ansisql ‘1998-12-23 14:23:05’ sdt , dt sdt , dt не для sdt и dt
Alphabetic a ’23 February 1998 14:23:05′ нет для всех (название месяца) нет
ODBC datetime odt {ts ‘1998-02-23 14:23:05’} нет нет для всех
ODBC date od {d ‘1998-02-23’} нет нет для всех
ODBC time ot {t ’14:23:05′} нет нет для всех
ISO 8601 iso ‘1998-02-23T14:23:05’ нет нет для всех
Time t ’14:23:05′
‘2:23:05 PM’
нет нет для всех
  • Отметим, ANSI SQL действительно только частный случай формата с разделительными символами Separated (так называемый “цифровой”), использующий в качестве разделителей тире (-), косую черту (/) и точку (.). Но, поскольку это единственный формат, определенный в стандарте ANSI SQL, по мнению автора это стоит упомянуть как частный случай.
  • Большинство форматов позволяют удалять часть содержащую дату и/или время, и в некоторых случаях это может выглядеть немного … странно. Казалось бы, неразумно указывать, например ‘2008-08-25’ как тип время (time ), но в конечном результате это аналогично не установке значений в строке datetime . Рассмотрим ниже:
    SELECT CAST(AS time)
    SELECT CAST(‘2008-08-25’ AS time)

    Оба запроса выдают один и тот же результат (time 00:00:00).
  • ODBC форматы (ODBC datetime, ODBC date, ODBC time ) отличаются в том смысле, что у них есть маркер (literal_type, t, d или ts), который необходимо правильно задать в зависимости от того, получать ли дату и время, только дату или только время.
  • Для применения формата ISO 8601 необходим сегмент даты и времени.
  • SET DATEFORMAT наследует свои настройки от SET LANGUAGE (но явно заданный SET DATEFORMAT аннулирует более поздний SET LANGUAGE). Языковые настройки по умолчанию задаются для каждого языка используемого при вводе логина. Язык по умолчанию для логина задается при помощи sp_configure.
  • Правила, относительно форматирования части даты и новых типов могут привести к путанице. Microsoft стремится, чтобы дата новых соответствующих типов данных (date, datetime2 и datetimeoffset ) была менее зависима от настроек и еще более соответствовала требованиям ANSI SQL. И в результате – новые типы нейтрально-языковые для выделения составляющих даты-времени до тех пор пока год на первом месте. SQL Server-у необходимо определить, что эта часть является годом, и поэтому требуется 4 позиции составляющих год (yyyy, а не yy). Если это так, то строка будет интерпретироваться как сначала год, затем месяц и, наконец, день – независимо от DATEFORMAT или языковых установок. Если же вначале указывается месяц, тогда DATEFORMAT и языковые настройки будут “соблюдаться”:
    SET LANGUAGE British –uses dmy
    GO
    SELECT CAST(’02-23-1998 14:23:05′ AS date) –Error
    GO
    SELECT CAST(‘2/23/1998 14:23:05’ AS date) –Error
    GO
    SELECT CAST(‘1998-02-23 14:23:05’ AS date) –Ok
    GO
    SELECT CAST(‘1998.02.23 14:23:05’ AS date) –Ok
    GO
    SELECT CAST(‘1998/02/23 14:23:05’ AS date) –Ok
    GO
    Первые
    два запроса ошибочны поскольку год не на первой позиции (и нет 23 месяца в 1998 году). В последующих трех запросах ошибок нет, поскольку требования учтены, и год указан первым (и мы используем один из новых стилей типов связанных с датой). Предельно прозрачно, правда? 🙂

Описание доступных форматов имеется в Books Online, поэтому вдаваться в подробности для каждого формата нет смысла.

Книга Richard T. Snodgrass “Разработка временно-ориентированных приложений баз данных в SQL”: содержит много сведений о представлении время-ориентированной информации в модели данных. И, конечно же, возможно использование этой дополнительной (исторической) информации в своих запросах SQL. Эта книга не издается, а на официальном сайте Ричарда (www.cs.arizona.edu/people/rts), вы бесплатно можете скачать ее в PDF формате.

Перевод: Винчик Евгений