oracle 日期处理总结

转换的格式:

表示year的:y 表示年的最后一位 yy 表示年的最后2位 yyy 表示年的最后3位 yyyy 用4位数表示年

表示month的:mm 用2位数字表示月;mon 用简写形式 比如11月或者nov ;month 用全称 比如11月或者november

表示day的:dd 表示当月第几天;ddd表示当年第几天;dy 当周第几天 简写 比如星期五或者fri;day当周第几天 全写

比如星期五或者friday。

表示hour的:hh 2位数表示小时 12进制; hh24 2位数表示小时 24小时

表示minute的:mi 2位数表示分钟

表示second的:ss 2位数表示秒 60进制

表示季度的:q 一位数 表示季度 (1-4)

另外还有ww 用来表示当年第几周 w用来表示当月第几周。

24小时制下的时间范围:00:00:00-23:59:59

12小时制下的时间范围:1:00:00-12:59:59

比如:

select to_char(sysdate,’yy-mm-dd hh24:mi:ss’) from dual //显示:08-11-07 13:22:42

select to_date(‘2005-12-25,13:25:59’,’yyyy-mm-dd,hh24:mi:ss’) from dual //显示:2005-12-25 13:25:59

而如果把上式写作:select to_date(‘2005-12-25,13:25:59’,’yyyy-mm-dd,hh:mi:ss’) from dual,则会报错,因为小时hh是12进制,13为非法输入,不能匹配。

补充:

当前时间减去7分钟的时间 
select sysdate,sysdate - interval ‘7’ MINUTE from dual 
当前时间减去7小时的时间 
select sysdate - interval ‘7’ hour from dual 
当前时间减去7天的时间 
select sysdate - interval ’7’ day from dual 
当前时间减去7月的时间 
select sysdate,sysdate - interval ‘7’ month from dual 
当前时间减去7年的时间 
select sysdate,sysdate - interval ‘7’ year from dual 
时间间隔乘以一个数字 
select sysdate,sysdate - 8*interval ‘7’ hour from dual

Dual伪列

含义解释:

Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的select语句块中。

比如,我要获得系统时间,则用“select sysdate from dual” 则返回系统当前的时间:2008-11-07 9:32:49,不同系统可能返回日期的格式不一样。”select user from dual”则返回当前连接的用户。如果是”select 1+2 from dual”,则返回结果:3

来自:http://hi.baidu.com/xkf007/blog/item/eb21d983b92e78b30cf4d2a5.html

TO_DATE格式(以时间:2007-11-02 13:45:25为例)

    Year:      
    yy two digits 两位年                显示值:07
    yyy three digits 三位年                显示值:007
    yyyy four digits 四位年                显示值:2007

    Month:      
    mm    number     两位月              显示值:11
    mon    abbreviated 字符集表示          显示值:11月,若是英文版,显示nov     
    month spelled out 字符集表示          显示值:11月,若是英文版,显示november 

    Day:      
    dd    number         当月第几天        显示值:02
    ddd    number         当年第几天        显示值:02
    dy    abbreviated 当周第几天简写    显示值:星期五,若是英文版,显示fri
    day    spelled out   当周第几天全写    显示值:星期五,若是英文版,显示friday        
    ddspth spelled out, ordinal twelfth 

          Hour:
          hh    two digits 12小时进制            显示值:01
          hh24 two digits 24小时进制            显示值:13

          Minute:
          mi    two digits 60进制                显示值:45

          Second:
          ss    two digits 60进制                显示值:25

          其它
          Q     digit         季度                  显示值:4
          WW    digit         当年第几周            显示值:44
          W    digit          当月第几周            显示值:1

    24小时格式下时间范围为: 0:00:00 - 23:59:59....      
    12小时格式下时间范围为: 1:00:00 - 12:59:59 .... 
  1. 日期和字符转换函数用法(to_date,to_char)

select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) as nowTime from dual; //日期转化为字符串 
select to_char(sysdate,’yyyy’) as nowYear from dual; //获取时间的年 
select to_char(sysdate,’mm’) as nowMonth from dual; //获取时间的月 
select to_char(sysdate,’dd’) as nowDay from dual; //获取时间的日 
select to_char(sysdate,’hh24’) as nowHour from dual; //获取时间的时 
select to_char(sysdate,’mi’) as nowMinute from dual; //获取时间的分 
select to_char(sysdate,’ss’) as nowSecond from dual; //获取时间的秒

