日期时间操作和持续时间

日期时间值可以递增,递减和减去。 这些操作可能涉及称为持续时间的十进制数。

持续时间

duration 是表示时间间隔的数字。

labeled-duration
Read syntax diagramSkip visual syntax diagram function(expression)constantcolumn-nameglobal-variablehost-variable YEARYEARSMONTHMONTHSDAY DAYS1HOURHOURSMINUTEMINUTESSECOND SECONDS2MICROSECONDMICROSECONDS
Notes:
  • 1 DAYS is the default for non-decimal numeric arithmetic involving dates and timestamps.
  • 2 SECONDS is the default for non-decimal numeric arithmetic involving time.
持续时间可以是下列其中一种类型:
labeled duration
由数字 (可以是表达式的结果) 表示的特定时间单位,后跟下列七个持续时间关键字之一: :MINUTES , MONTHS , DAYS , HOURS , MINUTES , SECONDS 或 MICROSECONDS。 (这些关键字的单数形式也可接受 :YEAR , MONTH , DAY , HOUR , MINUTE , SECOND 和 MICROSECOND。) 将转换指定的数字,就像将其分配给 DECIMAL (15, 0) 号 SECONDS 除外,后者使用 DECIMAL (27,12) 允许包含 0 到 12 位小数秒的小数一样。 标记的持续时间只能用作算术运算符的操作数,其中另一个操作数是数据类型为 DATE , TIME 或 TIMESTAMP 的值。 因此,表达式 HIREDATE + 2 MONTHS + 14 DAYS 有效,而表达式 HIREDATE + (2 MONTHS + 14 DAYS) 无效。 在这两个表达式中,标注的持续时间都是 2 MONTHS 和 14 DAYS。
date duration
以 DECIMAL (8, 0) 数字表示的年数,月数和日数。 要正确解释该数字,该数字的格式必须为 yyyymmdd.。 其中 yyyy 表示年数, mm 表示月数, dd 表示天数。 (格式中的句点指示 DECIMAL 数据类型。) 从另一个日期值中减去一个日期值 (如表达式 HIREDATE-BRTHDATE) 的结果是日期持续时间。
time duration
以 DECIMAL (6, 0) 数字表示的小时数,分钟数和秒数。 要正确解释此数字,该数字的格式必须为 hhmmss.。 其中 hh 表示小时数, mm 表示分钟数, ss 表示秒数。 (格式中的句点指示 DECIMAL 数据类型。) 从另一个时间值中减去一个时间值的结果是持续时间。
timestamp duration
年数,月数,天数,小时数,分钟数,秒数和 小数 秒,以 DECIMAL (14 +ss) 数字表示,其中 s 是小数秒数的位数 范围从 0 到 12。 要正确解释此数字,必须具有格式 yyyymmddhhmmss.nnnnnnnnnnnn,其中 yyyymmddhhmmssnnnnnnnnnnnn 分别表示年数,月数,天数,小时数,分钟数,秒数和 小数 秒。 从另一个时间戳记值中减去一个时间戳记值的结果是时间戳记持续时间, 其小数位与时间戳记操作数的最大时间戳记精度相匹配

SQL 中的日期时间算术

可以对日期时间值执行的唯一算术运算是加法和减法。 如果日期时间值是加法的操作数,那么另一个操作数必须是持续时间。 下面是控制使用具有日期时间值的添加运算符的特定规则。
  • 如果一个操作数是日期,那么另一个操作数必须是日期持续时间或标记为 "年" , "月" 或 "日" 的持续时间。
  • 如果一个操作数是时间,那么另一个操作数必须是持续时间或标记为 HOURS , MINUTES 或 SECONDS 的持续时间。
  • 如果一个操作数是时间戳记,那么另一个操作数必须是持续时间。 任何类型的持续时间都有效。
  • 加法运算符的两个操作数都不能是参数标记。
