datetime (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)

用于定义一个与采用 24 小时制并带有秒小数部分的一日内时间相组合的日期。

避免对新工作使用 日期/时间 。 请改用时间日期、datetime2datetimeoffset 数据类型。 这些类型与 SQL 标准保持一致,并且更易于移植。 time、datetime2 和 datetimeoffset 提供更高精度的秒数 。 datetimeoffset 为全局部署的应用程序提供时区支持 。

说明

properties
语法 DATETIME
使用情况 DECLARE @MyDatetime DATETIME;
CREATE TABLE Table1 (Column1 DATETIME);
默认字符串文本格式(用于下层客户端) 不适用
日期范围 1753-01-01 (1753 年 1 月 1 日) 到 9999-12-31 (9999 年 12 月 31 日)
时间范围 00:00:00 到 23:59:59.997
时区偏移范围
元素范围 yyyy是表示年份的四位数字17539999

MM 是两个数字,范围从一 0112,表示指定年份中的一个月。

dd是两个数字,范围从到0131取决于月份,表示指定月份的一天。

HH 是表示小时数的两位数字,范围介于 00 1 到 232 位。

mm 是表示分钟数的两位数字,范围从 00 1 到 591。

ss 是两个数字,范围从 00 1 到 59,表示第二个数字。

n* 为零到三位数字,范围从零 0999三,表示小数秒。
字符长度 最低 19 位到最高 23 位
存储大小 8 个字节
准确性 舍入为增量 .000.003.007
默认值 1900-01-01 00:00:00
日历 公历(包括整个年份范围)
用户定义的小数秒精度
时区偏移感知和保留
夏令时感知

datetime 支持的字符串文字格式

