4使用日期时间数据的计算
除了直接从日期时间数据中获取信息,在SPL中还可以使用日期时间类数据来执行各类计算。
最常用的有关日期的计算就是计算年龄:
![e9d872dfe425932bca2da4c5324a2f9b.png](https://i-blog.csdnimg.cn/blog_migrate/4a6e285669ce4adff532d5f715abab57.jpeg)
A1和B1中的数据如下:
![2f2ba94f4fff9d6660f1593ec8844140.png](https://i-blog.csdnimg.cn/blog_migrate/2162540c7fdfcc6853a1df6e30b4da71.jpeg)
![17332c5f1008c3942be762d1a33be50b.png](https://i-blog.csdnimg.cn/blog_migrate/45c8f0c770bd4d986658be035a4b1b2f.jpeg)
在第2行用age() 函数,根据A1中的生日来计算年龄,计算年龄时,是以当前的日期为准的,默认情况将精确到日,添加@m可以将精度设为月,添加@y可以将精度设定为年。在不同精度的情况下,计算所得的年龄可能会有区别,A2,B2和C2中得到的年龄分别如下:
![a37d64d753735e9825d9631f504d0a76.png](https://i-blog.csdnimg.cn/blog_migrate/502430e26597af4ea4caea779755b731.jpeg)
![fbcfc1b09a072efe6b222283b2887b78.png](https://i-blog.csdnimg.cn/blog_migrate/0545956a422b4c086b9eff5d0d538644.jpeg)
![fbcfc1b09a072efe6b222283b2887b78.png](https://i-blog.csdnimg.cn/blog_migrate/0545956a422b4c086b9eff5d0d538644.jpeg)
使用age() 函数,类似于计算生日日期和当前日期间隔的年数。更普遍的计算时间间隔的函数是interval() 函数,用这个函数可以计算两个日期时间数据之间相差多少天,添加@y,@q,@m,@s,@ms等选项,可以计算间隔多少年,季度,月,秒或毫秒。例如:
![a0ffe265ffb11bbf8a13358ff19dc4c7.png](https://i-blog.csdnimg.cn/blog_migrate/4cf41fda455e4630abc610d575bcb1d9.jpeg)
如果只需要计算两个日期之间相差多少天,也可以直接用减法完成,A2,B2和C2中的结果如下:
![f1db45276505f4695b2f312ebb9fafcb.png](https://i-blog.csdnimg.cn/blog_migrate/5d84c19cebc3c9876157394f798a3aaa.jpeg)
![e9e50e3b0b0f74c9ef3fae50a25e58e5.png](https://i-blog.csdnimg.cn/blog_migrate/f2bb016ee0673bc55211af297b128625.jpeg)
![f1db45276505f4695b2f312ebb9fafcb.png](https://i-blog.csdnimg.cn/blog_migrate/5d84c19cebc3c9876157394f798a3aaa.jpeg)
特别的,每个日期时间数据都可以转换为一个对应的长整数,这个长整数其实就是指定的日期时间和1970年1月1日,格林威治时间0:00:00的间隔毫秒数,如:
![2cd21f4ac3d1c8ed7600af88c16f64c1.png](https://i-blog.csdnimg.cn/blog_migrate/50503e9772621a7083e4e646b033ebde.jpeg)
而在B2中,用long() 函数直接将日期时间类数据转换为长整数,可以看到A2和B2中的结果是相同的:
![da4d64493af20d74f4ce3ee5ce41e2f3.png](https://i-blog.csdnimg.cn/blog_migrate/7fcf2dd709103ae74fbdc5df69cf8513.jpeg)
![da4d64493af20d74f4ce3ee5ce41e2f3.png](https://i-blog.csdnimg.cn/blog_migrate/7fcf2dd709103ae74fbdc5df69cf8513.jpeg)
SPL中的elapse(t,k) 函数,可以根据已有的日期时间t,计算k天后的结果。添加选项@y,可以计算k年后的日期时间。类似的,还可以添加@q,@m,@s,@ms等选项,将间隔单位设定为季度,月,秒或毫秒。如:
![5b415dce322d36774f2c2440bbbc816e.png](https://i-blog.csdnimg.cn/blog_migrate/5c12d8126fa7a95b2230880afc77796f.jpeg)
A2,B2和C2中分别计算10天后,20年后和1个月前的日期,结果如下:
![31520a9af00b99b7caede0cec482ed3d.png](https://i-blog.csdnimg.cn/blog_migrate/987600d4b0fa9a3b3af1c5147952ae74.jpeg)
![4f93c6524cd122878f5c3d40e0cacd87.png](https://i-blog.csdnimg.cn/blog_migrate/4afdba5b53f0b19d899f189e91467ba0.jpeg)
![2a6ccd8c7209c3346321aac3be47c9a8.png](https://i-blog.csdnimg.cn/blog_migrate/f9cbbafd0ed084b9978b1fc203009017.jpeg)
如果只是需要计算相差若干天的日期,也可以直接简写为加减法,如=A1+10,=A1-10等。
由于每个月的天数不同,在计算k个月后的日期时,默认情况下还会考虑当前日期是否是该月的最后一天,并进行对应的调整,如果不需要这样的调整,则需要添加@e选项,如:
![d7ec50eab8e9e006fbfcd6a15545cc4a.png](https://i-blog.csdnimg.cn/blog_migrate/52208e6f5a7ece92413ecf232a2765fe.jpeg)
B1和C1中的结果如下:
![692af19a386aa260e8e895d1267b09f2.png](https://i-blog.csdnimg.cn/blog_migrate/b72fb5e5c5b16792923983f8c6668ea7.jpeg)
![8c31dffc30f252c51aaf8bacd774b677.png](https://i-blog.csdnimg.cn/blog_migrate/5295099762f254b6540e73e82dc0b36a.jpeg)
可以看到,由于2020年2月29日是2月的最后一天,B1中计算3个月后的日期时,同样得到了5月的最后一天,而C1中添加了@e选项,只计算3个月后的日期,而不做调整。
由于日期时间数据比较特殊,很多情况下并不方便直接判断是否相等。为此,可以在SPL中使用deq() 函数,只要两个数据在同一天,即认为相等。也可以添加选项@y,@q,@m@t@w等,将精度设为精确到年,季度,月,旬或周。如:
![1072958ca5e492bfce90614530cdcc9e.png](https://i-blog.csdnimg.cn/blog_migrate/fff803027c843ae2b453f1cbe58da9d7.jpeg)
A2,B2和C2中的判断结果如下:
![af09d2b7dc005e08df42aadb9572cdc1.png](https://i-blog.csdnimg.cn/blog_migrate/37a02171de75564d3889ea62a6d2825e.jpeg)
![979ac13ce9c887dbb27561ddc1386e86.png](https://i-blog.csdnimg.cn/blog_migrate/4e46981b31fa7ddc72ed9e90cde90865.jpeg)
![af09d2b7dc005e08df42aadb9572cdc1.png](https://i-blog.csdnimg.cn/blog_migrate/37a02171de75564d3889ea62a6d2825e.jpeg)
在使用日期时间数据时,还有一类计算是有关工作日的计算,用workday(t,k,h) 函数可以计算指定日期时间t后k个工作日的日期时间,用workdays(b,e,h) 可以计算开始日期b和结束日期e之间的工作日序列。有关工作日的计算比较复杂,正常的工作日是每周的周一到周五,但是有时会受公假的影响,周一到周五的某天是休息日,或者周末的某一天需要正常上班,这样的日期调整可以设置到序列h中,序列中的非周末日期是增加的假期,序列中的周末日期则是需要加班的工作日。如:
![8fef746e7bea4eea2ba1be0cb9083491.png](https://i-blog.csdnimg.cn/blog_migrate/ff66c3285ee42533b873b222ffb1e20c.jpeg)
A2中设定了2019年五一劳动节的公共假期调休情况:5月1日至5月3日的原工作日放假,而4月28日及5月5日的原周末调整为工作日。A3中计算结果如下:
![3e64ac4f502a4ff52af501fcfc251ee4.png](https://i-blog.csdnimg.cn/blog_migrate/134c225c2758c3f7c9e71d1b975a927e.jpeg)
注意2019年5月1日至3日为劳动节假期,5月4日为周末,而5月5日的原周末调整为工作日,因此2019年4月30日后的第2个工作日是2019年5月6日。
B3和C3中的结果如下:
![5223393a862f7c4ae0c9d81f368babec.png](https://i-blog.csdnimg.cn/blog_migrate/d974cdf04e5a1a8013c526681924587f.jpeg)
![050b26c96e0ae94d3e5c23d81aeae6f3.png](https://i-blog.csdnimg.cn/blog_migrate/624a4ea98af2a4e3f75cd50e9fb9c862.jpeg)
可以看到,在未指定调整日期序列的情况下,只会显示周一到周五的日期;而A3中返回的结果才是正确的工作日。
用workdays() 可以得到工作日序列,更通用的计算日期时间序列的函数是periods(s,e,i),用来计算开始日期时间b和结束日期时间e之间的日期时间序列,间隔为i天。通过添加函数选项@y,@q,@m,@t,@s,可以调整时间间隔的单位为年,季度,月,旬或秒。如果不希望设定的结束值在结果中出现,则可以添加@x选项。在时间序列中,出现的每个数据都会调整为指定时间段的第1天,如每月第1天,每年第1天等,如果不需要这种调整,可以添加@o选项。如:
![4a54c776aefcd38f0e188696616d221c.png](https://i-blog.csdnimg.cn/blog_migrate/0d0f3363adb614ce6e92eac3e640fcf8.jpeg)
A2,B2中结果如下:
![eddf184fae4fd7b54136b510260062aa.png](https://i-blog.csdnimg.cn/blog_migrate/2b92a7774a85af97cdcfa5eb8c8d0a50.jpeg)
![206e668434956f510e55750eb0e169a3.png](https://i-blog.csdnimg.cn/blog_migrate/d05169d851626dc837d6fdcbdf3e5ad7.jpeg)
其中,A2中间隔单位为日,B2中间隔单位为月。
A3中设定去除结束日期,B3中设置不调整日期到月初,C3中同时设定@o和@x选项,结果如下:
![23ea02b15b2ecdf49615d3c97fc35397.png](https://i-blog.csdnimg.cn/blog_migrate/dd6fa337108e3a1a99e6c5797883c9a3.jpeg)
![a21ebacceae5fdfe36ccf0f726804d2d.png](https://i-blog.csdnimg.cn/blog_migrate/75078e562ade4d741795a1b36f5e3b9d.jpeg)
![ddd1bd7433b3b9644356c28fda5665e6.png](https://i-blog.csdnimg.cn/blog_migrate/9cddd90b70727fb3c2b333dfd04516ce.jpeg)
有时需要将一段时间等分,此时可以使用range() 函数,如:
![880b6d04fbc6690215469a3b6c7c3737.png](https://i-blog.csdnimg.cn/blog_migrate/28ab8725b814878b3b190c79afdc18c3.jpeg)
A2中,将2019年1月1日至2020年1月1日平均分为4段,取出第1段的起止日期;B2中取出第3段的起止日期。C2中将获取平均分为4段时,包括起止时间的每个间隔日期。A2,B2和C2中结果如下:
![c13ef24b1c882c6c8b9b680d9110da86.png](https://i-blog.csdnimg.cn/blog_migrate/5bd70c216756319ff95bb1d45b5627dc.jpeg)
![8bd495bd047168aaa74bceb0b1aa8211.png](https://i-blog.csdnimg.cn/blog_migrate/6c0627b301c25cdbce163b1fc7138da7.jpeg)
![58f587f3a92fc3c6da3ddaf3bd091e75.png](https://i-blog.csdnimg.cn/blog_migrate/91923ede0820c7390b7977f8de3f8dea.jpeg)
使用range函数时,如果前两个参数为日期时间,则分段时将精确到日;如果前两个参数为日期时间,则将精确到秒。