在日期时间值上使用减法运算符的规则与用于加法的规则不同,因为无法从持续时间中减去日期时间值,并且由于从日期时间值中减去两个日期时间值的操作与从日期时间值中减去持续时间的操作不同。 下面是控制使用带有日期时间值的减法运算符的特定规则。
  • 如果第一个操作数是时间戳记,那么第二个操作数必须是 日期, 时间戳记, 日期的字符串表示, 时间戳记的字符串表示, 或持续时间。 如果第二个操作数是时间戳记的字符串表示,那么它将以与第一个操作数相同的精度隐式转换为时间戳记。
  • 如果第二个操作数是时间戳记,那么第一个操作数必须是 日期, 时间戳记, 日期的字符串表示, 或时间戳记的字符串表示。 如果第一个操作数是时间戳记的字符串表示,那么它将以与第二个操作数相同的精度隐式转换为时间戳记。
  • 如果第一个操作数是日期,那么第二个操作数必须是日期,日期持续时间,日期的字符串表示,或者标记为 DAYS , MONTHS 或 DAYS 的持续时间。
  • 如果第二个操作数是日期,那么第一个操作数必须是日期或日期的字符串表示。
  • 如果第一个操作数是时间,那么第二个操作数必须是时间,持续时间,时间的字符串表示,或者标记为 HOURS , MINUTES 或 SECONDS 的持续时间。
  • 如果第二个操作数是时间,那么第一个操作数必须是时间或时间的字符串表示。
  • 减法运算符的两个操作数都不能是参数标记。

日期算法

可以将日期减去,递增或递减。

  • 从另一个日期 (DATE1) 中减去一个日期 (DATE2) 的结果是指定两个日期之间的年数,月数和天数的日期持续时间。 结果的数据类型为 DECIMAL (8, 0)。 如果 DATE1 大于或等于 DATE2,那么将从 DATE1中减去 DATE2 。 但是,如果 DATE1 小于 DATE2,那么将从 DATE2中减去 DATE1 ,并使结果的符号为负数。 以下过程描述阐明了操作结果 = DATE1 - DATE2中涉及的步骤。
       If DAY(DATE2) <= DAY(DATE1)
       then DAY(RESULT) = DAY(DATE1) - DAY(DATE2).
       If DAY(DATE2) > DAY(DATE1)
       then DAY(RESULT) = N + DAY(DATE1) - DAY(DATE2)
       where N = the last day of MONTH(DATE2).
       MONTH(DATE2) is then incremented by 1.
       If MONTH(DATE2) <= MONTH(DATE1)
       then MONTH(RESULT) = MONTH(DATE1) - MONTH(DATE2).
       If MONTH(DATE2) > MONTH(DATE1)
       then MONTH(RESULT) = 12 + MONTH(DATE1) - MONTH(DATE2).
       YEAR(DATE2) is then incremented by 1.
       YEAR(RESULT) = YEAR(DATE1) - YEAR(DATE2).

    例如, DATE ('3/15/2000')-'12/31/1999' 的结果为 00000215。 (或者,持续时间为 0 年, 2 个月和 15 天)。

  • 将持续时间添加到日期或从日期中减去持续时间的结果本身就是日期。 (对于此操作,月份表示相当于日历页面。 将月份添加到日期,就像翻开日历的页面一样,从显示日期的页面开始。) 结果必须介于 1 月 1 , 0001 和 9999 年 12 月 31 日 (含) 之间。

    如果添加或减去年份持续时间,那么仅影响日期的年份部分。 月不变,如日,除非结果会是非跨年的 2 月 29 日。 在这种情况下,该日期将更改为 28 ,并且 SQLCA 中的警告指示符将设置为指示调整。

    同样,如果添加或减去月的持续时间,那么仅影响月数,并且在必要时影响年数。 除非结果无效 (例如, 9 月 31 日) ,否则日期的日期部分保持不变。 在这种情况下,将日期设置为月份的最后一天,并设置 SQLCA 中的警告指示符以指示调整。

    当然,添加或减去天数的持续时间将影响日期的日期部分,并可能影响月份和年份。

    日期持续时间 (无论是正数还是负数) 也可以添加到日期并从日期中减去。 与带标签的持续时间一样,结果是有效日期,只要需要进行月末调整,就会在 SQLCA 中设置警告指示符。

    如果将正日期持续时间添加到某个日期,或者从某个日期中减去负日期持续时间,那么该日期将按指定的年数,月数和天数按该顺序递增。 因此, DATE1 + X (其中 X 是正 DECIMAL (8, 0) 数字) 等价于表达式:
       DATE1 + YEAR(X) YEARS + MONTH(X) MONTHS + DAY(X) DAYS.
    当从日期中减去正日期持续时间,或将负日期持续时间添加到日期时,该日期将按指定的天数,月数和年数 (按该顺序) 递减。 因此, DATE1 -X (其中 X 是正 DECIMAL (8, 0) 数字) 等同于表达式:
       DATE1 - DAY(X) DAYS - MONTH(X) MONTHS - YEAR(X) YEARS.

    将持续时间添加到日期时,将一个月添加到给定日期将给出一个月后的相同日期,除非该日期在以后的月份中不存在。 在这种情况下,日期设置为后一个月的最后一天。 例如, 1 月 28 日加一个月给出 2 月 28 日; 而一个月加到 1 月 29 日, 30 日或 31 日的结果要么是 2 月 28 日,要么是闰年, 2 月 29 日。

    注: 如果将一个或多个月添加到给定日期,然后从结果中减去相同的月数,那么最终日期不一定与原始日期相同。

