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

В следующих подразделах данного раздела приводятся сведения и даются примеры использования функций и типов данных даты и времени. Обзор всех типов данных и функций даты и времени в языке Transact-SQL см. в разделе Типы данных и функции даты и времени (Transact-SQL).

  • Использование операторов с типами данных даты и времени

  • Использование форматов даты и времени

  • Форматы даты и времени для строковых литералов

  • Строковый формат без разделителей

  • Формат ISO 8601

  • Алфавитные форматы даты

  • Числовые форматы даты

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

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

  • Преобразование типов date, time, datetime2 и datetimeoffset

  • Преобразование между строковыми литералами и типами time(n), date, datetime2(n) и datetimeoffset(n)

  • Преобразование между типами данных даты и времени

  • Использование операций CAST и CONVERT с типами time, date, datetime2 и datetimeoffset

  • Аргументы стиля для функции CONVERT

  • Ограничения даты и времени в SQL Server

  • Обратная совместимость для клиентов нижнего уровня

  • Пример

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

Для всех типов данных даты и времени поддерживаются реляционные операторы (<, <=, >, >=, <>), операторы сравнения (=, <, <=, >, >=, <>, !<, !>), а также логические операторы и предикаты Boolean (IS NULL, IS NOT NULL, IN, BETWEEN, EXISTS, NOT EXISTS и LIKE).

Арифметические операторы для типов данных даты и времени

Для сложения и вычитания любых типов данных даты и времени следует использовать функции DATEADD и DATEDIFF.

Использование форматов даты и времени

Форматы строковых литералов влияют на представление данных в приложениях для пользователей, но не на базовый формат хранения целых чисел в SQL Server. Однако SQL Server может воспринять значение даты в формате строкового литерала, поставленное приложением или пользователем для хранения или для обработки функцией для работы с датами, как разные даты. То, как будет воспринято значение, зависит от сочетания формата строкового литерала, типа данных и следующих настроек времени выполнения: SET DATEFORMAT, SET LANGUAGE и параметр default language.

На некоторые форматы строковых литералов эти настройки не влияют. Если нет уверенности в том, что эти настройки верны для данного формата, то, возможно, стоит задуматься об использовании формата, не зависящего от них. Формат ISO 8601 не зависит от этих настроек и является международным стандартом. Язык Transact-SQL, который использует форматы строковых литералов, зависящие от системных настроек, является менее мобильным.

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

Формат даты ydm не поддерживается для типов date, datetime2.и datetimeoffset. Во время выполнения возникнет ошибка.

Форматы даты и времени для строковых литералов

Следующая таблица содержит список различных строковых форматов даты и времени. Рекомендуется использовать многоязычные форматы даты и времени, не зависящие от параметра DATEFORMAT. Форматы ISO 8601 «1998-02-23T14:23:05» и «1998-02-23T14:23:05 -08:00» являются единственными форматами, принятыми в качестве международного стандарта. Они не зависят от параметра DATEFORMAT или от языка имени входа и являются многоязычными.

Элемент дата-время

Тип формата

Пример формата

Комбинируемость с другими форматами

Зависимость от параметра DATEFORMAT

Многоязычный

Дата

Неразделяемый

ISO 8601

'19980223'

Да

Нет

Да

Дата

Numeric

'02/23/1998'

Да

да

Нет

(DATEFORMAT)

Дата

ISO 8601 Числовой

'1998-02-23'

Да

Нет

Нет

Дата

Алфавитный

«23 февраля 1998 г.»

Да

Нет

Нет

(месяц или сокращенный месяц)

Дата

ODBC дата

{ д «23.02.1998» }

Нет

Нет

Да

Время

ISO 8601 Время

'14:23:05'

'10:00:00.123456'

Да

Нет

Да

Время

ODBC время

{ т «14:23:05» }

Нет

Нет

Да

Дата-время

ODBC дата-время

{тс «1998-02-23 14:23:05»}

Нет

Нет

Да

Дата-время

ISO 8601

1998-02-23T14:23:05

1998-02-23T14:23:05 -08:00

Нет

Нет

Да date, datetime2, datetimeoffset.

Дата-время

Стандарт SQL ANSI

'1998-02-23 14:23:05'

'1998-02-23 14:23:05 -08:00'

Нет

Нет (datetime2, datetimeoffset)

Да (datetime)

Да date, datetime2, datetimeoffset.

Дата-время

Сочетание даты и времени

'19980223 14:23:05'

'02/23/1998 2:23:05 PM'

'1998-02-23 10:00:00.123'

'23 фев 1998 14:23:05'

Нет

Да

(часть даты)

Нет

TimeZone

Формат TimeZone

'+12:00'

'01:00'

'-08:00'

«П»

Да

Нет

Да

Следующие инструкции демонстрируют эффект настроек SET LANGUAGE и SET DATEFORMAT.

DECLARE @Today date = '12/1/2003';
DECLARE @MyTime time = '12:30:22';
DECLARE @MyDatetimeoffset datetimeoffset = '12/1/2003 12:30:22 -5:00';
SET LANGUAGE Italian
    -- Returns: Changed language setting to Italiano.
SELECT DATENAME(month, @Today) AS 'Month Name';
    -- Returns: dicembre
SELECT CONVERT(VARCHAR(30), @MyDatetimeoffset) AS 'DATETIMEOFFSET';
    -- Returns: dic  1 2003 12:30PM -05:00
SELECT DATENAME(hour, @MyTime) As 'Hour Name';
    -- Returns: 12

SET LANGUAGE us_english;
    -- Returns: Changed language setting to us_english.
SELECT DATENAME(month, @Today) AS 'Month Name';
    -- Returns: December
SELECT CONVERT(VARCHAR(30), @MyDatetimeoffset) AS 'DATETIMEOFFSET';
    -- Returns: Dec  1 2003 12:30PM -05:00
SELECT DATENAME(hour, @MyTime) As 'Hour Name';
    -- Returns: 12
GO
-- Set date format to month, day, year.
SET DATEFORMAT mdy;
GO
DECLARE @datevar date = '12/31/1998';
SELECT @datevar AS DateVar;
    -- Returns: 1998-12-31
GO
-- Set date format to year, day, month. 
SET DATEFORMAT ydm;
GO
DECLARE @datevar datetimeoffset = '1998/31/12 12:30:22 -05:00';
SELECT @datevar AS DateVar;
    -- Returns: Msg 241, Conversion failed when converting 
    -- date and/or time from character string.
GO
-- Set date format to year, month, day.
SET DATEFORMAT ymd;
GO
DECLARE @datevar date = '12/31/1998';
SELECT @datevar AS DateVar;
    -- Returns: 1998-12-31
GO

Строковый формат без разделителей

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

Параметр сеанса SET DATEFORMAT не влияет на записи даты, содержащие только цифры, например на цифровые записи без разделителей. Шестиразрядные и восьмиразрядные строки всегда интерпретируются как ymd. На месяц и день всегда должно приходиться по две цифры.

Вот пример допустимого строкового формата без разделителей: [19]960415

Строка только из четырех разрядов интерпретируется как год. Число и месяц принимают значение 1 января. В четырехразрядном формате всегда указывайте столетие.

Формат ISO 8601

Далее приводится формат даты со временем ISO 8601:

  • ГГГГ-ММ-ДДТчч:мм:сс[.ннннннн] [{+|-}чч:мм]

  • ГГГГ-ММ-ДДТчч:мм:сс[.ннннннн]П (UTC, универсальное синхронизированное время)

Символ T указывает на начало временной части значения дата-время.

Чтобы использовать формат ISO 8601, необходимо указать каждый элемент формата. Необходимо включить символ T, двоеточия (:) знаки + или - и точки (.). Скобки показывают, что доли секунд или величина смещения часового пояса не являются обязательными.

Временной компонент указан в 24-часовом формате.

Преимущество использования формата ISO 8601 заключается в том, что он является международным стандартом. Значения даты-времени, указанные с помощью данного формата, однозначны. Также на данный формат не влияют настройки SET DATEFORMAT, SET LANGUAGE или язык по умолчанию для имени входа.

