# 第四十五章 SQL函数 DATEPART 日期/时间函数,返回表示日期/时间表达式指定部分的值的整数。 # 大纲 ``` DATEPART(datepart,date-expression) ``` # 参数 - `datepart` - 要返回的日期/时间信息的类型。日期或时间部分的名称(或缩写)。这个名称可以用大写或小写来指定,有或没有引号。`datepart`可以指定为文字或主机变量。 - `date-expression` - 从中返回`datepart`值的日期、时间或时间戳表达式。日期表达式必须包含`datepart`类型的值。 # 描述 `DATEPORT`函数以整数数据类型返回关于指定日期/时间表达式的`DATEPORT`信息。唯一的例外是`sqltimestamp` (sts),它以数据类型`%Library.Timestamp`返回。要以字符串形式返回日期部分信息,请使用`DATENAME`。 `DATEPART`只返回日期表达式中一个元素的值;要返回包含多个日期部分的字符串,请使用`TO_DATE`。 也可以使用`DATEPART()`方法调用从ObjectScript调用此函数: ```sql $SYSTEM.SQL.Functions.DATEPART(datepart,date-expression) ``` 提供`DATEPART`是为了与Sybase和Microsoft SQL Server兼容。 # Datepart 参数 日期部分参数可以是下列日期/时间组件之一,可以是全名(日期部分列)或其缩写(缩写列)。这些`datepart`组件名称和缩写不区分大小写。 Date Part| Abbreviations| Return Values ---|---|--- year| yyyy, yy |0001-9999 quarter| qq, q| 1-4 month| mm, m| 1-12 week| wk, ww| 1-53 weekday |dw| 1-7 (Sunday,...,Saturday) dayofyear| dy, y| 1-366 day |dd, d| 1-31 hour| hh| 0-23 minute |mi, n| 0-59 second| ss, s| 0-59 millisecond |ms |0-999 (with precision of 3) microsecond| mcs |0–999999 (with precision of 6) nanosecond |ns |0–999999999 (with precision of 9) sqltimestamp |sts| SQL_TIMESTAMP: yyyy-mm-dd hh:mm:ss 上表显示了不同日期部分的默认返回值。可以使用带有各种时间和日期选项的“设置选项”命令来修改其中几个日期部分的返回值。 `week`:可以配置为使用默认算法或ISO 8601标准算法来确定给定日期的一年中的星期。 `weekday`:对`weekday`的默认设置是将星期日指定为一周的第一天(`weekday=1`)。但是,可以将一周的第一天配置为另一个值,或者可以应用ISO 8601标准,将星期一指定为一周的第一天。请注意,ObjectScript `$ZDATE`和`$ZDATETIME`函数计算的周天数是从0到6(而不是从1到7)。 `second`:如果日期表达式包含小数秒,将秒作为十进制数返回,整数秒作为整数部分,小数秒作为小数部分。精度不会被截断。 `millisecond`:返回三个小数位数的精度,去掉尾随零。如果日期表达式的精度超过三位数会将其截断为三位数。 `sqltimestamp`: 将输入数据转换为时间戳格式,并在必要时为时间元素提供零值。`sqltimestamp`(缩写为sts) `datepart`值仅用于`datepart`。不要试图在其他上下文中使用此值。 `datepart`可以指定为带引号的字符串,不带引号,或者在带引号的字符串周围加上括号。无论如何指定,都不会对`datepart`执行文字替换;对日期表达式执行文字替换。所有datepart值都返回一个数据类型`INTEGER`值,但`sqltimestamp`(或sts)除外,它以数据类型`timestamp`的字符串形式返回其值。 # 日期输入格式 日期表达式参数可以采用以下任何格式: - %Date logical value (+$H) - %PosixTime (%Library.PosixTime) logical value (an encoded 64-bit signed integer) - %TimeStamp (%Library.TimeStamp) logical value (YYYY-MM-DD HH:MM:SS.FFF), also known as ODBC format. - IRIS %String (or compatible) value %String(或兼容)值可以是以下任何格式: - 99999,99999 ($H format) - Sybase/SQL-Server-date Sybase/SQL-Server-time - Sybase/SQL-Server-time Sybase/SQL-Server-date - Sybase/SQL-Server-date (default time is 00:00:00) - Sybase/SQL-Server-time (default date is 01/01/1900) Sybase/SQL-Server-date是这五种格式之一: ``` mmdelimiterdddelimiter[yy]yy dd Mmm[mm][,][yy]yy dd [yy]yy Mmm[mm] yyyy Mmm[mm] dd yyyy [dd] Mmm[mm] ``` 其中分隔符是斜杠(`/`)、连字符(`-`)或句点(`.`)). Sybase/SQL服务器时间代表这三种格式之一: ``` HH:MM[:SS:SSS][{AM|PM}] HH:MM[:SS.S] HH['']{AM|PM} ``` 如果日期表达式指定了时间格式,但没有指定日期格式,则`DATENAME`默认为日期`1900–01–01`,该日期的工作日值为2(星期一)。 对于`sqltimestamp`,时间以24小时制返回。分数秒被截断。 # 无效的参数错误代码 如果指定无效的`datepart`选项,`DATEPART`将生成一个`SQLCODE -8`错误代码,并且以下`%msg: 'badopt' is not a recognized DATEPART option`. 如果指定了无效的日期表达式值(例如,字母文本字符串),`DATEPART`将生成`SQLCODE -400`错误代码和以下 `%msg: Invalid input to DATEPART() function: DATEPART('year','badval')`。如果指定的日期表达式未通过验证(如下所述),`datepart`将生成一个`SQLCODE -400`错误代码,并显示以下`%msg: Unexpected error occurred: datepart`. # 范围和值检查 `DATEPART`对日期表达式值执行以下检查。如果值未通过检查,则返回空字符串。 - 有效的日期表达式可以由日期字符串(`yyyy-mm-dd`)、时间字符串(`hh:mm:ss`)或日期和时间字符串(`yyy-mm-dd hh:mm:ss`)组成。如果同时指定了日期和时间,则两者都必须有效。例如,如果未指定时间字符串,则可以返回年份值,但是如果指定了无效的时间字符串,则不能返回年份值。 - 日期字符串必须完整且格式正确,每个元素都有适当数量的元素和数字,以及适当的分隔符。例如,如果省略了“日”值,则不能返回“年”值。年份必须指定为四位数。 - 时间字符串必须用适当的分隔符正确格式化。因为时间值可以为零,所以可以省略一个或多个时间元素(保留或省略分隔符),这些元素将以零值返回。因此,`' hh:mm:ss '`,`' hh:mm '`,`' hh:mm '`,`' hh:ss '`,`' hh:'`,和`':::'`都是有效的。要省略`Hour`元素,日期表达式不能包含字符串的日期部分,并且必须至少保留一个分隔符(`:`)。 - 日期和时间值必须在有效范围内。年份:`0001`到`9999`。月份:`1`到`12`。天数:`1`到`31`天。小时:`0`到`23`。分钟:`0`到`59`。秒:`0`到`59`。 - 一个月中的天数必须与月和年相匹配。例如,日期`“02–29”`仅在指定年份为闰年时有效。 - 大多数小于`10`的日期和时间值可能包含或省略前导零。但是,如果小时值是日期时间字符串的一部分,则小于`10`的小时值必须包含前导零。不允许其他非规范整数值。因此,`“07”`或`“7”`的“日”值有效,但`“007”`、`“7.0”`或`“7a”`无效。 - 如果日期表达式指定了时间格式,但没有指定日期格式,则`DATEPART`不会对时间分量值执行范围验证。 # 示例 在下面的示例中,每个`DATEPART`将日期时间字符串的年份部分(在本例中为`2018`年)作为整数返回。请注意,日期表达式可以有多种格式,`datepart`可以指定为`datepart`名称或`datepart`缩写,带引号或不带引号: ```sql SELECT DATEPART('yy','2018-02-22 12:00:00') AS YearDTS, DATEPART('year','2018-02-22') AS YearDS, DATEPART(YYYY,'02/22/2018') AS YearD, DATEPART(YEAR,64701) AS YearHD, DATEPART('Year','64701,23456') AS YearHDT 2018 2018 2018 2018 2018 ``` 以下示例基于`$HOROLOG`值返回当前年份和季度: ```sql SELECT DATEPART('yyyy',$HOROLOG) AS Year,DATEPART('q',$HOROLOG) AS Quarter 2022 1 ``` 下面的嵌入式SQL示例使用主机变量来提供`DATEPART`参数值: ```sql SET x="year" SET datein="2018-02-22" &sql(SELECT DATEPART(:x,:datein) INTO :partout) WRITE "the ",x," is ",partout ``` 下面的示例返回`Sample.Person`表的出生日期(按星期几排序): ```sql SELECT Name,DOB,DATEPART('weekday',DOB) AS bday FROM Sample.Person ORDER BY bday,DOB ``` 在以下示例中,每个`DATEPART`返回20作为日期表达式字符串的分钟部分: ```sql SELECT DATEPART('mi','2018-2-20 12:20:07') AS Minutes, DATEPART('n','2018-02-20 10:20:') AS Minutes, DATEPART(MINUTE,'2018-02-20 10:20') AS Minutes 20 20 20 ``` 在下面的示例中,每个`DATEPART`返回0作为日期表达式字符串的秒部分: ```sql SELECT DATEPART('ss','2018-02-20 03:20:') AS Seconds, DATEPART('S','2018-02-20 03:20') AS Seconds, DATEPART('Second','2018-02-20') AS Seconds 0 0 0 ``` 以下示例以`TIMESTAMP`数据类型返回完整的SQL `TIMESTAMP`。`DATEPART`填充缺失的时间信息以返回时间戳`‘2018-02-25 00:00:00’`: ```sql SELECT DATEPART(sqltimestamp,'2/25/2018') AS DTStamp 2018/2/25 0:00:00 ``` 以下示例以`$HOROLOG`格式提供日期和时间,并返回时间戳`‘2018-02-22 06:30:56’`: ```sql SELECT DATEPART(sqltimestamp,'64701,23456') AS DTStamp 2018/2/22 6:30:56 ``` 下面的示例使用带有`DATEPART`的子查询来返回生日为闰年日(2月29日)的那些人: ```sql SELECT Name,DOB FROM (SELECT Name,DOB,DATEPART('dd',DOB) AS DayNum,DATEPART('mm',DOB) AS Month FROM Sample.Person) WHERE Month=2 AND DayNum=29 ```