时间算术

时间可以减去,递增或递减。

  • 从另一时间 (TIME1) 中减去一次 (TIME2) 的结果是指定两次之间的小时数,分钟数和秒数的持续时间。 结果的数据类型为 DECIMAL (6, 0)。

    如果 TIME1 大于或等于 TIME2,那么将从 TIME1中减去 TIME2 。

    但是,如果 TIME1 小于 TIME2,那么 TIME1 将从 TIME2中减去,并且结果的符号为负数。 以下过程描述阐明了操作结果中涉及的步骤 = TIME1 - TIME2。
       If SECOND(TIME2) <= SECOND(TIME1)
       then SECOND(RESULT) = SECOND(TIME1) - SECOND(TIME2).
       If SECOND(TIME2) > SECOND(TIME1)
       then SECOND(RESULT) = 60 + SECOND(TIME1) - SECOND(TIME2).
       MINUTE(TIME2) is then incremented by 1.
       If MINUTE(TIME2) <= MINUTE(TIME1)
       then MINUTE(RESULT) = MINUTE(TIME1) - MINUTE(TIME2).
       If MINUTE(TIME1) > MINUTE(TIME1)
       then MINUTE(RESULT) = 60 + MINUTE(TIME1) - MINUTE(TIME2).
       HOUR(TIME2) is then incremented by 1.
       HOUR(RESULT) = HOUR(TIME1) - HOUR(TIME2).

    例如, TIME ('11:02:26')-'00:32:56' 的结果为 102930。 (持续时间为 10 小时 29 分 30 秒)。

  • 将持续时间添加到时间或从时间中减去持续时间的结果本身就是时间。 将废弃任何溢出或下溢的小时数,从而确保结果始终是一个时间。 如果添加或减去小时数的持续时间,那么仅影响时间的小时数部分。 分钟和秒不变。

    同样,如果添加或减去持续时间 (分钟) ,那么仅会影响分钟,如果需要,还会影响小时数。 时间的秒数部分保持不变。

    当然,添加或减去持续时间 (以秒计) 将影响时间的秒数部分,并可能影响分钟数和小时数。

    时间持续时间 (无论是正值还是负值) 也可以添加到时间中并从时间中减去。 结果是按指定的小时数,分钟数和秒数 (按该顺序) 递增或递减的时间。 TIME1 + X 其中 "X" 是 DECIMAL (6, 0) 数字,相当于表达式:
       TIME1 + HOUR(X) HOURS + MINUTE(X) MINUTES + SECOND(X) SECONDS

    当用包含秒的分数的值减去标记的 SECOND 或 SECONDS 持续时间时,将执行减法,就像时间值具有最多 12 个小数秒数字一样,但返回的结果将截断小数秒。

    注: 虽然接受时间 "24:00:00" 作为有效时间,但从不作为时间加法或减法的结果返回,即使持续时间操作数为零 (例如, time ('24:00:00') ± 0 seconds = '00:00:00')。

