第四十二章 SQL函数 DATEADD

[toc]

第四十二章 SQL函数 DATEADD

一个日期/时间函数,它返回一个时间戳,计算方法是在一个日期或时间戳中添加或减去若干日期部件单位(如小时或天)。

大纲

DATEADD(datepart,integer-exp,date-exp)

参数

  • datepart - 日期或时间部分的名称(或缩写)。
    可以用大写或小写指定该名称,也可以不加引号。
    可以将datepart指定为文字或主机变量。
  • integer-exp - 任意数字类型的数字表达式。
    该值被截断为整数(正或负)。
    该值指示将添加到(或从)date-exp中减去的datepart单元的数量。
  • date-exp - 要修改的日期/时间表达式。它可以是日期字符串,也可以是时间戳字符串(%PosiTime%Timestamp数据类型),也可以是CURRENT_DATE之类的函数。返回的值始终是时间戳,数据类型格式为%PosiTime%Timestamp

描述

DATEADD函数通过将指定的日期部分递增指定的单元数来修改日期/时间表达式。
例如,如果datepart“month”且整数-exp5,则DATEADDdate-exp递增5个月。
还可以通过为integer-exp指定一个负整数来减少日期部分。

计算出的日期将作为完整的日期/时间表达式(时间戳)返回。返回的数据类型取决于Date-EXP的数据类型。如果Date-EXP%Library.PosiTime(编码的64位有符号整数),则DATEADD返回数据类型%Library.PosiTime。否则,DATEADD返回数据类型%Library.TimeStamp(yyyy-mm-dd hh:mm:ss.fff)

DATEADD始终返回有效日期,并考虑一个月的天数,并计算闰年。例如,将1月31日递增一个月将返回2月28日(该月中的最高有效日期),除非指定的年份是闰年,在这种情况下将返回2月29日。将闰年日期2月29日递增一年将返回2月28日。将闰年日期2月29日递增四年返回2月29日。

如果指定包含小数秒的date-exp,则返回值也包括小数秒。如果省略date-exp的时间部分,DATEADD将返回默认时间00:00:00。如果省略date-exp的日期部分,DATEADD将返回默认日期1900-01-01

DATEADDTIMESTAMPADD处理季度(3个月间隔);DATEDIFFTIMESTAMPDIFF不处理季度。

可以使用TIMESTAMPADD ODBC标量函数执行类似的时间/日期修改操作。

也可以使用DATEADD()方法调用从ObjectScript调用此函数:

$SYSTEM.SQL.Functions.DATEADD(datepart,integer-exp,date-exp)

Datepart Argument

日期部分参数可以是以下日期/时间组件之一:全名(日期部分列)或其缩写(缩写列)。这些日期部分组件名称和缩写不区分大小写。

Date Part Abbreviations integer-exp = 1
year yyyy, yy Increments year by 1.
quarter qq, q Increments month by 3.
month mm, m Increments month by 1.
week wk, ww Increments day by 7.
weekday dw Increments day by 1.
day dd, d Increments day by 1.
dayofyear dy, y Increments day by 1.
hour hh Increments hour by 1.
minute mi, n Increments minute by 1.
second ss, s Increments second by 1.
millisecond ms Increments by .001 of a second.
microsecond mcs 0–999999 (with precision of 6)
nanosecond ns 0–999999999 (with precision of 9)

递增或递减日期部分会导致适当修改其他日期部分。例如,午夜过后的小时递增会自动递增日期,这又可能会递增月份,依此类推。

日期部分可以指定为带引号的字符串或不带引号。这些语法变体执行的操作略有不同:

  • QUOTESDATEADD('month',12,$HOROLOG):在创建缓存查询时,日期部分被视为文字。 SQL执行文字替换。这会产生更普遍可重用的缓存查询。
  • 无引号:DATEADD(MONTH,12,$HOROLOG):在创建缓存查询时,日期部分被视为关键字。没有文字替换。这会产生更具体的缓存查询。

如果将无效的日期部分值指定为文字,则会发出SQLCODE-8错误代码。但是,如果提供无效的日期部件值作为主机变量,则不会发出SQLCODE错误,并且DATEPART函数返回值为NULL

日期表达式格式