select to_date(‘2004-05-07 13:23:44’,’yyyy-mm-dd hh24:mi:ss’) from dual//

  1. select to_char( to_date(222,’J’),’Jsp’) from dual

    显示Two Hundred Twenty-Two

3.求某天是星期几 
select to_char(to_date(‘2002-08-26’,’yyyy-mm-dd’),’day’) from dual; 
星期一 
select to_char(to_date(‘2002-08-26’,’yyyy-mm-dd’),’day’,’NLS_DATE_LANGUAGE = American’) from dual; 
monday 
设置日期语言 
ALTER SESSION SET NLS_DATE_LANGUAGE=’AMERICAN’; 
也可以这样 
TO_DATE (‘2002-08-26’, ‘YYYY-mm-dd’, ‘NLS_DATE_LANGUAGE = American’)

  1. 两个日期间的天数 
    select floor(sysdate - to_date(‘20020405’,’yyyymmdd’)) from dual;

  2. 时间为null的用法 
    select id, active_date from table1 
    UNION 
    select 1, TO_DATE(null) from dual;

    注意要用TO_DATE(null)

6.月份差 
a_date between to_date(‘20011201’,’yyyymmdd’) and to_date(‘20011231’,’yyyymmdd’) 
那么12月31号中午12点之后和12月1号的12点之前是不包含在这个范围之内的。 
所以,当时间需要精确的时候,觉得to_char还是必要的

  1. 日期格式冲突问题 
    输入的格式要看你安装的ORACLE字符集的类型, 比如: US7ASCII, date格式的类型就是: ‘01-Jan-01’ 
    alter system set NLS_DATE_LANGUAGE = American 
    alter session set NLS_DATE_LANGUAGE = American 
    或者在to_date中写 
    select to_char(to_date(‘2002-08-26’,’yyyy-mm-dd’),’day’,’NLS_DATE_LANGUAGE = American’) from dual; 
    注意我这只是举了NLS_DATE_LANGUAGE,当然还有很多, 
    可查看 
    select * from nls_session_parameters 
    select * from V$NLS_PARAMETERS

  2. select count(*) 
    from ( select rownum-1 rnum 
    from all_objects 
    where rownum <= to_date(‘2002-02-28’,’yyyy-mm-dd’) - to_date(‘2002- 
    02-01’,’yyyy-mm-dd’)+1 

    where to_char( to_date(‘2002-02-01’,’yyyy-mm-dd’)+rnum-1, ‘D’ ) 
    not in ( ‘1’, ‘7’ )

    查找2002-02-28至2002-02-01间除星期一和七的天数 
    在前后分别调用DBMS_UTILITY.GET_TIME, 让后将结果相减(得到的是1/100秒, 而不是毫秒).

  3. 查找月份 
    select months_between(to_date(‘01-31-1999’,’MM-DD-YYYY’),to_date(‘12-31-1998’,’MM-DD-YYYY’)) “MONTHS” FROM DUAL; 

    select months_between(to_date(‘02-01-1999’,’MM-DD-YYYY’),to_date(‘12-31-1998’,’MM-DD-YYYY’)) “MONTHS” FROM DUAL; 
    1.03225806451613

  4. Next_day的用法 
    Next_day(date, day)

    Monday-Sunday, for format code DAY 
    Mon-Sun, for format code DY 
    1-7, for format code D

11 
select to_char(sysdate,’hh:mi:ss’) TIME from all_objects 
注意:第一条记录的TIME 与最后一行是一样的 
可以建立一个函数来处理这个问题 
create or replace function sys_date return date is 
begin 
return sysdate; 
end;

select to_char(sys_date,’hh:mi:ss’) from all_objects;

12.获得小时数 
extract()找出日期或间隔值的字段值 
SELECT EXTRACT(HOUR FROM TIMESTAMP ‘2001-02-16 2:38:40’) from offer 
SQL> select sysdate ,to_char(sysdate,’hh’) from dual;

SYSDATE TO_CHAR(SYSDATE,'HH')      
-------------------- ---------------------      
2003-10-13 19:35:21 07      

SQL> select sysdate ,to_char(sysdate,'hh24') from dual;      

SYSDATE TO_CHAR(SYSDATE,'HH24')      
-------------------- -----------------------      
2003-10-13 19:35:21 19    

13.年月日的处理 
select older_date, 
newer_date, 
years, 
months, 
abs( 
trunc( 
newer_date- 
add_months( older_date,years*12+months ) 

) days

from ( select 
trunc(months_between( newer_date, older_date )/12) YEARS, 
mod(trunc(months_between( newer_date, older_date )),12 ) MONTHS, 
newer_date, 
older_date 
from ( 
select hiredate older_date, add_months(hiredate,rownum)+rownum newer_date 
from emp 

)

14.处理月份天数不定的办法 
select to_char(add_months(last_day(sysdate) +1, -2), ‘yyyymmdd’),last_day(sysdate) from dual

16.找出今年的天数 
select add_months(trunc(sysdate,’year’), 12) - trunc(sysdate,’year’) from dual

闰年的处理方法 
to_char( last_day( to_date(‘02’ | | :year,’mmyyyy’) ), ‘dd’ ) 
如果是28就不是闰年

17.yyyy与rrrr的区别 
‘YYYY99 TO_C


yyyy 99 0099 
rrrr 99 1999 
yyyy 01 0001 
rrrr 01 2001

18.不同时区的处理 
select to_char( NEW_TIME( sysdate, ‘GMT’,’EST’), ‘dd/mm/yyyy hh:mi:ss’) ,sysdate 
from dual;

19.5秒钟一个间隔 
Select TO_DATE(FLOOR(TO_CHAR(sysdate,’SSSSS’)/300) * 300,’SSSSS’) ,TO_CHAR(sysdate,’SSSSS’) 
from dual

2002-11-1 9:55:00 35786 
SSSSS表示5位秒数

20.一年的第几天 
select TO_CHAR(SYSDATE,’DDD’),sysdate from dual

310 2002-11-6 10:03:51

21.计算小时,分,秒,毫秒 
select 
Days, 
A, 
TRUNC(A*24) Hours, 
TRUNC(A*24*60 - 60*TRUNC(A*24)) Minutes, 
TRUNC(A*24*60*60 - 60*TRUNC(A*24*60)) Seconds, 
TRUNC(A*24*60*60*100 - 100*TRUNC(A*24*60*60)) mSeconds 
from 

select 
trunc(sysdate) Days, 
sysdate - trunc(sysdate) A 
from dual 
)

select * from tabname 
order by decode(mode,’FIFO’,1,-1)*to_char(rq,’yyyymmddhh24miss’);

// 
floor((date2-date1) /365) 作为年 
floor((date2-date1, 365) /30) 作为月 
d(mod(date2-date1, 365), 30)作为日.

23.next_day函数 返回下个星期的日期,day为1-7或星期日-星期六,1表示星期日 
next_day(sysdate,6)是从当前开始下一个星期五。后面的数字是从星期日开始算起。 
1 2 3 4 5 6 7 
日 一 二 三 四 五 六


select (sysdate-to_date(‘2003-12-03 12:55:45’,’yyyy-mm-dd hh24:mi:ss’))*24*60*60 from ddual 
日期 返回的是天 然后 转换为ss

24,round舍入到最接近的日期 
select sysdate S1, 
round(sysdate) S2 , 
round(sysdate,’year’) YEAR, 
round(sysdate,’month’) MONTH , 
round(sysdate,’day’) DAY from dual

25,trunc[截断到最接近的日期,单位为天] ,返回的是日期类型 
select sysdate S1, 
trunc(sysdate) S2, //返回当前日期,无时分秒 
trunc(sysdate,’year’) YEAR, //返回当前年的1月1日,无时分秒 
trunc(sysdate,’month’) MONTH , //返回当前月的1日,无时分秒 
trunc(sysdate,’day’) DAY //返回当前星期的星期天,无时分秒 
from dual

26,返回日期列表中最晚日期 
select greatest(‘01-1月-04’,’04-1月-04’,’10-2月-04’) from dual

27.计算时间差 
注:oracle时间差是以天数为单位,所以换算成年月,日

  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))/365) as spanYears from dual        //时间差-年
  select ceil(moths_between(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanMonths from dual        //时间差-月
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanDays from dual             //时间差-天
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24) as spanHours from dual         //时间差-时
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60) as spanMinutes from dual    //时间差-分
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60*60) as spanSeconds from dual //时间差-秒

