六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 86|回复: 0

DB2日期时间函数

[复制链接]

升级  50%

35

主题

35

主题

35

主题

秀才

Rank: 2

积分
125
 楼主| 发表于 2013-1-13 18:58:40 | 显示全部楼层 |阅读模式
日期函数
有时,您需要知道两个时间戳记之间的时差。为此,DB2 提供了一个名为 TIMESTAMPDIFF() 的内置函数。但该函数返回的是近似值,因为它不考虑闰年,而且假设每个月只有 30 天。以下示例描述了如何得到两个日期的近似时差:
timestampdiff (<n>, char(timestamp('2002-11-30-00.00.00')-timestamp('2002-11-08-00.00.00')))
 
对于 <n>,可以使用以下各值来替代,以指出结果的时间单位:

  • 1 = 秒的小数部分
  • 2 = 秒
  • 4 = 分
  • 8 = 时
  • 16 = 天
  • 32 = 周
  • 64 = 月
  • 128 = 季度
  • 256 = 年
当日期很接近时使用 timestampdiff() 比日期相差很大时精确。如果需要进行更精确的计算,可以使用以下方法来确定时差(按秒计):
(DAYS(t1) - DAYS(t2)) * 86400 +  (MIDNIGHT_SECONDS(t1) - MIDNIGHT_SECONDS(t2))
 
为方便起见,还可以对上面的方法创建 SQL 用户定义的函数:
CREATE FUNCTION secondsdiff(t1 TIMESTAMP, t2 TIMESTAMP)RETURNS INTRETURN ((DAYS(t1) - DAYS(t2)) * 86400 +  (MIDNIGHT_SECONDS(t1) - MIDNIGHT_SECONDS(t2)))@
 
如果需要确定给定年份是否是闰年,以下是一个很有用的 SQL 函数,您可以创建它来确定给定年份的天数:
CREATE FUNCTION daysinyear(yr INT)RETURNS INTRETURN (CASE (mod(yr, 400)) WHEN 0 THEN 366 ELSE         CASE (mod(yr, 4))   WHEN 0 THEN         CASE (mod(yr, 100)) WHEN 0 THEN 365 ELSE 366 END         ELSE 365 ENDEND)@
 
最后,以下是一张用于日期操作的内置函数表。它旨在帮助您快速确定可能满足您要求的函数,但未提供完整的参考。有关这些函数的更多信息,请参考 SQL 参考大全。
SQL 日期和时间函数
DAYNAME返回一个大小写混合的字符串,对于参数的日部分,用星期表示这一天的名称(例如,Friday)。
DAYOFWEEK返回参数中的星期几,用范围在 1-7 的整数值表示,其中 1 代表星期日。
DAYOFWEEK_ISO返回参数中的星期几,用范围在 1-7 的整数值表示,其中 1 代表星期一。
DAYOFYEAR返回参数中一年中的第几天,用范围在 1-366 的整数值表示。
DAYS返回日期的整数表示。
JULIAN_DAY返回从公元前 4712 年 1 月 1 日(儒略日历的开始日期)到参数中指定日期值之间的天数,用整数值表示。
MIDNIGHT_SECONDS返回午夜和参数中指定的时间值之间的秒数,用范围在 0 到 86400 之间的整数值表示。
MONTHNAME对于参数的月部分的月份,返回一个大小写混合的字符串(例如,January)。
TIMESTAMP_ISO根据日期、时间或时间戳记参数而返回一个时间戳记值。
TIMESTAMP_FORMAT从已使用字符模板解释的字符串返回时间戳记。
TIMESTAMPDIFF根据两个时间戳记之间的时差,返回由第一个参数定义的类型表示的估计时差。
TO_CHAR返回已用字符模板进行格式化的时间戳记的字符表示。TO_CHAR 是 VARCHAR_FORMAT 的同义词。
TO_DATE从已使用字符模板解释过的字符串返回时间戳记。TO_DATE 是 TIMESTAMP_FORMAT 的同义词。
WEEK返回参数中一年的第几周,用范围在 1-54 的整数值表示。以星期日作为一周的开始。
WEEK_ISO返回参数中一年的第几周,用范围在 1-53 的整数值表示。
 
[img=100%,1]http://www.ibm.com/i/v14/rules/blue_rule.gif[/img]
[img=100%,4]http://www.ibm.com/i/c.gif[/img]


定制日期/时间格式
在上面的例子中,我们展示了如何将 DB2 当前的日期格式转化成系统支持的特定格式。但是,如果你想将当前日期格式转化成定制的格式(比如‘yyyymmdd’),那又该如何去做呢?按照我的经验,最好的办法就是编写一个自己定制的格式化函数。
下面是这个 UDF 的代码:
create function ts_fmt(TS timestamp, fmt varchar(20))returns varchar(50)returnwith tmp (dd,mm,yyyy,hh,mi,ss,nnnnnn) as(    select    substr( digits (day(TS)),9),    substr( digits (month(TS)),9) ,    rtrim(char(year(TS))) ,    substr( digits (hour(TS)),9),    substr( digits (minute(TS)),9),    substr( digits (second(TS)),9),    rtrim(char(microsecond(TS)))    from sysibm.sysdummy1    )selectcase fmt    when 'yyyymmdd'        then yyyy || mm || dd    when 'mm/dd/yyyy'        then mm || '/' || dd || '/' || yyyy    when 'yyyy/dd/mm hh:mi:ss'        then yyyy || '/' || mm || '/' || dd || ' ' ||                hh || ':' || mi || ':' || ss    when 'nnnnnn'        then nnnnnn    else        'date format ' || coalesce(fmt,' <null> ') ||         ' not recognized.'    endfrom tmp
 
乍一看,函数的代码可能显得很复杂,但是在仔细研究之后,你会发现这段代码其实非常简单而且很优雅。最开始,我们使用了一个公共表表达式(CTE)来将一个时间戳记(第一个输入参数)分别剥离为单独的时间元素。然后,我们检查提供的定制格式(第二个输入参数)并将前面剥离出的元素按照该定制格式的要求加以组合。
这个函数还非常灵活。如果要增加另外一种模式,可以很容易地再添加一个 WHEN 子句来处理。在使用过程中,如果用户提供的格式不符合任何在 WHEN 子句中定义的任何一种模式时,函数会返回一个错误信息。
使用方法示例:
values ts_fmt(current timestamp,'yyyymmdd') '20030818'values ts_fmt(current timestamp,'asa')  'date format asa not recognized.'
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表