Date-exp参数可以采用以下任何格式,并且可以包括或省略小数秒:

  • %Date logical value (+$H)

  • %PosiTime(%Library.PosiTime)逻辑值(编码的64位有符号整数)

  • (%Library.TimeStamp)逻辑值(YYYY-MM-DD HH:MM:SS)

  • %String(或兼容)值

%STRING(或COMPATIBLE)值可以采用以下任何格式:

  • 99999,99999 ($H format)

  • /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-Server-Time表示以下三种格式之一:

HH:MM[:SS:SSS][{AM|PM}] HH:MM[:SS.S] HH['']{AM|PM}

请注意,提供DATEADD是为了与SybaseMicrosoft SQL Server兼容。

范围和值检查

DATEADD对输入值执行以下检查。如果值未通过检查,则返回空字符串。

  • 日期字符串必须完整且格式正确,包含适当数量的元素和每个元素的数字,以及适当的分隔符。年份必须指定为四位数。
  • 日期值必须在有效范围内。年份:00019999。月份:1到12天1到31。时间:0点到23点。分钟:0到59分钟。秒:0到59
  • 返回的递增的year值必须在00019999之间。
    超出此范围将返回<null>
  • 一个月中的天数必须与月和年相匹配。
    例如,日期“02-29”仅在指定的年份为闰年时有效。
  • 小于10的日期值可以包括或省略前导零。
    不允许使用其他非规范整数值。
    因此,Day值为“07”“7”是有效的,但“007”“7.0”“7a”无效。

下面的例子为指定的日期添加了1周:

SELECT DATEADD('week',1,'2018-02-26') AS NewDate

2018/3/5 0:00:00

它返回2018-03-05 00:00:00,因为增加1周会增加7天。
注意,DATEADD提供了省略的时间部分。

下面的例子为时间戳添加了5个月:

SELECT DATEADD(MM,5,'2017-11-26 12:00:00') AS NewDate

2018/4/26 12:00:00

它返回2018-04-26 12:00:00,因为增加5个月也会增加一年。

下面的例子也在时间戳上增加了5个月:

SELECT DATEADD('mm',5,'2018-01-31 12:00:00') AS NewDate

2018/6/30 12:00:00

它返回2018-06-30 12:00:00
这里DATEADD修改了日值和月值,因为简单地增加月值将导致6月31日,这是一个无效的日期。

下面的例子为时间戳添加了45分钟:

SELECT DATEADD(MI,45,'2018-02-26 12:00:00') AS NewTime

2018/2/26 12:45:00

下面的示例还为时间戳添加了45分钟,但在本例中,添加的内容增加了日,从而增加了月:

SELECT DATEADD('mi',45,'2018-02-28 23:30:00') AS NewTime

2018/3/1 0:15:00

下面的例子将原始时间戳减去45分钟:

SELECT DATEADD(N,-45,'2018-01-01 00:10:00') AS NewTime

2017/12/31 23:25:00

下面的例子为当前日期添加了60天,并根据月份的不同长度进行调整:

SELECT DATEADD(D,60,CURRENT_DATE) AS NewDate

2022/4/4 0:00:00

在下面的例子中,第一个DATEADD为指定的日期添加了92天,第二个DATEADD为指定的日期添加了1 / 4天:

SELECT DATEADD('dd',92,'2018-12-20') AS NewDateD,
       DATEADD('qq',1,'2018-12-20') AS NewDateQ
image.png

第一季将于2019-03-22 00:00:00回归;
第二季将于2019-03-20 00:00:00回归。
每增加1 / 4,month字段就会增加3,如果需要,还会增加year字段。
它还校正给定月份的最大天数。

上面的例子都使用日期部分的缩写。
但是,也可以用它的全名来指定日期部分,就像下面的例子一样:

SELECT DATEADD('day',92,'2018-12-20') AS NewDate

2019/3/22 0:00:00

下面的嵌入式SQL示例使用主机变量来执行与前面示例相同的DATEADD操作:

ClassMethod DateAdd()
{
    s x="day"
    s datein="2019-12-20"
    &sql(SELECT DATEADD(:x,92,:datein)
       INTO :dateout)
    w "in:  ",datein,!,"out: ",dateout
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).DateAdd()
in:  2019-12-20
out: 2020-03-21 00:00:00
DHC-APP>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容