时间戳记算术

时间戳记可以减去,递增或递减。

  • 从另一个时间戳记 (TS1) 中减去一个时间戳记 (TS2) 的结果是时间戳记持续时间,用于指定两个时间戳记之间的年数,月数,日数,小时数,分钟数,秒数和 小数 秒。 结果的数据类型为 DECIMAL (14 +ss) ,其中 s 是 TS1 和 TS2的最大时间戳记精度。
    如果 TS1 大于或等于 TS2,那么将从 TS1中减去 TS2 。 但是,如果 TS1 小于 TS2,那么将从 TS2 中减去 TS1 ,并使结果的符号为负数。 以下过程描述阐明了操作结果 = TS1 - TS2:
        If SECOND(TS2,s) <= SECOND(TS1,s)
        then SECOND(RESULT,s) = SECOND(TS1,s) -
        SECOND(TS2,s).
        If SECOND(TS2,s) > SECOND(TS1,s)
        then SECOND(RESULT,s) = 60 +
        SECOND(TS1,s) - SECOND(TS2,s).
        MINUTE(TS2) is then incremented by 1.
    时间戳记的分钟部分将按照规则中指定的时间减去时间。
       If HOUR(TS2) <= HOUR(TS1)
       then HOUR(RESULT) = HOUR(TS1) - HOUR(TS2).
       If HOUR(TS2) > HOUR(TS1)
       then HOUR(RESULT) = 24 + HOUR(TS1) - HOUR(TS2)
       and DAY(TS2) is incremented by 1.

    时间戳记的日期部分将按照用于减去日期的规则中指定的那样进行减去。

  • 从时间戳记 (TS1) 中减去日期 (D1) 的结果与从 TS1中减去 TIMESTAMP (D1) 的结果相同。 同样,从日期 (D2) 中减去一个时间戳记 (TS1) 的结果与从 TIMESTAMP (D2) 中减去 TS1 的结果相同。
  • 将持续时间添加到时间戳记或从时间戳记中减去持续时间的结果本身就是时间戳记。结果时间戳记的精度与时间戳记操作数的精度相匹配。 日期算术部分 按先前定义的方式执行,但结果的日期部分中必须包含有效日期范围内的溢出或小时数下溢。 时间算术部分与时间算术类似,不同之处在于它还考虑了持续时间中包含的小数秒数。 因此,从时间戳记 TIMESTAMP1中减去持续时间 X,其中 X 是 DECIMAL (14+s,s) 数字,等同于表达式:
       TIMESTAMP1 - YEAR(X)  YEARS - MONTH(X)  MONTHS - DAY(X)  DAYS
                  - HOUR(X)  HOURS - MINUTE(X)  MINUTES - SECOND(X, s)  SECONDS

    当减去具有非零刻度的持续时间或具有包含秒的分数的值的标记持续时间 SECOND 或 SECONDS 时,将执行减法,就像时间戳记值具有最多 12 个小数秒位一样。 将结果值指定给时间戳记值,该时间戳记值具有时间戳记操作数的时间戳记精度,这可能导致小数秒数字被截断。