28.更新时间 
注:oracle时间加减是以天数为单位,设改变量为n,所以换算成年月,日 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n*365,’yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-年 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),add_months(sysdate,n) as newTime from dual //改变时间-月 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n,’yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-日 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24,’yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-时 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24/60,’yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-分 
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24/60/60,’yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-秒

29.查找月的第一天,最后一天 
SELECT Trunc(Trunc(SYSDATE, ‘MONTH’) - 1, ‘MONTH’) First_Day_Last_Month, 
Trunc(SYSDATE, ‘MONTH’) - 1 / 86400 Last_Day_Last_Month, 
Trunc(SYSDATE, ‘MONTH’) First_Day_Cur_Month, 
LAST_DAY(Trunc(SYSDATE, ‘MONTH’)) + 1 - 1 / 86400 Last_Day_Cur_Month 
FROM dual;

 

表 5-7. 格式化函数 
 
函数返回描述例子
to_char(timestamp, text) text 把 timestamp 转换成 string to_char(timestamp 'now','HH12:MI:SS')
to_char(int, text) text 把 int4/int8 转换成 string to_char(125, '999')
to_char(float, text) text 把 float4/float8 转换成 string to_char(125.8, '999D9')
to_char(numeric, text) text 把 numeric 转换成 string to_char(numeric '-125.8', '999D99S')
to_date(text, text) date 把 string 转换成 date to_date('05 Dec 2000', 'DD Mon YYYY')
to_timestamp(text, text) date 把 string 转换成 timestamp to_timestamp('05 Dec 2000', 'DD Mon YYYY')
to_number(text, text) numeric 把 string 转换成 numeric to_number('12,454.8-', '99G999D9S')

