SPL:日期时间运算
SPL提供了丰富的日期时间操作函数,分为基本处理、运算两大类,包括当前时刻、日期时间分量的拆分、分量组合成日期时间、格式转换、精度调整、相关日期、时间间隔、相对时间、相同判断、工作日计算、时间等分序列等。
1. 基本处理
1.1 当前时刻
目标 | 示例代码 | 返回值 |
返回当前时刻,精确到毫秒 | now() | |
返回当前日期 | now@d() | |
返回当前时间 | now@t() | |
返回当前时刻,精确到分 | now@m() | |
返回当前时刻,精确到秒 | now@s() |
1.2 拆分
从日期、时间、日期时间对象或串中提取出它所对应的年、月、日、时、分、秒、周等数据。
下表中的dt是日期时间对象:datetime("2018-08-15 16:07:58:327","yyyy-MM-dd HH🇲🇲ss:SSS")
目标 | 示例代码 | 返回值 |
取出年份 | year(dt) | 2018 |
取出月份 | month(dt) | 8 |
取出年月 | month@y(dt) | 201808 |
取出日 | day(dt) | 15 |
取出该日是周几 | day@w(dt) | 4(周日为1,周一为2) |
取出小时 | hour(dt) | 16 |
取出分钟 | minute(dt) | 7 |
取出秒 | second(dt) | 58 |
取出毫秒 | millisecond(dt) | 327 |
取出日期时间对象的日期部分 | date(dt) | "2018-08-15")date( |
取出日期时间对象的时间部分 | time(dt) | time("16:07:58") |
取出日期时间对象的时间部分,精确到分 | time@m(dt) | time("16:07:00") |
1.3 组合
用年、月、日、时、分、秒、长整数或日期时间串生成日期、时间或日期时间对象。
下表中的dt是日期时间对象:datetime("2018-08-15 16:07:58:327","yyyy-MM-dd HH🇲🇲ss:SSS")
目标 | 示例代码 | 返回值 |
用年月日分量生成日期 | date(2018,8,15) | |
用时分秒分量生成时间 | time(16,7,58) | |
用年月日时分秒分量生成日期时间 | datetime(2018,8,15,16,7,58) | |
用日期和时间分量拼成日期时间 | datetime(date("2018-08-15"), time("16:07:58")) |
1.4 转换
下表中的d是日期对象:date("2018-08-15")
t是时间对象:time("16:07:58:327","HH🇲🇲ss:SSS")
dt是日期时间对象:datetime("2018-08-15 16:07:58:327","yyyy-MM-dd HH🇲🇲ss:SSS")
目标 | 示例代码 | 返回值 |
调整日期时间精度,精确到日 | datetime(dt) | 2018-08-15 00:00:00 |
调整日期时间精度,精确到分 | datetime@m(dt) | 2018-08-15 16:07:00 |
调整日期时间精度,精确到秒 | datetime@s(dt) | 2018-08-15 16:07:58 |
按默认格式将串转成日期 | date("2018-08-15") | |
按指定格式将串转成日期 | date("08/15/2018","MM/dd/yyyy") | |
按指定格式将串转成日期 | date("201808","yyyyMM") | 2018-08-01 |
按默认格式将串转成时间 | time("16:07:58") | |
按指定格式将串转成时间 | time("4:07 PM","h:mm a") | 16:07:00 |
按格式将串转成日期时间 | datetime("2018-08-15 16:07:58") | |
按指定格式将串转成日期时间 | datetime("08/15/2018 4:07 PM", "MM/dd/yyyy h:mm a") | |
转成默认日期格式串 | string(d) | 2018-08-15 |
转成指定日期格式串 | string(dt,"MM/dd/yyyy") | 08/15/2018 |
转成指定日期格式串 | string(dt,"yyyyMM") | 201808 |
转成默认时间格式串 | string(t) | 16:07:58 |
转成指定时间格式串 | string(dt,"h:mm a") | 4:07 PM |
转成默认日期时间格式 | string(dt) | 2018-08-15 16:07:58 |
转成指定日期时间格式 | string(dt,"MM/dd/yyyy h:mm a") | 08/15/2018 4:07 PM |
将长整数转成日期时间 | datetime(321656865654) | 1980-03-12 05:07:45 |
转成长整数(1970年1月1日以来的毫秒数) | long(dt) | 1534320478000 |
2. 运算
2.1 相关日期
下表中的dt为:date("2020-04-16")
目标 | 示例代码 | 返回值 |
取所在周的第一天(周日) | pdate@w(dt) | 2020-04-12 |
取所在月的第一天 | pdate@m(dt) | 2020-04-01 |
取所在季的第一天 | pdate@q(dt) | 2020-04-01 |
取所在年的第一天 | pdate@y(dt) | 2020-01-01 |
取所在周的最后一天(周六) | pdate@we(dt) | 2020-04-18 |
取所在月的最后一天 | pdate@me(dt) | 2020-04-30 |
取所在季的最后一天 | pdate@qe(dt) | 2020-06-30 |
取所在年的最后一天 | pdate@ye(dt) | 2020-12-31 |
取所在月的天数 | days(dt) | 30 |
取所在季的天数 | days@q(dt) | 91 |
取所在年的天数 | days@y(dt) | 366 |
2.2 时间间隔
计算两个时刻之间间隔的时间。
下表中dt1、dt2分别为:datetime("2008-08-08 20:00:00")、datetime("2018-05-28 10:27:15")
目标 | 示例代码 | 返回值 |
某时刻与当前时刻相差的整年数 | age(dt1) | 13 |
两时刻间相差的整年数 | age(dt1,dt2) | 9 |
两时刻所在年间相差的年数 | age@y(dt1,dt2) | 10 |
两时刻所在月间相差的年数 | age@m(dt1,dt2) | 9 |
两时刻间相差的年数 | interval@y(dt1,dt2) | 10 |
两时刻间相差的季数 | interval@q(dt1,dt2) | 40 |
两时刻间相差的月数 | interval@m(dt1,dt2) | 117 |
两时刻间相差的秒数 | interval@s(dt1,dt2) | 309277635 |
两时刻间相差的毫秒数 | interval@ms(dt1,dt2) | 309277635000 |
两时刻间的周日数 | interval@7(dt1,dt2) | 512 |
两时刻间的周一数 | interval@1(dt1,dt2) | 512 |
两时刻间相差的天数(整数) | interval(dt1,dt2) | 3580 |
两时刻间相差的天数(整数) | dt2-dt1 | 3580 |
两时刻间相差的天数(实数) | interval@r(dt1,dt2) | 3579.6022569444444 |
2.3 相对时间
elapse(dt,k)
计算某时刻dt向后或向前移动一定时间k后的新时间,k为正数时向后移动,为负数时向前移动。如果原时刻是月底,移动后默认也会调整到月底。
下表中dt为:datetime("2017-02-28 10:27:15"),属于月底。
目标 | 示例代码 | 返回值 |
3天后的时间 | dt+3 | 2017-03-03 10:27:15 |
3天后的时间 | elapse(A2,3) | 2017-03-03 10:27:15 |
3年后的时间(调整月底) | elapse@y(A2,3) | 2020-02-29 10:27:15 |
3年后的时间(不调整月底) | elapse@ye(A2,3) | 2020-02-28 10:27:15 |
3季后的时间(调整月底) | elapse@q(A2,3) | 2017-11-30 10:27:15 |
3季后的时间(不调整月底) | elapse@qe(A2,3) | 2017-11-28 10:27:15 |
4月前的时间(调整月底) | elapse@m(A2,-4) | 2016-10-31 10:27:15 |
4月前的时间(不调整月底) | elapse@me(A2,-4) | 2016-10-28 10:27:15 |
100秒后的时间 | elapse@s(A2,100) | 2017-02-28 10:28:55 |
368毫秒后的时间 | elapse@ms(A2,368) | 2017-02-28 10:27:15:368 |
2.4 相同判断
目标 | 示例代码 | 返回值 |
两个日期是否相同 | deq("1988-12-08","1988-12-07") | false |
两个日期的年份是否相同 | deq@y(date("1988-11-08"),date("1988-09-12")) | true |
两个日期的月份是否相同 | deq@m(date("1988-11-08"),date("1988-09-12")) | false |
两个日期的季度是否相同 | deq@q(date("1988-12-08"),date("1988-10-12")) | true |
两个日期的旬是否相同 | deq@t(date("1988-10-08"),date("1988-10-12")) | false |
两个日期的周是否相同 | deq@w(date("1988-10-05"),date("1988-10-08")) | true |
2.5 工作日问题
workday(dt,k,h) 计算和日期dt相距k个工作日的工作日期。
workdays(dt1,dt2,h) 计算日期dt1和dt2之间的工作日序列。
h是假日序列或非假日序列,即h中成员若非周末则指定为假日,若是周末则指定为非假日。
目标 | 示例代码 | 返回值 |
2个工作日后的工作日 | workday(date("2020-04-29"),2,[date("2020-05-01")]) | 2020-05-04 |
2020-05-01是周五,此处被指定为放假日。 | ||
2个工作日后的工作日 | workday(date("2020-09-25"),2,[date("2020-09-27")]) | 2020-09-28 |
2020-09-27是周日,此处被指定为工作日。 | ||
两个日期间的工作日序列 | =workdays(date("2020-09-24"),date("2020-09-29"),[date("2020-09-27")]) | [2020-09-24,2020-09-25,2020-09-27,2020-09-28,2020-09-29] |
2.6 等分时间段
periods(s,e,i)
s,e是时间变量,i为整数,返回从s到e(包括端点)每间隔i的时间值构成的序列,缺省单位为日,i缺省为1。若不想包括端点e可加选项x。
目标 | 示例代码 | 返回值 |
两时刻间相隔3天的日期序列 | periods("2018-09-25","2018-10-06",3) | [2018-09-25,2018-09-28, 2018-10-01,2018-10-04, 2018-10-06] |
两时刻间相隔3年的日期序列 (调整为年起点) |
periods@y("2010-09-25","2018-10-06",3) | [2010-09-25,2013-01-01, 2016-01-01,2018-10-06] |
两时刻间相隔3年的日期序列 (不调整为年起点) |
periods@yo("2010-09-25","2018-10-06",3) | [2010-09-25,2013-09-25, 2016-09-25,2018-10-06] |
两时刻间相隔3季度的日期序列 (调整为季度起点) |
periods@q("2010-09-25","2012-05-06",3) | [2010-09-25,2011-04-01, 2012-01-01,2012-05-06] |
两时刻间相隔3季度的日期序列 (不调整为季度起点) |
periods@qo("2010-09-25","2012-05-06",3) | [2010-09-25,2011-06-25, 2012-03-25,2012-05-06] |
两时刻间相隔3月的日期序列 (调整为月起点) |
periods@m("2010-09-25","2011-04-06",3) | [2010-09-25,2010-12-01, 2011-03-01,2011-04-06] |
两时刻间相隔3月的日期序列 (不调整为月起点) |
periods@mo("2010-09-25","2011-04-06",3) | [2010-09-25,2010-12-25, 2011-03-25,2011-04-06] |
两时刻间相隔2旬的日期序列 | periods@t("2010-09-25","2010-11-06",2) | [2010-09-25,2010-10-11, 2010-11-01,2010-11-06] |
两时间相隔3秒的时间序列 | periods@s("08:25:30","08:25:39",3) | [08:25:30,08:25:33, 08:25:36,08:25:39] |
range(s,e,k:n)
s、e是时间变量,将s、e之间等分成n份,返回第k段的范围。根据s、e的数据类型决定返回精确度,date型精确到天,datetime型精确到秒。
目标 | 示例代码 | 返回值 |
2日期3等分的分段点 | range(date("2018-08-09"),date("2020-02-20"),3) | [2018-08-09,2019-02-12, 2019-08-18,2020-02-20] |
2日期3等分后第2段的范围 | range(date("2018-08-09"),date("2020-02-20"),2:3) | [2019-02-12,2019-08-18] |
2日期时间3等分后第2段的 范围 |
range(datetime("2018-01-01 10:20:30"), datetime("2020-01-01 10:00:00"),2:3) |
[2018-09-01 18:13:40, 2019-05-03 02:06:50] |
更多日期时间操作请参阅SPL资料中的日期时间函数。