以下各表列出了 datetime 支持的字符串文字格式。 除了 ODBC 之外, 日期/时间 字符串文本采用单引号('例如 'string_literaL')。 如果环境不是 us_english,字符串文本应采用 Unicode 格式 N'string_literaL'

数字格式

您可以指定日期数据,其中月份也通过数值指定。 例如, 5/20/97 表示 1997 年 5 月的第 20 天。 使用数字日期格式时,请在使用斜杠标记()、连字符(/-)或句点(.)作为分隔符的字符串中指定月份、日和年。 此字符串必须采用以下格式:

<number separator number separator number [time] [time]>

当语言设置为 us_english时,日期的默认顺序为 mdy (月、日、年)。 可以使用 SET DATEFORMAT 语句更改日期顺序。

用于 SET DATEFORMAT 确定如何解释日期值的设置。 如果顺序不符合设置,这些值不会被解释为日期。 无序日期可能被误解释为超出范围或值错误。 例如, 12/10/08 可以根据设置解释为六个日期 DATEFORMAT 之一。 四位数字的年份被解释为年。

日期格式 下单(O)
[0]4/15/[19]96 mdy
[0]4-15-[19]96 mdy
[0]4.15.[19]96 mdy
[0]4/[19]96/15 myd
15/[0]4/[19]96 dmy
15/[19]96/[0]4 dym
[19]96/15/[0]4 ydm
[19]96/[0]4/15 ymd
时间格式
14:30
14:30[:20:997]
14:30[:20.9]
4am
4 PM

字母格式

您可以指定一个日期数据,其中使用完整的月份名称来指定月份。 例如, April或当前语言中指定的月份缩写 Apr。 逗号是可选的,且忽略大小写。

下面是使用字母日期格式的一些准则:

  • 将日期和时间数据括在单引号 (') 中。 对于英语以外的语言,请使用 N''

  • 括在括号中的字符是可选的。

  • 如果仅指定年份的最后两位数字,则小于两位数年份截止配置选项值的最后两位数的值与截止年份位于同一世纪。 大于或等于该选项值的值处于截止年份的上一个世纪。 例如,如果 两位数年份截止2050 (默认值), 25 则解释为 202550 解释为 1950。 为避免不确定性,请使用四位数年份。

  • 如果没有指定日,则默认为当月第一天。

  • SET DATEFORMAT 按字母顺序指定月份时,不会应用会话设置。

字母
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]

ISO 8601 格式

若要使用 ISO 8601 格式,必须指定格式中的每个元素,包括 T格式中显示的冒号(:)和句点(.)。

方括号表示秒小数部分是可选的。 时间部分按 24 小时制指定。 指示T日期/时间值的时间部分的开始时间。

使用 ISO 8601 格式的优点是它是一个具有明确规范的国际标准。 此外,此格式不受或 SET LANGUAGE 设置的影响SET DATEFORMAT

示例:

  • 2004-05-23T14:25:10
  • 2004-05-23T14:25:10.487
ISO 8601
yyyy-MM-ddTHH:mm:ss[.mmm]
yyyyMMdd[ HH:mm:ss[.mmm]]

未分离的格式

此格式类似于 ISO 8601 格式,但不包含日期分隔符。

未分隔的
yyyyMMdd HH:mm:ss[.mmm]

ODBC 格式

ODBC API 用于定义转义序列以表示日期和时间值,ODBC 称之为时间戳数据。 Microsoft OLE DB provider for SQL Server 所支持的 OLE DB 语言定义 (DBGUID-SQL) 也支持这种 ODBC 时间戳格式。 使用 ADO、OLE DB 和基于 ODBC 的 API 的应用程序可以使用这种 ODBC 时间戳格式来表示日期和时间。

ODBC 时间戳转义序列的格式如下: { <literal_type> '<constant_value>' }

  • <literal_type> 指定转义序列的类型。 时间戳有三 <literal_type> 个说明符:

    • d = 仅日期
    • t = 仅限时间
    • ts = 时间戳 (时间 + 日期)
  • <constant_value> 是转义序列的值。 <constant_value> 必须针对每个 <literal_type>格式遵循以下格式:

    • d: yyyy-MM-dd
    • t: hh:mm:ss[.fff]
    • ts: yyyy-MM-dd HH:mm:ss[.fff]
ODBC
{ ts '1998-05-02 01:23:56.123' }
{ d '1990-10-02' }
{ t '13:33:41' }

datetime 秒的小数部分精度的舍入

datetime 值舍入为增量 .000.003.007 秒,如以下示例所示。

SELECT '01/01/2024 23:59:59.999' AS [User-specified value],
    CAST('01/01/2024 23:59:59.999' AS DATETIME) AS [System stored value]
UNION SELECT '01/01/2024 23:59:59.998', CAST('01/01/2024 23:59:59.998' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.997', CAST('01/01/2024 23:59:59.997' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.996', CAST('01/01/2024 23:59:59.996' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.995', CAST('01/01/2024 23:59:59.995' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.994', CAST('01/01/2024 23:59:59.994' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.993', CAST('01/01/2024 23:59:59.993' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.992', CAST('01/01/2024 23:59:59.992' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.991', CAST('01/01/2024 23:59:59.991' AS DATETIME)
UNION SELECT '01/01/2024 23:59:59.990', CAST('01/01/2024 23:59:59.990' AS DATETIME);

下面是结果集:

用户指定的值 系统存储的值
01/01/2024 23:59:59.999 2024-01-02 00:00:00.000
01/01/2024 23:59:59.998
01/01/2024 23:59:59.997
01/01/2024 23:59:59.996
01/01/2024 23:59:59.995
2024-01-01 23:59:59.997
01/01/2024 23:59:59.994
01/01/2024 23:59:59.993
01/01/2024 23:59:59.992
2024-01-01 23:59:59.993
01/01/2024 23:59:59.991
01/01/2024 23:59:59.990
2024-01-01 23:59:59.990

对 ANSI 和 ISO 8601 的遵从性

datetime 不遵从 ANSI 或 ISO 8601

转换日期和时间数据

转换为日期和时间数据类型时,数据库引擎将拒绝无法识别为日期或时间的所有值。 有关对日期和时间数据使用 CASTCONVERT 函数的信息,请参阅 CAST 和 CONVERT

将其他日期和时间类型转换为 datetime 数据类型

本部分介绍其他日期和时间数据类型转换为 datetime 数据类型时会发生什么

从 date 转换时,会复制年、月和日。 时间组件设置为 00:00:00.000. 下面的代码显示将 DATE 值转换为 DATETIME 值的结果。

DECLARE @date DATE = '12-21-16';
DECLARE @datetime DATETIME = @date;

SELECT @datetime AS '@datetime', @date AS '@date';

下面是结果集:

@datetime                @date
------------------------ -----------
2016-12-21 00:00:00.000  2016-12-21

前面的示例使用区域特定的日期格式(MM-DD-YY)。

DECLARE @date DATE = '12-21-16';

应更新示例以匹配区域的格式。

还可以使用符合 ISO 8601 的日期格式(yyyy-MM-dd)完成示例。 例如:

DECLARE @date DATE = '2016-12-21';
DECLARE @datetime DATETIME = @date;

SELECT @datetime AS '@datetime', @date AS '@date';

当转换从 time(n开始时,将复制时间组件,并将日期组件设置为 1900-01-01。 当 time(n 值的分数精度大于三位数时,该值将被截断以适应。 下面的示例显示了将 TIME(4) 值转换为 DATETIME 值的结果。

DECLARE @time TIME(4) = '12:10:05.1237';
DECLARE @datetime DATETIME = @time;

SELECT @datetime AS '@datetime', @time AS '@time';

下面是结果集:

@datetime                @time
------------------------ --------------
1900-01-01 12:10:05.123  12:10:05.1237

从 smalldatetime 转换时,会复制小时和分钟。 秒和小数秒设置为 0。 下面的代码显示将 SMALLDATETIME 值转换为 DATETIME 值的结果。

DECLARE @smalldatetime SMALLDATETIME = '12-01-16 12:32';
DECLARE @datetime DATETIME = @smalldatetime;

SELECT @datetime AS '@datetime', @smalldatetime AS '@smalldatetime';

下面是结果集:

@datetime                @smalldatetime
------------------------ --------------------
2016-12-01 12:32:00.000  2016-12-01 12:32:00

从 datetimeoffset(n转换时,将复制日期和时间组件。 时区被截断。 当 datetimeoffset(n 值的分数精度大于三位数时,该值将被截断。 下面的示例显示了将 DATETIMEOFFSET(4) 值转换为 DATETIME 值的结果。

DECLARE @datetimeoffset DATETIMEOFFSET(4) = '1968-10-23 12:45:37.1234 +10:0';
DECLARE @datetime DATETIME = @datetimeoffset;

SELECT @datetime AS '@datetime', @datetimeoffset AS '@datetimeoffset';

下面是结果集:

@datetime                @datetimeoffset
------------------------ -------------------------------
1968-10-23 12:45:37.123  1968-10-23 12:45:37.1237 +10:0

当转换从 datetime2(n进行时,将复制日期和时间。 当 datetime2(n 值的分数精度大于三位数时,将截断该值。 下面的示例显示了将 DATETIME2(4) 值转换为 DATETIME 值的结果。

DECLARE @datetime2 DATETIME2(4) = '1968-10-23 12:45:37.1237';
DECLARE @datetime DATETIME = @datetime2;

SELECT @datetime AS '@datetime', @datetime2 AS '@datetime2';

下面是结果集:

@datetime                @datetime2
------------------------ -------------------------
1968-10-23 12:45:37.123  1968-10-23 12:45:37.1237

示例

下例比较了将一个字符串分别转换为各种 date 和 time 数据类型时所产生的结果 。

SELECT CAST('2024-05-08 12:35:29.1234567 +12:15' AS TIME(7)) AS 'time',
    CAST('2024-05-08 12:35:29.1234567 +12:15' AS DATE) AS 'date',
    CAST('2024-05-08 12:35:29.123' AS SMALLDATETIME) AS 'smalldatetime',
    CAST('2024-05-08 12:35:29.123' AS DATETIME) AS 'datetime',
    CAST('2024-05-08 12:35:29.1234567 +12:15' AS DATETIME2(7)) AS 'datetime2',
    CAST('2024-05-08 12:35:29.1234567 +12:15' AS DATETIMEOFFSET(7)) AS 'datetimeoffset';

下面是结果集。

数据类型 输出
time 12:35:29.1234567
date 2024-05-08
smalldatetime 2024-05-08 12:35:00
datetime 2024-05-08 12:35:29.123
datetime2 2024-05-08 12:35:29.1234567
datetimeoffset 2024-05-08 12:35:29.1234567 +12:15