表 5-8. 用于 date/time 转换的模板 
 

模板描述
HH 一天的小时数 (01-12)
HH12 一天的小时数 (01-12)
HH24 一天的小时数 (00-23)
MI 分钟 (00-59)
SS 秒 (00-59)
SSSS 午夜后的秒 (0-86399)
AM or A.M. or PM or P.M. 正午标识(大写)
am or a.m. or pm or p.m. 正午标识(小写)
Y,YYY 带逗号的年(4 和更多位)
YYYY 年(4和更多位)
YYY 年的后三位
YY 年的后两位
Y 年的最后一位
BC or B.C. or AD or A.D. 年标识(大写)
bc or b.c. or ad or a.d. 年标识(小写)
MONTH 全长大写月份名(9字符)
Month 全长混合大小写月份名(9字符)
month 全长小写月份名(9字符)
MON 大写缩写月份名(3字符)
Mon 缩写混合大小写月份名(3字符)
mon 小写缩写月份名(3字符)
MM 月份 (01-12)
DAY 全长大写日期名(9字符)
Day 全长混合大小写日期名(9字符)
day 全长小写日期名(9字符)
DY 缩写大写日期名(3字符)
Dy 缩写混合大小写日期名(3字符)
dy 缩写小写日期名(3字符)
DDD 一年里的日子(001-366)
DD 一个月里的日子(01-31)
D 一周里的日子(1-7;SUN=1)
W 一个月里的周数
WW 一年里的周数
CC 世纪(2 位)
J Julian 日期(自公元前4712年1月1日来的日期)
Q 季度
RM 罗马数字的月份(I-XII;I=JAN)-大写
rm 罗马数字的月份(I-XII;I=JAN)-小写

所有模板都都允许使用前缀和后缀修改器。模板里总是允许使用修改器。前缀 'FX' 只是一个全局修改器。

表 5-9. 用于日期/时间模板 to_char() 的后缀 
 

后缀描述例子
FM 填充模式前缀 FMMonth
TH 大写顺序数后缀 DDTH
th 小写顺序数后缀 DDTH
FX 固定模式全局选项(见下面) FX Month DD Day
SP 拼写模式(还未实现) DDSP