Ниже приведены два примера значений даты-времени, указанных в формате ISO 8601:

  • 2004-05-23Т14:25:10

  • 2004-05-23T14:25:10.1234567+07:00

Алфавитные форматы даты

На английском языке месяц можно указать как имя, например April, или как сокращение Apr. Эти значения должны быть указаны на языке, заданном параметром LANGUAGE для данного сеанса; например, если указан французский язык, то значения должны быть avril или avr. Запятые являются необязательными, регистр букв не учитывается.

Некоторые рекомендации по применению алфавитных форматов даты:

  • Заключайте дату и время в одинарные кавычки (').

  • Если указать две последние цифры года, значения, меньшие двух последних цифр значения параметра конфигурации two digit year cutoff, будут относиться к столетию года усечения. Значения, большие или равные двум последним цифрам этого параметра, относятся к столетию, предшествующему столетию года усечения. Например, если параметр two digit year cutoff равен 2050 (значение по умолчанию), значение 25 интерпретируется как 2025, а 50 — как 1950. Во избежание неоднозначности пользуйтесь четырехсимвольным обозначением года.

  • Если не указано число месяца, подразумевается первое число месяца.

  • Параметр сеанса SET DATEFORMAT не применяется, если месяц указывается в алфавитном формате.

  • Следующие форматы являются допустимыми алфавитными форматами для даты в SQL Server. Символы, заключенные в квадратные скобки, являются необязательными.

  • Apr[il] [15][,] 1996

  • Apr[il] 15[,] [19]96

  • Apr[il] 1996 [15]

  • [15] Apr[il][,] 1996

  • 15 Apr[il][,][19]96

  • 15 [19]96 apr[il]

  • [15] 1996 apr[il]

  • 1996 APR[IL] [15]

  • 1996 [15] APR[IL]

Числовые форматы даты

Месяц в датах может указываться в числовом формате. Например, 5/20/97 обозначает двадцатое мая 1997 года. Используя формат числовых дат, указывайте месяц, день и год в виде строки со знаками косой черты (/), дефисами (-) или точками (.) в качестве разделителей. Эта строчка должна выглядеть следующим образом:

числоразделительчислоразделительчисло [время] [время]

Допустимы следующие числовые форматы.

  • [0]4/15/[19]96 -- (мдг)

  • [0]4-15-[19]96 -- (мдг)

  • [0]4.15.[19]96 -- (мдг)

  • [0]4/[19]96/15 -- (мгд)

  • 15/[0]4/[19]96 -- (дмг)

  • 15/[19]96/[0]4 -- (дгм)

  • [19]96/15/[0]4 -- (гдм)

  • [19]96/[0]4/15 -- (гмд)

Значение параметра DATEFORMAT языка по умолчанию для сеанса задается языком по умолчанию для имени входа, инструкцией SET LANGUAGE или инструкцией SET DATEFORMAT. Если именем входа или инструкцией SET LANGUAGE устанавливается язык us_english, то порядком по умолчанию для даты является mdy.

Можно изменить порядок даты при помощи инструкции SET DATEFORMAT. Установка для SET DATEFORMAT определяет, как будут интерпретированы значения дат. Если порядок не соответствует параметру, значения не рассматриваются как даты, поскольку находятся вне допустимого диапазона или интерпретируются ошибочно. Например, 12/10/08 может быть интерпретировано как одна из шести различных дат в зависимости от установки DATEFORMAT. Четырехразрядный год будет интерпретирован как год.

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

SQL Server распознает следующие форматы для данных времени. Формат должен быть заключен в одинарные кавычки ('):

  • 14:30

  • 14:30[:20:999]

  • 14:30[:20.9]

  • 04:00:00

  • 16:00:00

  • [0]4[:30:20:500]AM

Следующие инструкции показывают возвращаемые значения функции CAST для различных входных данных

SELECT CAST('01/01/2000 14:30' AS datetime2)
    --Returns: 2000-01-01 14:30:00.0000000
SELECT CAST('01/01/2000 14:30:20:999' AS datetime2)
    -- Returns: 2000-01-01 14:30:20.9990000
SELECT CAST('01/01/2000 14:30:20.9' AS datetime2)
    -- Returns: 2000-01-01 14:30:20.9000000
SELECT CAST('01/01/2000 4am' AS datetime2)
    -- Returns: 2000-01-01 04:00:00.0000000
SELECT CAST('01/01/2000 4 PM' AS datetime2)
    -- Returns: 2000-01-01 16:00:00.0000000
SELECT CAST('01/01/2000 04:30:20:500AM' AS datetime2)
    -- Returns: 2000-01-01 04:30:20.5000000
SELECT CAST('01/01/2000 04:30:20:500 AM' AS datetime2)
    -- Returns: 2000-01-01 04:30:20.5000000
GO

Для указания времени до или после 12 часов дня можно использовать суффиксы «АМ» и «РМ». Регистр символов в них не учитывается.

Часы могут быть указаны исходя из 12- или 24-часового формата. Значения часов интерпретируются следующим образом.

  • Значение часа 00 представляет час после полуночи («АМ»), независимо от того, указано «АМ» или нет. Если значение часа равно 00, то «PM» указывать нельзя.

  • Значения часа от 01 до 11 представляют часы до полудня, если не задан параметр «AM» или «PM». Если задан параметр «AM», то эти значения также представляют часы до полудня. Если указано «PM», то эти значения указывают на часы после полудня.

  • Значение 12 представляет час, начавшийся в полдень, если не указано «PM» или «AM». Если указано «AM», это значение представляет час, начавшийся в полночь. Если указано «PM», то это значение представляет час, начавшийся в полдень. Например: 12:01 — это 1 минута после полудня, так же как и 12:01 PM, тогда как 12:01 AM — это 1 минута после полуночи. 12:01 АМ аналогично указанию 00:01 или 00:01 AM.

  • Значения часов от 13 до 23 представляют часы после полудня, если не указано «AM» или «PM». Если задан параметр «PM», то эти значения также представляют часы после полудня. Если час принимает значение от 13 до 23, то указывать «AM» нельзя.

  • Нельзя указывать значение часа 24. Для обозначения полночи пользуйтесь значением 12:00 АМ или 00:00.

Миллисекундам может предшествовать либо двоеточие (:), либо точка (.). Число после двоеточия обозначает тысячные доли секунды. При использовании точки однозначное число обозначает десятые доли секунды, двузначное число — сотые, а трехзначное — тысячные доли секунды. Например: 12:30:20:1 означает 20 и одну тысячную долю секунды после 12:30, 12:30:20.1 означает 20 и одну десятую секунды после 12:30.

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

Интерфейс API ODBC определяет управляющие последовательности, представляющие значения даты и времени, называемые в ODBC временными метками. Этот формат временных меток ODBC также поддерживается языком определений OLE DB (DBGUID-SQL) и поставщиком OLE DB для MicrosoftSQL Server. Приложения, использующие ADO, OLE DB или API-интерфейсы, основанные на ODBC, могут использовать этот формат временных меток ODBC для представления даты и времени.

SQL Server всегда обрабатывает данные ODBC как тип данных datetime.

Управляющие последовательности временных меток ODBC имеют следующий формат:

{ literal_type 'constant_value' }

  • literal_type
    Определяет тип управляющей последовательности. Далее приводятся допустимые аргументы для управляющей последовательности literal_type.

    d = только дата

    t = только время

    ts = временная метка (дата + время)

  • 'constant_value'
    Значение управляющей последовательности. constant_value должно соответствовать этим форматам для каждого literal_type.

    literal_type

    формат constant_value

    d

    ГГГГ-ММ-ДД

    t

    ЧЧ:ММ:СС[.ссс]

    ts

    ГГГГ-ММ-ДДЧЧ:ММ:СС[.ссс]

Вот примеры констант даты и времени ODBC:

  • { тс «1998-05-02 01:23:56.123» }

  • { д «1990-10-02» }

  • { т «13:33:41» }

Не путайте имя типа данных временной метки ODBC и OLE DB с именем типа данных timestamp языка Transact-SQL. Тип данных временной метки ODBC и OLE DB сохраняет сведения о дате и времени. Тип данных Transact-SQLtimestamp — это двоичный тип данных, не использующий значения, зависящие от времени.

Преобразование типов date, time, datetime2 и datetimeoffset

Существует два вида преобразования данных между разными типами даты: явный и скрытый. Скрытое преобразование выполняется без помощи функций CAST и CONVERT. Явное преобразование выполняется с помощью функций CAST и CONVERT.

Преобразование между строковыми литералами и типами time(n), date, datetime2(n) и datetimeoffset(n)

Преобразование строковых литералов в типы данных даты и времени разрешается, если все части строк записаны в допустимом формате. Иначе возникает ошибка времени выполнения.

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

Для скрытого преобразования типов данных date, time, datetime2 и datetimeoffset в символьные строки будет использован стандартный формат SQL ГГГ-ММ-ДД чч:мм:сс.[nnnnnnn] со стилем 121 функции CONVERT. Стиль функции CONVERT 0 с форматом мес дд гггг чч:ммAM (или PM) применяется для типов данных datetime и smalldatetime.

В следующей таблице приводятся правила преобразования типов данных date, time, datetime2 и datetimeoffset в строковые литералы и обратно.

Строковый литерал входа

date

time(n)

datetime2(n)

datetimeoffset(n)

ODBC DATE

См. примечание 1.

См. примечание 1.

См. примечание 1.

См. примечание 1.

ODBC TIME

См. примечание 1.

См. примечание 1.

См. примечание 1.

См. примечание 1.

ODBC DATETIME

См. примечание 1.

См. примечание 1.

См. примечание 1.

См. примечание 1.

только DATE

Простейший

Указаны значения по умолчанию

Компонент TIME по умолчанию имеет значение 00:00:00.

Компонент TIME по умолчанию имеет значение 00:00:00. TIMEZONE по умолчанию имеет значение +00:00.

только TIME

Указаны значения по умолчанию

Простейший

Компонент DATE по умолчанию имеет значение 1900-1-1.

Компонент DATE по умолчанию имеет значение 1900-1-1. TIMEZONE по умолчанию имеет значение +00:00.

только TIMEZONE

Указаны значения по умолчанию

Указаны значения по умолчанию

Указаны значения по умолчанию

Указаны значения по умолчанию

DATE + TIME

Используется компонент DATE входной строки.

Используется компонент TIME входной строки.

Простейший

Компонент TIMEZONE по умолчанию имеет значение +00:00.

DATE + TIMEZONE

Запрещены

Запрещены

Запрещены

Запрещены

TIME + TIMEZONE

Указаны значения по умолчанию

Используется компонент TIME входной строки.

Компонент DATE по умолчанию имеет значение 1900-1-1. Входное значение TIMEZONE не учитывается.

Компонент DATE по умолчанию имеет значение 1900-1-1.

DATE + TIME + TIMEZONE

Используется компонент DATE локального значения DATETIME.

Используется компонент TIME локального значения DATETIME.

Используется локальный компонент DATETIME.

Простейший

Примечания касательно преобразований

  1. Строковые литералы ODBC сопоставляются с типом данных datetime. Любая операция назначения от литералов ODBC DATETIME к типам данных date, time, datetime2 или datetimeoffse вызовет скрытое преобразование между типом datetime и вышеупомянутыми типами. Это преобразование пройдет согласно правилам преобразования.

  2. Точность в долях секунды типа datetime составляет три сотые доли секунды (эквивалент 3.33 миллисекунд или 0.00333 секунд). Значения округляются в большую сторону до 0,000, 0,003 или 0,007 долей секунд. «08/22/1995 10:15:19:999» округляется, поскольку значение «.999'» превышает точность.

  3. Для типов данных time(3), datetime2(3) или datetimeoffset(3) точность в долях секунды составляет одну миллисекунду. Следовательно значение «1995-8-22 10:15:19:999» не будет округляться.

  4. Компонент смещения входного значения TIMEZONE всегда должен иметь по две цифры для часов и минут. Знак + или – является обязательным.

Преобразование между типами данных даты и времени

В таблицах в этом разделе описаны способы преобразования следующих типов данных даты и времени в другие типы данных даты и времени:

  • date

  • time(n)

  • datetime

  • smalldatetime

  • datetimeoffset(n)

  • datetime2

Тип данных date

В следующей таблице описано, каким образом тип данных date преобразуется в другие типы даты и времени.

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

time(n)

Преобразование завершается ошибкой 206: «Конфликт типов операндов: тип date несовместим с типом time».

datetime

Дата копируется. Следующий код демонстрирует результаты преобразования значения date в значение datetime.

DECLARE @date date
DECLARE @datetime datetime
SELECT @date = '12-10-25'
SELECT @datetime = @date
SELECT @date AS '@date', @datetime AS '@datetime'
--Result
--@date      @datetime
------------ -----------------------
--2025-12-10 2025-12-10 00:00:00.000
--
--(1 row(s) affected)

smalldatetime

Если значение типа date находится в диапазоне значений smalldatetime, компонент даты копируется, а для компонента времени устанавливается значение 00:00:00.000. Если значение date выходит за диапазон значений smalldatetime, выводится сообщение об ошибке 242: «Преобразование типа данных date в тип данных smalldatetime привело к появлению значения, выходящего за диапазон допустимых значений». После этого для значения типа smalldatetime устанавливается значение NULL.

Следующий код демонстрирует результаты преобразования значения date в значение smalldatetime.

DECLARE @date date
DECLARE @smalldatetime smalldatetime
SELECT @date = '1912-10-25'
SELECT @smalldatetime = @date
SELECT @date AS '@date', @smalldatetime AS '@smalldatetime'
--Result
--@date      @smalldatetime
------------ -----------------------
--1912-10-25 1912-10-25 00:00:00
--
--(1 row(s) affected)

datetimeoffset(n)

Дата копируется, для времени устанавливается значение 00:00.0000000 +00:00.

Следующий код демонстрирует результаты преобразования значения date в значение datetimeoffset(3).

DECLARE @date date
DECLARE @datetimeoffset datetimeoffset(3)
SELECT @date = '1912-10-25'
SELECT @datetimeoffset = @date
SELECT @date AS '@date', @datetimeoffset AS '@datetimeoffset'
--Result
--@date      @datetimeoffset
------------ ------------------------------
--1912-10-25 1912-10-25 00:00:00.000 +00:00
--
--(1 row(s) affected)

datetime2(n)

Компонент даты копируется, для компонента времени устанавливается значение 00:00.000000.

Следующий код демонстрирует результаты преобразования значения date в значение datetime2(3).

DECLARE @date date
DECLARE @datetime2 datetime2(3)
SELECT @date = '1912-10-25'
SELECT @datetime2 = @date
SELECT @date AS '@date', @datetime2 AS '@datetime2(3)'
--Result
--@date      @datetime2(3)
------------ -----------------------
--1912-10-25 1912-10-25 00:00:00.000
--
--(1 row(s) affected)

Тип данных time(n)

В следующей таблице описано, каким образом тип данных time преобразуется в другие типы даты и времени.

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

time(n)

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

Следующий пример демонстрирует результаты преобразования значения time(4) в значение time(3).

DECLARE @timeTo time(3)
DECLARE @timeFrom time(4)
SELECT @timeFrom = '12:34:54.1234'
SELECT @timeTo = @TimeFrom
SELECT @timeTo AS 'time(3)', @timeFrom AS 'time(4)'
--Results
--time(3)      time(4)
-------------- -------------
--12:34:54.123 12:34:54.1234
--
--(1 row(s) affected)

date

Преобразование завершается ошибкой 206: «Конфликт типов операндов: тип date несовместим с типом time».

datetime

Значения часов, минут и секунд копируются; для компонента даты устанавливается значение «1900-01-01». Если точность в долях секунды значения типа time(n) больше трех цифр, результат типа datetime будет усечен.

Следующий код демонстрирует результаты преобразования значения time(4) в значение datetime.

DECLARE @time time(4)
DECLARE @datetime datetime
SELECT @time = '12:15:04.1234'
SELECT @datetime = @time
SELECT @time AS '@time', @datetime AS '@datetime'
--Result
--@time         @datetime
--------------- -----------------------
--12:15:04.1234 1900-01-01 12:15:04.123
--
--(1 row(s) affected)

smalldatetime

Значения часов и минут копируются; для даты устанавливается значение «1900-01-01». Секунды и доли секунд устанавливаются в значение 0.

Следующий код демонстрирует результаты преобразования значения time(4) в значение smalldatetime.

DECLARE @time time(4)
DECLARE @smalldatetime smalldatetime
SELECT @time = '12:15:04.1234'
SELECT @smalldatetime = @time
SELECT @time AS '@time', @smalldatetime AS '@smalldatetime'
--Result
--@time         @smalldatetime
--------------- -----------------------
--12:15:04.1234 1900-01-01 12:15:00
--
--(1 row(s) affected)

datetimeoffset(n)

Время копируется; для даты устанавливается значение «1900-01-01». Для смещения часового пояса устанавливается значение +00:00. Если точность в долях секунды значения типа time(n) больше, чем точность значения типа datetimeoffset(n), значение усекается.

В следующем примере демонстрируются результаты преобразования значения типа time(4) в тип datetimeoffset(3).

DECLARE @time time(4)
DECLARE @datetimeoffset datetimeoffset(3)
SELECT @time = '12:15:04.1234'
SELECT @datetimeoffset = @time
SELECT @time AS '@time', @datetimeoffset AS '@datetimeoffset'
--Result
--@time         @datetimeoffset
--------------- ------------------------------
--12:15:04.1234 1900-01-01 12:15:04.123 +00:00
--
--(1 row(s) affected)

datetime2(n)

Для даты устанавливается значение «1900-01-01»; компонент времени копируется; для смещения часового пояса устанавливается значение 00:00. Если точность в долях секунды значения типа datetime2(n) больше, чем точность значения типа time(n), значение усекается.

Следующий пример демонстрирует результаты преобразования значения time(4) в значение datetime2(2).

DECLARE @time time(4)
DECLARE @datetime2 datetime2(3)
SELECT @time = '12:15:04.1234'
SELECT @datetime2 = @time
SELECT @datetime2 AS '@datetime2', @time AS '@time'
--Result
--@datetime2              @time
------------------------- -------------
--1900-01-01 12:15:04.123 12:15:04.1234
--
--(1 row(s) affected)

Тип данных datetime

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

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

date

Копируется год, месяц и время. Для компонента времени устанавливается значение 00:00:00.000.

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

DECLARE @date date
DECLARE @datetime datetime
SELECT @date = '12-21-05'
SELECT @datetime = @date
SELECT @datetime AS '@datetime', @date AS '@date'
--Result
--@datetime               @date
------------------------- ----------
--2005-12-21 00:00:00.000 2005-12-21

time(n)

Компонент времени копируется, для компонента даты устанавливается значение «1900-01-01». Если точность в долях секунды значения time(n) больше трех цифр, значение будет усечено.

Следующий пример демонстрирует результаты преобразования значения time(4) в значение datetime.

DECLARE @time time(4)
DECLARE @datetime datetime
SELECT @time = '12:10:05.1234'
SELECT @datetime = @time
SELECT @datetime AS '@datetime', @time AS '@time'
--Result
--@datetime               @time
------------------------- -------------
--1900-01-01 12:10:05.123 12:10:05.1234
--
--(1 row(s) affected)

smalldatetime

Копируются часы и минуты. Секунды и доли секунд устанавливаются в значение 0.

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

DECLARE @smalldatetime smalldatetime
DECLARE @datetime datetime
SELECT @smalldatetime = '12-01-01 12:32'
SELECT @datetime = @smalldatetime
SELECT @datetime AS '@datetime', @smalldatetime AS '@smalldatetime'
--Result
--@datetime               @smalldatetime
------------------------- -----------------------
--2001-12-01 12:32:00.000 2001-12-01 12:32:00
--
--(1 row(s) affected)

datetimeoffset(n)

Копируются компоненты даты и времени. Часовой пояс усекается. Если точность в долях секунд для значения datetimeoffset(n) превышает три разряда, значение будет усечено.

Следующий пример демонстрирует результаты преобразования значения datetimeoffset(4) в значение datetime.

DECLARE @datetimeoffset datetimeoffset(4)
DECLARE @datetime datetime
SELECT @datetimeoffset = '1968-10-23 12:45:37.1234 +10:0'
SELECT @datetime = @datetimeoffset
SELECT @datetime AS '@datetime', @datetimeoffset AS '@datetimeoffset'
--Result
--@datetime               @datetimeoffset
------------------------- ------------------------------
--1968-10-23 12:45:37.123 1968-10-23 12:45:37.1234 +01:0
--
--(1 row(s) affected)

datetime2(n)

Копируются компоненты даты и времени. Если точность в долях секунд для значения datetime2(n) превышает три разряда, значение будет усечено.

Следующий пример демонстрирует результаты преобразования значения datetime2(4) в значение datetime.

DECLARE @datetime2 datetime2(4)
DECLARE @datetime datetime
SELECT @datetime2 = '1968-10-23 12:45:37.1237'
SELECT @datetime = @datetime2
SELECT @datetime AS '@datetime', @datetime2 AS '@datetime2'
--Result
--@datetime               @datetime2
------------------------- ------------------------
--1968-10-23 12:45:37.123 1968-10-23 12:45:37.1237
--
--(1 row(s) affected)

Тип данных smalldatetime

В следующей таблице описано, каким образом тип данных smalldatetime преобразуется в другие типы даты и времени.

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

date

Год, месяц и день копируются.

Следующий код демонстрирует результаты преобразования значения smalldatetime в значение date.

DECLARE @smalldatetime smalldatetime
DECLARE @date date
SELECT @smalldatetime = '1955-12-13 12:43:10'
SELECT @date = @smalldatetime
SELECT @smalldatetime AS '@smalldatetime', @date AS 'date'
--Result
--@smalldatetime          date
------------------------- ----------
--1955-12-13 12:43:00     1955-12-13
--
--(1 row(s) affected)

time(n)

Копируются часы, минуты и секунды. Доли секунды устанавливаются в значение 0.

Следующий код демонстрирует результаты преобразования значения smalldatetime в значение time(4).

DECLARE @smalldatetime smalldatetime
DECLARE @time time(4)
SELECT @smalldatetime = '1955-12-13 12:43:10'
SELECT @time = @smalldatetime
SELECT @smalldatetime AS '@smalldatetime', @time AS 'time'
--Result
--@smalldatetime          time
------------------------- -------------
--1955-12-13 12:43:00     12:43:00.0000
--
--(1 row(s) affected)

datetime

Значение smalldatetime копируется из значения datetime. Доли секунды устанавливаются в значение 0.

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

DECLARE @smalldatetime smalldatetime
DECLARE @datetime datetime
SELECT @smalldatetime = '1955-12-13 12:43:10'
SELECT @datetime = @smalldatetime
SELECT @smalldatetime AS '@smalldatetime', @datetime AS 'datetime'
--Result
--@smalldatetime          datetime
------------------------- -----------------------
--1955-12-13 12:43:00     1955-12-13 12:43:00.000
--
--(1 row(s) affected)

datetimeoffset(n)

Значение smalldatetime копируется из значения datetimeoffset(n). Для долей секунды устанавливается значение 0; для смещения часового пояса устанавливается значение +00:0.

Следующий код демонстрирует результаты преобразования значения smalldatetime в значение datetimeoffset(4).

DECLARE @smalldatetime smalldatetime
DECLARE @datetimeoffset datetimeoffset(4)
SELECT @smalldatetime = '1955-12-13 12:43:10'
SELECT @datetimeoffset = @smalldatetime
SELECT @smalldatetime AS '@smalldatetime', @datetimeoffset AS 'datetimeoffset(4)'
--Result
--@smalldatetime          datetimeoffset(4)
------------------------- ------------------------------
--1955-12-13 12:43:00     1955-12-13 12:43:00.0000 +00:0
--
--(1 row(s) affected)

datetime2(n)

Значение smalldatetime копируется из значения datetime2(n). Доли секунды устанавливаются в значение 0.

Следующий код демонстрирует результаты преобразования значения smalldatetime в значение datetime2(4).

DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2(4)
SELECT @smalldatetime = '1955-12-13 12:43:10'
SELECT @datetime2 = @smalldatetime
SELECT @smalldatetime AS '@smalldatetime', @datetime2 AS ' datetime2(4)'
--Result
--@smalldatetime           datetime2(4)
------------------------- ------------------------
--1955-12-13 12:43:00     1955-12-13 12:43:00.0000
--
--(1 row(s) affected)

Тип данных datetimeoffset(n)

В следующей таблице описано, каким образом тип данных datetimeoffset(n) преобразуется в другие типы даты и времени.

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

date

Год, месяц и день копируются.

Следующий код демонстрирует результаты преобразования значения datetimeoffset(4) в значение date.

DECLARE @datetimeoffset datetimeoffset(4)
DECLARE @date date
SELECT @datetimeoffset = '12-10-25 12:32:10 +01:0'
SELECT @date = @datetimeoffset
SELECT @datetimeoffset AS '@datetimeoffset ', @date AS 'date'
--Result
--@datetimeoffset                date
-------------------------------- ----------
--2025-12-10 12:32:10.0000 +01:0 2025-12-10
--
--(1 row(s) affected)

time(n)

Часы, минуты, секунды и доли секунды копируются. Значение часового пояса усекается. Если точность значения типа datetimeoffset(n) больше точности значения типа time(n), оно усекается.

Следующий код демонстрирует результаты преобразования значения datetimeoffset(4) в значение time(3).

DECLARE @datetimeoffset datetimeoffset(4)
DECLARE @time time(3)
SELECT @datetimeoffset = '12-10-25 12:32:10.1234 +01:0'
SELECT @time = @datetimeoffset
SELECT @datetimeoffset AS '@datetimeoffset ', @time AS 'time'
--Result
--@datetimeoffset                time
-------------------------------- ------------
--2025-12-10 12:32:10.1234 +01:0 12:32:10.123
--
--(1 row(s) affected)

datetime

Значения даты и времени копируются; часовой пояс усекается. Если точность в долях секунды для значения datetimeoffset(n) превышает три разряда, значение будет усечено.

Следующий код демонстрирует результаты преобразования значения datetimeoffset(4) в значение datetime.

DECLARE @datetimeoffset datetimeoffset(4)
DECLARE @datetime datetime
SELECT @datetimeoffset = '12-10-25 12:32:10.1234 +01:0'
SELECT @datetime = @datetimeoffset
SELECT @datetimeoffset AS '@datetimeoffset ', @datetime AS 'datetime'
--Result
--@datetimeoffset                datetime
-------------------------------- -----------------------
--2025-12-10 12:32:10.1234 +01:0 2025-12-10 12:32:10.123
--
--(1 row(s) affected)

smalldatetime

Дата, часы и минуты копируются. Секунды устанавливаются в значение 0.

Следующий код демонстрирует результаты преобразования значения datetimeoffset(3) в значение smalldatetime.

DECLARE @datetimeoffset datetimeoffset(3)
DECLARE @smalldatetime smalldatetime
SELECT @datetimeoffset = '1912-10-25 12:24:32 +10:0'
SELECT @smalldatetime = @datetimeoffset
SELECT @datetimeoffset AS '@datetimeoffset', @smalldatetime AS '@smalldatetime'
--Result
--@datetimeoffset                @smalldatetime
-------------------------------- -----------------------
--1912-10-25 12:24:32.000 +10:00 1912-10-25 12:25:00
--
--(1 row(s) affected)

datetime2(n)

Значения даты и времени копируются в значение типа datetime2; часовой пояс усекается. Если точность значения типа datetime2(n) больше точности значения типа datetimeoffset(n), доли секунды усекаются.

Следующий код демонстрирует результаты преобразования значения типа datetimeoffset(4) в значение типа datetime2(3).

DECLARE @datetimeoffset datetimeoffset(4)
DECLARE @datetime2 datetime2(3)
SELECT @datetimeoffset = '1912-10-25 12:24:32.1234 +10:0'
SELECT @datetime2 = @datetimeoffset
SELECT @datetimeoffset AS '@datetimeoffset', @datetime2 AS '@datetime2'
--Result
--@datetimeoffset                @datetime2
-------------------------------- -----------------------
--1912-10-25 12:24:32.1234 +10:0 1912-10-25 12:24:32.123
--
--(1 row(s) affected)

Тип данных datetime2

В следующей таблице описано, каким образом тип данных datetime2 преобразуется в другие типы даты и времени.

Тип данных, в который выполняется преобразование

Дополнительные сведения о преобразовании

date

Год, месяц и день копируются.

Следующий код демонстрирует результаты преобразования значения datetime2(4) в значение date.

DECLARE @datetime2 datetime2(4)
DECLARE @date date
SELECT @datetime2 = '12-10-25 12:32:10.1234'
SELECT @date = @datetime2
SELECT @datetime2 AS '@datetime2', @date AS 'date'
--Result
--@datetime2               date
-------------------------- ----------
--2025-12-10 12:32:10.1234 2025-12-10
--
--(1 row(s) affected)

time(n)

Часы, минуты, секунды и доли секунды копируются.

Следующий код демонстрирует результаты преобразования значения datetime2(4) в значение time(3).

DECLARE @datetime2 datetime2(4)
DECLARE @time time(3)
SELECT @datetime2 = '12-10-25 12:32:10.1234'
SELECT @time = @datetime2
SELECT @datetime2 AS '@datetime2', @time AS 'time(3)'
--Result
--@datetime2                time(3) 
-------------------------- ------------
--2025-12-10 12:32:10.1234 12:32:10.123
--
--(1 row(s) affected)

datetime

Копируются компоненты даты и времени. Если точность в долях секунды для значения datetimeoffset(n) превышает три разряда, значение будет усечено.

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

DECLARE @datetime2 datetime2
DECLARE @datetime datetime
SELECT @datetime2 = '12-10-25 12:32:10.1234567'
SELECT @datetime = @datetime2
SELECT @datetime2 AS '@datetime2', @datetime AS '@datetime'
--Result
--@datetime2                  @datetime
----------------------------- -----------------------
--2025-12-10 12:32:10.1234567 2025-12-10 12:32:10.123
--
--(1 row(s) affected)

smalldatetime

Дата, часы и минуты копируются. Секунды устанавливаются в значение 0.

Следующий код демонстрирует результаты преобразования значения datetime2 в значение smalldatetime.

DECLARE @datetime2 datetime2
DECLARE @smalldatetime smalldatetime
SELECT @datetime2 = '12-10-25 12:32:10.1234567'
SELECT @smalldatetime = @datetime2
SELECT @datetime2 AS '@datetime2', @smalldatetime AS '@smalldatetime'
--Result
--@datetime2                  @datetime
----------------------------- -----------------------
--2025-12-10 12:32:10.1234567 2025-12-10 12:32:10.123
--
--(1 row(s) affected)

datetimeoffset(n)

Значение datetime2(n) копируется из значения datetimeoffset(n). Для смещения часового пояса устанавливается значение +00:0. Если точность значения типа datetime2(n) больше, чем точность значения типа datetimeoffset(n), значение усекается.

Следующий код демонстрирует результаты преобразования значения datetime2(5) в значение datetimeoffset(3).

DECLARE @datetime2 datetime2(3)
DECLARE @datetimeoffset datetimeoffset(2)
SELECT @datetime2 = '12-10-25 12:32:10.1234567'
SELECT @datetimeoffset = @datetime2
SELECT @datetime2 AS '@datetime2', @datetimeoffset AS '@datetimeoffset(2)'
--Result
--@datetime2              @datetimeoffset(2)
------------------------- -----------------------------
--2025-12-10 12:32:10.123 2025-12-10 12:32:10.12 +00:00
--
--(1 row(s) affected)

Использование операций CAST и CONVERT с типами time, date, datetime2 и datetimeoffset

В следующем разделе приводятся сведения о преобразованиях между типами данных даты и времени.

Преобразование в тип datetimeoffset

  • В случае, если значение без компонента часового пояса необходимо преобразовать в тип datetimeoffset с компонентом временного пояса (например при обычной операции назначения), значение без часового пояса считается локальным и из него вычитается текущее смещение по умолчанию для временного пояса (00:00), чтобы получить значение UTC.
  1. При преобразовании типов данных без часового пояса в тип данных datetimeoffset для следующих преобразований всегда осуществляется добавление значения часового пояса UTC (00:00).
  • date в datetimeoffset

  • time в datetimeoffset

  • datetime2 в datetimeoffset

  • datetime или smalldatetime в datetimeoffset

  • Строковые литералы в допустимых форматах date, time или datetime и без часовых поясов в datetimeoffset

Преобразование из типа datetimeoffset

При преобразовании данных из типа datetimeoffset в следующие типы без часовых поясов, стиль 0 (установленный по умолчанию) указывает, что возвращаемое значение date, time, datetime2, datetime или smalltime будет в локальном формате сохраненного значения смещения часового пояса. Стиль 1 всегда указывает формат UTC.

Если в результате следующих скрытых преобразований должно получиться значение без часового пояса, то значение datetimeoffset обрабатывается как значение в формате UTC. Для получения локального времени к значению добавляется сохраненное значение смещения часового пояса. В результате получается значение локального времени без смещения часового пояса.

  • datetimeoffset в date

  • datetimeoffset в time

  • datetimeoffset в datetime2

  • datetimeoffset в datetime или в smalldatetime

  • Стили 0 и 1 не могут быть использованы для преобразования значений datetimeoffset в строчные значения. Чтобы сделать это, необходимо сначала преобразовать значения datetimeoffset в datetime2 или datetime, а уже затем преобразовать их в varchar или char.

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

Все существующие стили даты и времени будут применяться к любым преобразованиям из типа datetimeoffset в строковый тип; смещение часового пояса будет сохранено.

Входная строка для компонента смещения часового пояса всегда должна иметь по две цифры для часов и минут. Знак + или – является обязательным.

Данные, удаляющиеся при преобразовании

  • При преобразовании типов datetime2 или datetimeoffset в тип date не производится никакого округления и компонент даты извлекается явно. Для типа datetimeoffset извлечение происходит по локальному значению даты и времени, а не по значению UTC.

  • Для любых скрытых преобразований из типа datetimeoffset в типы date, time, datetime2, datetime или smalldatetime преобразование опирается на локальное значение даты и времени (для постоянного смещения часового пояса). Например, при преобразовании значения «2006-10-21 12:20:20.999 -8:00» из типа данных datetimeoffset(3) в тип time(3) в результате получится значение «12:20:20.999», а не «20:20:20.999(UTC)».

Усечение при преобразовании

  • Разрешается преобразование значений с высокой степенью точности в значения с меньшей степенью точности. Значения с более высокой точностью будут усечены, чтобы соответствовать типу с более низкой точностью.

Преобразование долей секунды

Если стиль включает формат времени «чч:мм:сс.mmm», то он станет «чч:мм:сс.[nnnnnnn]» для типов time(n), datetime2(n) и datetimeoffset(n). Число цифр зависит от спецификации типа. Если необходима точность только до миллисекунд, то следует сначала выполнить преобразование в datetime2(3), а затем в строковый тип.

Для стилей 9, 109, 13, 113, 21, 121, 130 и 131 при преобразовании из типов time, datetime2 и datetimeoffset в строковый тип не поддерживается разделитель двоеточие (:), которое предшествует значению долей секунды. Формат выходной строки с любым из этих стилей будет преобразован в точку (.).

Аргументы стиля для функции CONVERT

В следующей таблице приводятся примеры значений типов date, time, datetime2 и datetimeoffset для аргументов стиля для функции CONVERT. Дополнительные сведения о стиле см. в подразделе «Аргументы» раздела Функции CAST и CONVERT (Transact-SQL).

Стиль

Associated standard

Input/Output (3)

format

date

time(n)

datetime2(n)

datetimeoffset(n)

0 или 100 (1,2)

По умолчанию

мес дд гггг чч:ммAM (или PM)

Янв 1 2001

12:20PM

Янв 1 2001 12:20PM

Янв 1 2001 12:20PM -08:00

101

США

мм/дд/гггг

01/01/2001

-

01/01/2001

01/01/2001

102

ANSI

гг.мм.дд

2001.01.01

-

2001.01.01

2001.01.01

103

Британский/французский

дд/мм/гг

01/01/2001

-

01/01/2001

01/01/2001

104

Немецкий

дд.мм.гг

01.01.2001

-

01.01.2001

01.01.2001

105

Итальянский

дд-мм-гг

01-01-2001

-

01-01-2001

01-01-2001

106(1)

-

дд мес гг

01 Янв 2001

-

01 Янв 2001

01 Янв 2001

107(1)

-

Мес дд, гг

Янв 01, 2001

-

Янв 01, 2001

Янв 01, 2001

108

-

чч:мм:сс

-

12:20:20

12:20:20

12:20:20

9 или 109 (1,2)

По умолчанию + миллисекунды

мес дд гггг чч:ми:сс:мммAM (или PM)

Янв 1 2001

12:20:20.1234567AM

Янв 1 2001 12:20:20.1234567PM

Янв 1 2001 12:20:20:1230000PM -08:00

110

США

мм-дд-гг

01-01-2001

-

01-01-2001

01-01-2001

111

Японский

гг/мм/дд

2001/01/01

-

2001/01/01

2001/01/01

112

ISO

ггммдд

20010101

-

20010101

20010101

13 или 113 (1,2)

Европейский по умолчанию + миллисекунды

дд мес гггг чч:мм:сс:ммм (24-часовой формат)

01 Янв 2001

12:20:20.1234567

01 Янв 2001 12:20:20.1234567

01 Янв 2001 12:20:20:1230000 -08:00

114

-

чч:ми:сс:ммм (24-часовой формат)

-

12:20:20.1234567

12:20:20.1234567

12:20:20:1230000 -08:00

20 или 120 (2)

Канонический формат ODBC

гггг-мм-дд чч:ми:сс (24-часовой формат)

2001-01-01

12:20:20

2001-01-01 12:20:20

2001-01-01 12:20:20 -08:00

21 или 121 (2)

Канонический формат ODBC (с миллисекундами)

гггг-мм-дд чч:ми:сс.ммм (24-часовой формат)

2001-01-01

12:20:20.1234567

2001-01-01 12:20:20.1234567

2001-01-01 12:20:20.1230000 -08:00

126 (4)

ISO8601.

гггг-мм-ддТчч:мм:сс.ммм (без пробелов)

2001-01-01

12:20:20.1234567

2001-01-01T 12:20:20.1234567

2001-01-01T 12:20:20.1234567

127(6, 7)

ISO8601 с часовым поясом П.

гггг-мм-ддТчч:мм:сс.мммП

(без пробелов)

2001-01-01

12:20:20.1234567П

2001-01-01T 12:20:20.1234567П

2001-01-01T20:20:20.1230000П

130 (1,2)

Хиджра (5)

дд мес гггг чч:ми:сс:мммAM (или PM)

01 Янв 2001

12:20:20.1230000PM

01 Янв 2001 12:20:20.1230000PM

1 Янв 2001 12:20:20:1230000PM -08:00

131 (2)

Хиджра (5)

дд/мм/гг чч:ми:сс:мммAM (или PM)

01/01/2001

12:20:20.1230000PM

01/01/2001 12:20:20.1230000PM

01/01/2001 12:20:20.1230000PM -08:00

1  Эти значения стилей возвращают недетерминированные результаты. Включают в себя все стили «гг» (без обозначения века) и часть стилей «гггг» (с обозначением века).

2 Значения по умолчанию (style0 или 100, 9 или 109, 13 или 113, 20 или 120 и 21 или 121) всегда возвращают год с веком (гггг).

3.  Вход при преобразовании в тип datetime; выход при преобразовании в символьные данные.

4.  Для использования в формате XML. Для преобразования из datetime или smalldatetime в символьные данные формат вывода должен быть таким как это описано в предыдущей таблице.

5 Хиджра — календарная система с несколькими вариантами. В SQL Server используется кувейтский алгоритм.

6 Поддерживается только при приведении символьных данных к типу datetime или smalldatetime. При приведении символьных данных, представляющих только дату или только время, к типам datetime и smalldatetime неуказанное время устанавливается в 00:00:00.000, а неуказанная дата — в 1900-01-01.

7 Необязательный признак часового пояса П используется для упрощения сопоставления XML-значений типа datetime, содержащих сведения о часовом поясе, со значениями SQL Server типа datetime без таких сведений. П — это индикатор часового пояса UTC-0.

Ограничения даты и времени в SQL Server

В следующем списке дата и время — это любой тип данных даты-времени, который включает компонент даты или времени.

  • Для типа datetimeoffset на стороне сервера не поддерживается переход на летнее время.

  • Для даты не поддерживается юлианский календарь.

  • Для времени не поддерживается представление полуночи как «24» часа.

  • Для времени не поддерживаются значения «корректировочной секунды» больше «59».

  • Для времени не поддерживаются значения «одна наносекунда» и более точные для точности в долях секунды.

  • В часовом поясе не поддерживается время.

  • Не поддерживается операция INTERVAL по стандарту SQL.

Обратная совместимость для клиентов нижнего уровня

Некоторые клиенты низкого уровня не поддерживают типы данных time, date, datetime2 и datetimeoffset, добавленные в SQL Server 2008. В следующей таблице показывается сопоставление типов экземпляра более высокого уровня SQL Server 2008 и клиентов низкого уровня.

Тип данных SQL Server 2008

Формат строкового литерала по умолчанию, передаваемый клиенту низкого уровня

ODBC низкого уровня

OLEDB низкого уровня

JDBC низкого уровня

SQLCLIENT низкого уровня

time

чч:мм:сс[.ннннннн]

SQL_WVARCHAR или SQL_VARCHAR

DBTYPE_WSTR или DBTYPE_STR

Java.sql.String

String или SqString

date

ГГГГ-ММ-ДД

SQL_WVARCHAR или SQL_VARCHAR

DBTYPE_WSTR или DBTYPE_STR

Java.sql.String

String или SqString

datetime2

ГГГГ-ММ-ДД чч:мм:сс[.ннннннн]

SQL_WVARCHAR или SQL_VARCHAR

DBTYPE_WSTR или DBTYPE_STR

Java.sql.String

String или SqString

datetimeoffset

ГГГГ-ММ-ДД чч:мм:сс[.ннннннн] [+|-]чч:мм

SQL_WVARCHAR или SQL_VARCHAR

DBTYPE_WSTR или DBTYPE_STR

Java.sql.String

String или SqString

Примеры

А. Сравнение типов данных даты и времени

В следующем примере сравниваются результаты приведения типа строкового литерала к каждому из типов данных даты и времени. При попытке приведения (с помощью функции CAST) строкового литерала с точностью до долей секунды, которая больше разрешенной для типов smalldatetime и datetime, возникнет ошибка.

SELECT 
     CAST('2007-05-08 12:35:29. 1234567 +12:15' AS time(7)) AS 'time' 
    ,CAST('2007-05-08 12:35:29. 1234567 +12:15' AS date) AS 'date' 
    ,CAST('2007-05-08 12:35:29.123' AS smalldatetime) AS 
        'smalldatetime' 
    ,CAST('2007-05-08 12:35:29.123' AS datetime) AS 'datetime' 
    ,CAST('2007-05-08 12:35:29. 1234567 +12:15' AS datetime2(7)) AS 
        'datetime2'
    ,CAST('2007-05-08 12:35:29.1234567 +12:15' AS datetimeoffset(7)) AS 
        'datetimeoffset';

Тип данных

Output

Time

12:35:29.1234567

Date

2007-05-08

Smalldatetime

2007-05-08 12:35:00

Datetime

2007-05-08 12:35:29.123

datetime2(7)

2007-05-08 12:35:29.1234567

datetimeoffset(7)

2007-05-08 12:35:29.1234567 +12:15

Б. Получение текущей системной даты и времени

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

SELECT SYSDATETIME() AS 'SYSDATETIME'

--Results
--SYSDATETIME
--2007-10-22 14:10:41.7984554
--(1 row(s) affected)

SELECT SYSDATETIMEOFFSET() AS 'SYSDATETIMEOFFSET'

--Results
--SYSDATETIMEOFFSET
--2007-10-22 14:11:34.2607172 -0
--(1 row(s) affected)

SELECT SYSUTCDATETIME() AS 'SYSUTCDATETIME'

--Results
--SYSUTCDATETIME
--2007-10-22 21:12:11.7069470
--(1 row(s) affected)

SELECT CURRENT_TIMESTAMP AS 'CURRENT_TIMESTAMP'

--Results
--CURRENT_TIMESTAMP
-------------------------
--2007-10-22 14:12:33.320
--(1 row(s) affected)

SELECT GETDATE() AS 'GETDATE'

--Results
--GETDATE
--2007-10-22 14:13:57.943
--(1 row(s) affected)

SELECT GETUTCDATE() AS 'GETUTCDATE'

--Results
--GETUTCDATE
--2007-10-22 21:14:35.657
--(1 row(s) affected)

В. Поиск всех значений типа datetime2, приходящихся на один день

  • В следующем примере демонстрируется поиск всех значений даты и времени, приходящихся на один день.
-- Create a table that contains with the following dates:
--     The last date-time in 2005-04-06, '2005-04-06 23:59:59.9999999'
--     The first date-time in 2005-04-07, '2005-04-07 00:00:00.0000000'
--     The last date-time in 2005-04-07, '2005-04-07 23:59:59.9999999'
--     The first date-time in 2005-04-08, '2005-04-08 00:00:00.0000000'
CREATE TABLE #Search
    (
    MyDate datetime2
    );
INSERT INTO #Search(MyDate)VALUES('2005-04-06 23:59:59.9999999');
INSERT INTO #Search(MyDate)VALUES('2005-04-07 00:00:00.0000000');
INSERT INTO #Search(MyDate)VALUES('2005-04-07 23:59:59.9999999');
INSERT INTO #Search(MyDate)VALUES('2005-04-08 00:00:00.0000000');

-- The following four SELECT statements show different ways to find
-- only the two rows that contain 2005-04-07 dates.
--Use CONVERT.
SELECT MyDate 
FROM #Search 
WHERE CONVERT(date,MyDate) = '2005-04-07';

--Use >= and <=.
SELECT MyDate 
FROM #Search 
WHERE MyDate >= '2005-04-07 00:00:00.0000000' 
    AND MyDate <= '2005-04-07 23:59:59.9999999';

--Use > and <.
SELECT MyDate
FROM #Search
WHERE MyDate > '2005-04-06 23:59:59.9999999'
    AND MyDate < '2005-04-08 00:00:00.0000000';

--Use BETWEEN AND.
SELECT MyDate
FROM #Search
WHERE MyDate BETWEEN '2005-04-07 00:00:00.0000000'
    AND '2005-04-07 23:59:59.9999999';
DROP TABLE #Search
GO

Г. Поиск временного периода дня

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

-- Create a table called Search and insert
-- five different time values for the same
-- date.

CREATE TABLE #Search
    (
    MyDate datetime2
    );

INSERT INTO #Search(MyDate)VALUES('2005-04-06 08:59:59.9999999');
INSERT INTO #Search(MyDate)VALUES('2005-04-06 09:00:00.0000000');
INSERT INTO #Search(MyDate)VALUES('2005-04-06 09:00:00.9999999');
INSERT INTO #Search(MyDate)VALUES('2005-04-06 16:59:59.9999999');
INSERT INTO #Search(MyDate)VALUES('2005-04-06 17:00:00.0000000');

-- The following SELECT statements show different ways
-- to search for dates that have time values to find a
-- time range.

--Using CONVERT with time (0) to ignore fractional seconds
SELECT MyDate 
FROM #Search 
WHERE CONVERT(time(0),MyDate) = '09:00:00';

--Returns two rows (ignores fractional seconds):
--2005-04-06 08:59:59.9999999
--2005-04-06 09:00:00.0000000

--Using CONVERT with time (7) to include fractional seconds
SELECT MyDate 
FROM #Search 
WHERE CONVERT(time(7),MyDate) = '09:00:00';

--Returns one row (matches fractional seconds):
--2005-04-06 09:00:00.0000000


--Each of the SELECT statements below use CONVERT
--to find all times in an eight-hour period.

--Use CONVERT with >= and <=.
SELECT MyDate 
FROM #Search 
WHERE CONVERT(time(7),MyDate) >=  '09:00:00.0000000'
    AND CONVERT(time(7),MyDate) <= '16:59:59.9999999'

--Use CONVERT with > and <.
SELECT MyDate
FROM #Search
WHERE CONVERT(time(7),MyDate) > '08:59:59.9999999'
    AND CONVERT(time(7),MyDate) < '17:00:00.0000000';

--Use CONVERT with BETWEEN AND
SELECT MyDate
FROM #Search
WHERE CONVERT(time(7),MyDate) BETWEEN '09:00:00.0000000'
    AND '16:59:59.9999999';
DROP TABLE #Search
GO

Д. Использование функций DATEPART и DATEADD для нахождения первого и последнего дня значения типа datepart

В следующем примере показывается, как можно возвратить первый или последний день значения типа datepart.

-- When several months, quarters, or years are added to the base
-- year,1900-01-01, the returned day is the first day of a month.
-- To calculate the last day of the current month, you need to
--
-- 1. Find the difference in months between today and the base
--    year (0 ='1900-01-01'). This is accomplished by
--
-- DATEDIFF(month, 0, SYSDATETIME())
-- 2. Add that number of months plus 1 to the base year (0)
--    to obtain the first day of the next month.
--    DATEADD(month, DATEDIFF(month, 0, SYSDATETIME()) + 1, 0)
-- 3. Subtract 1 day.
--
--Find the first day of the current month.
SELECT DATEADD(month, DATEDIFF(month, 0, SYSDATETIME()), 0);

--Find the last day of the current month.
SELECT DATEADD(month, DATEDIFF(month, 0, SYSDATETIME()) + 1, 0) - 1;

-- Find the first day of the current quarter.
SELECT DATEADD(quarter, DATEDIFF(quarter, 0, SYSDATETIME()), 0);

-- Find the last day of the current quarter.
SELECT DATEADD(quarter, DATEDIFF(quarter, -1, SYSDATETIME()), -1);

-- Find the first day of the current year.
SELECT DATEADD(year, DATEDIFF(year, 0, SYSDATETIME()), 0);

-- Find the last day of the current year.
SELECT DATEADD(year, DATEDIFF(year, -1, SYSDATETIME()), -1);

Е. Использование определяемых пользователем аргументов типа datepart для функций DATEADD, DATEDIFF, DATENAME и DATEPART

В следующем примере создается скалярная, определяемая пользователем функция, добавляющая константу в любой компонент значения типа datetime2.

USE tempdb
GO
CREATE FUNCTION UserDateadd
    (
    @datepart nvarchar(11)
    ,@number int 
    ,@date datetime2
    )
RETURNS datetime2
AS
BEGIN
    DECLARE @Return datetime2

    SELECT @Return = CASE @datepart
        WHEN 'year' THEN DATEADD(year,@number,@date) 
        WHEN 'yy' THEN DATEADD(year,@number,@date) 
        WHEN 'yyyy' THEN DATEADD(year,@number,@date) 
        WHEN 'quarter' THEN DATEADD(quarter,@number,@date) 
        WHEN 'qq' THEN DATEADD(quarter,@number,@date) 
        WHEN 'month' THEN DATEADD(month,@number,@date) 
        WHEN 'mm' THEN DATEADD(month,@number,@date) 
        WHEN 'm' THEN DATEADD(month,@number,@date) 
        WHEN 'dayofyear' THEN DATEADD(dayofyear,@number,@date) 
        WHEN 'dy' THEN DATEADD(dayofyear,@number,@date) 
        WHEN 'y' THEN DATEADD(dayofyear,@number,@date) 
        WHEN 'day' THEN DATEADD(day,@number,@date) 
        WHEN 'dd' THEN DATEADD(day,@number,@date) 
        WHEN 'd' THEN DATEADD(day,@number,@date) 
        WHEN 'week' THEN DATEADD(week,@number,@date) 
        WHEN 'wk' THEN DATEADD(week,@number,@date) 
        WHEN 'ww' THEN DATEADD(week,@number,@date) 
        WHEN 'weekday' THEN DATEADD(weekday,@number,@date) 
        WHEN 'wk' THEN DATEADD(weekday,@number,@date) 
        WHEN 'w' THEN DATEADD(weekday,@number,@date) 
        WHEN 'hour' THEN DATEADD(hour,@number,@date) 
        WHEN 'hh' THEN DATEADD(hour,@number,@date) 
        WHEN 'minute' THEN DATEADD(minute,@number,@date)
        WHEN 'mi' THEN DATEADD(minute,@number,@date) 
        WHEN 'n' THEN DATEADD(minute,@number,@date)  
        WHEN 'second' THEN DATEADD(second,@number,@date) 
        WHEN 'ss' THEN DATEADD(second,@number,@date)
        WHEN 's' THEN DATEADD(second,@number,@date)
        WHEN 'millisecond' THEN DATEADD(millisecond,@number,@date) 
        WHEN 'ms' THEN DATEADD(millisecond,@number,@date) 
        WHEN 'microsecond' THEN DATEADD(microsecond,@number,@date)
        WHEN 'mcs' THEN DATEADD(microsecond,@number,@date)
        WHEN 'nanosecond' THEN DATEADD(nanosecond,@number,@date)
        WHEN 'ns' THEN DATEADD(nanosecond,@number,@date)
    END
    return @Return
END
GO

SELECT GetDate()
SELECT dbo.UserDateadd('year', 1, GetDate())
GO

Ж. Использование функции DATEPART для группировки по частям даты

В следующем примере используется образец базы данных AdventureWorks. Функция DATEPART используется для группировки общих продаж по дню недели, месяцу, году и по последовательности год/месяц/день недели.

USE AdventureWorks
GO
SELECT SUM(TotalDue) AS 'Total Sales'
    ,DATEPART(year,OrderDate)AS 'By Year'
    ,DATEPART(month,OrderDate) AS 'By Month'
    ,DATEPART(weekday,OrderDate) AS 'By Weekday'
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) IN('2003','2004')
GROUP BY GROUPING SETS 
    (
    (DATEPART(year,OrderDate))
    ,(DATEPART(month,OrderDate))
    ,(DATEPART(weekday,OrderDate))
    ,(
        DATEPART(year,OrderDate)
        ,DATEPART(month,OrderDate),
        DATEPART(weekday,OrderDate))
    )
ORDER BY DATEPART(year,OrderDate)
    ,DATEPART(month,OrderDate)
    ,DATEPART(weekday,OrderDate)