marb 发表于 2013-1-13 18:58:40

DB2日期时间函数

日期函数
有时,您需要知道两个时间戳记之间的时差。为此,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 的整数值表示。 
http://www.ibm.com/i/v14/rules/blue_rule.gif
http://www.ibm.com/i/c.gifhttp://www.ibm.com/i/c.gif


定制日期/时间格式
在上面的例子中,我们展示了如何将 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.'
页: [1]
查看完整版本: DB2日期时间函数