用法须知:

  • 如果没有使用 FX 选项,to_timestamp 和 to_date 忽略空白。FX 必须做为模板里的第一个条目声明。
  • 反斜杠("\")必须用做双反斜杠("\\"),例如 '\\HH\\MI\\SS'
  • 双引号('"')之间的字串被忽略并且不被分析。如果你想向输出写双引号,你必须在双引号前面放置一个双反斜杠('\\'),例如 '\\"YYYY Month\\"'
  • to_char 支持不带前导双引号('"')的文本,但是在双引号之间的任何字串会被迅速处理并且还保证不会被当作模板关键字解释(例如:'"Hello Year: "YYYY')。
表 5-10. 用于 to_char(numeric) 的模板 
 
模板描述
9 带有指定位数的值
0 前导零的值
. (句点) 小数
, (逗号) 分组(千)分隔符
PR 尖括号内负值
S 带负号的负值(使用本地化)
L 货币符号(使用本地化)
D 小数点(使用本地化)
G 分组分隔符(使用本地化)
MI 在指明的位置的负号(如果数字 < 0)
PL 在指明的位置的正号(如果数字 > 0)
SG 在指明的位置的正/负号
RN 罗马数字(输入在 1 和 3999 之间)
TH or th 转换成序数
V 移动 n 位(小数)(参阅注解)
EEEE 科学记数。现在不支持。

用法须知:

  • 使用 'SG','PL' 或 'MI' 的带符号字并不附着在数字上面;例如,to_char(-12, 'S9999') 生成 ' -12',而 to_char(-12, 'MI9999') 生成 '- 12'Oracle 里的实现不允许在 9 前面使用 MI,而是要求 9 在 MI 前面。
  • PLSG,和 TH 是 Postgres 扩展。
  • 9 表明一个与在 9 字串里面的一样的数字位数。如果没有可用的数字,那么使用一个空白(空格)。
  • TH 不转换小于零的值,也不转换小数TH 是一个 Postgres 扩展。
  • V 方便地把输入值乘以 10^n,这里 n 是跟在 V 后面的数字。to_char 不支持把 V 与一个小数点绑在一起使用(例如. "99.9V99" 是不允许的)。
表 5-11. to_char 例子 
 
输入输出
to_char(now(),'Day, HH12:MI:SS') 'Tuesday , 05:39:18'
to_char(now(),'FMDay, HH12:MI:SS') 'Tuesday, 05:39:18'
to_char(-0.1,'99.99') ' -.10'
to_char(-0.1,'FM9.99') '-.1'
to_char(0.1,'0.9') ' 0.1'
to_char(12,'9990999.9') ' 0012.0'
to_char(12,'FM9990999.9') '0012'
to_char(485,'999') ' 485'
to_char(-485,'999') '-485'
to_char(485,'9 9 9') ' 4 8 5'
to_char(1485,'9,999') ' 1,485'
to_char(1485,'9G999') ' 1 485'
to_char(148.5,'999.999') ' 148.500'
to_char(148.5,'999D999') ' 148,500'
to_char(3148.5,'9G999D999') ' 3 148,500'
to_char(-485,'999S') '485-'
to_char(-485,'999MI') '485-'
to_char(485,'999MI') '485'
to_char(485,'PL999') '+485'
to_char(485,'SG999') '+485'
to_char(-485,'SG999') '-485'
to_char(-485,'9SG99') '4-85'
to_char(-485,'999PR') '<485>'
to_char(485,'L999') 'DM 485
to_char(485,'RN') ' CDLXXXV'
to_char(485,'FMRN') 'CDLXXXV'
to_char(5.2,'FMRN') V
to_char(482,'999th') ' 482nd'
to_char(485, '"Good number:"999') 'Good number: 485'
to_char(485.8,'"Pre-decimal:"999" Post-decimal:" .999') 'Pre-decimal: 485 Post-decimal: .800'
to_char(12,'99V999') ' 12000'
to_char(12.4,'99V999') ' 12400'
to_char(12.45, '99V9') ' 125'
posted @ 2018-05-04 11:38  积极解放  阅读(855)  评论(0)    收藏  举报