Oracle中的時間類型只有date和TIMESTAMP,TIMESTAMP是比date更精確的類型。日期時間函數用於處理時間類型的數據,Oracle以7位數字格式來存放日期數據,包括世紀、年、月、日、小時、分鍾、秒,並且默認日期顯式格式為“DD-MON-YY”。在Oracle中准確來說一個禮拜是從星期日開始到星期六結束的,其中時間差以天數為單位。
SYSDATE:取得當前的日期和時間,類型是DATE.它沒有參數.但在分布式SQL語句中使用時,SYSDATE返回本地數據庫的日期和時間.
SYSTIMESTAMP:9i新增函數,返回當前系統的日期時間及時區。
多種日期格式:
YYYY:四位表示的年份
YYY,YY,Y:年份的最后三位、兩位或一位,缺省為當前世紀
IYYY:ISO標准的四位年份
MM:01~12的月份編號
MON:縮寫字符集表示
MONTH:全拼字符集表示的月份,右邊用空格填補
Q:季度
W:當月第幾周
WW:當年第幾周
IW:ISO標准的年中的第幾周
D:當周第幾天
DD:當月第幾天
DDD:當年第幾天
DY:縮寫字符集表示
DAY:全拼字符集表示的天 如(星期六)
HH,HH12:一天中的第幾個小時,12進制表示法
HH24:一天中的第幾個小時,取值為00~23
MI:一小時中的分鍾
SS:一分鍾中的秒
SSSS:從午夜開始過去的秒數
select to_char(sysdate, 'yyyy') 年, to_char(sysdate, 'mm') 月, to_char(sysdate, 'DD') 日, to_char(sysdate, 'HH24') 時, to_char(sysdate, 'MI') 分, to_char(sysdate, 'SS') 秒, to_char(sysdate, 'DAY') 天, to_char(sysdate, 'Q') 第幾季度, to_char(sysdate, 'W') 當月第幾周, to_char(sysdate, 'WW') 當年第幾周, to_char(sysdate, 'D') 當周第幾天, to_char(sysdate, 'DDD') 當年第幾天 from dual;
結果:
1、與date操作關系最大的就是兩個轉換函數:to_date(char[fmt[,'nls_param’]]),to_char(date[,fmt,[,nls_param]])
1.1、to_date(char[fmt[,'nls_param’]]):將字符類型按一定格式轉化為日期類型
具體用法:to_date('2004-11-27','yyyy-mm-dd'),前者為字符串,后者為轉換日期格式,注意,前后兩者要一一對應。
當時間為null時的用法:select to_date(null) from dual;
結果:
1.2、to_char(date[,fmt,[,nls_param]]):將日期轉按一定格式換成字符類型 ,fmt,nls_param為可選項,fmt指定了要轉化的格式,nls_param指定了返回日期所使用的語言

select to_char(to_date('2018-05-11','yyyy-mm-dd'),'DAY') from dual;
結果:
select to_char(to_date('2018-05-11','yyyy-mm-dd'),'DAY','NLS_DATE_LANGUAGE=American') from dual;
結果:
1.4、設置日期語言:也就是設置nls_session_parameters視圖的值
查看參數值:select * from nls_session_parameters where parameter = 'NLS_DATE_LANGUAGE';
修改時間以什么區域方式顯示,比如是要顯示MONDAY還是要顯示星期一:alter session set NLS_DATE_LANGUAGE='American';
日期格式: alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';
2、顯示數字的英文讀法:這個是oracle的特殊用法,也不常用。
select to_char(to_date(222,'J'),'Jsp') from dual;
結果:Two Hundred Twenty-Two
3、TO_TIMESTAMP(char[fmt[,'nls_param’]])函數:應注意char、fmt、nls_param之間的對應關系。

select cast(sysdate as timestamp) date_to_timestamp from dual;
4、TO_TIMESTAMP_TZ(char[fmt[,’nls_param’]])函數:將符合特定日期和時間格式的字符串轉變為TIMESTAMP WITH TIME ZONE類型。

5、current_date、current_timestamp、localtimestamp、sessiontimezone、dbtimezone函數
current_date:9i新增函數,返回當前會話時區所對應的日期時間(date型)
current_timestamp:以 timestamp with time zone 數據類型返回當前會話時區所對應的日期時間。
localtimestamp:返回當前會話時區的日期時間
sessiontimezone:返回會話時區(字符型)
dbtimezone:返回數據庫所在時區
SELECT current_date,current_timestamp,localtimestamp,sessiontimezone,dbtimezone from dual;
結果:
ZOON時區:
GMT:格林威治時間(老的時間計量標准)
UTC:協調世界時間(我們現在用的時間標准),比GTM更加標准,UTC=GMT
CST:中央標准時間 CDT:中部夏令時
PST:太平洋時間 PDT:太平洋夏令時
EST: 東部標准時間 EDT:東部夏令時間 EST=UTC-5;
6、FROM_TZ(timaezone_stamp,timezone_value)函數:將時區值和TIMESTAMP(時間戳)轉換為TIMESTAMP WITH TIME ZONE值。
結果:
7、TZ_OFFSET(time_zone_name||sessiontimezone||dbtimezone):返回特定時區與UTC相比的時區偏移。

8、SYS_EXTRACT_UTC(timestamp)函數:將一個timestamptz轉換成UTC時區的本地時間

9、NEW_TIME(date,timezone1,timezone2):計算當時區timezone1中的日期和時間是date時候,返回時區timezone2中的日期和時間
select NEW_TIME(to_date('2018-05-14 12:00:00','yyyy-mm-dd hh24:mi:ss'),'GMT','EST'),to_date('2018-05-14 12:00:00','yyyy-mm-dd hh24:mi:ss') from dual;
結果:

10、ADD_MONTHS(d,n)函數:在某一個日期d上,加上指定的月數n,n可以是任意整數。返回計算后的新日期

select floor(to_date('2018-05-03 20:00:00','yyyy-mm-dd hh24:mi:ss')-to_date('2018-05-01 12:00:00','yyyy-mm-dd hh24:mi:ss')) A from dual;
結果:

12、NumtoDSinterval(n,char_expr)函數:將數字n轉換為INTERNAL DAY TO SECOND(內部時間)格式;char_expr是一個字符串,可以是DAY\HOUR\MINUTE或SECOND。【DS表示 DAY——>SECOND】
select sysdate,sysdate+numtoDSinterval(3,'hour') from dual;
結果:

13、TO_DSINTERVAL函數:可以對日期隨意加減,如下例:對原來的時間加一天。參數格式為 天數 時,分,秒
select sysdate,TO_DSINTERVAL('01 00:00:00')+sysdate from dual;
結果:
14、NUMTOYMINTERVAL(n,char_expr)函數:將數字n轉換為INTERVAL YEAR TO MONTH格式,char_expr可以是year或者month。【YM表示 YEAR——>MONTH】
select sysdate,sysdate+numtoyminterval(3,'year') from dual;
結果:
15、TO_YMINTERVAL(char)函數:參數要求格式必須是'xx-xx'.例如'02-08' 就表示某兩個時間差了 2年零 8個月.
select sysdate,sysdate + to_yminterval('02-08') from dual;
結果:
16、Last_day(d)函數:返回包含了日期參數的月份的最后一天的日期。是處理月份天數不定的辦法,可以用來計算當月中剩余天數。
select to_char(add_months(last_day(sysdate)+1,-1),'yyyy-mm-dd'),last_day(sysdate) from dual;
結果:
17、months_between(date1,date2)函數:計算date1和date2之間相差的月數.如果date1<date2,則返回負數;如果date1,date2這兩個日期中日分量信息是相同的,或者這兩個日期都分別是所在月的最后一天,那么返回的結果是一個整數,否則包括一個小數,小數為富余天數除以31,Oracle以每月31天為准計算結果。
select months_between(to_date('2018-02-11','yyyy-mm-dd'),to_date('2018-05-11','yyyy-mm-dd'))"month" from dual;
結果:-3
select sysdate,next_day(sysdate,'星期五') next_day from dual;
結果:
19、EXTRACT(fmt FROM d)函數:提取日期中的特定部分。fmt 為:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中 YEAR、MONTH、DAY可以為 DATE 類型匹配,也可以與 TIMESTAMP 類型匹配;但是 HOUR、MINUTE、SECOND 必須與 TIMESTAMP 類型匹配。HOUR 匹配的結果中沒有加上時區,因此在中國運行的結果小 8 小時。
SELECT SYSDATE , EXTRACT(YEAR FROM SYSDATE) "year", EXTRACT(MONTH FROM SYSDATE) "month", EXTRACT(DAY FROM SYSDATE) "day", EXTRACT(HOUR FROM SYSTIMESTAMP) "hour", EXTRACT(MINUTE FROM SYSTIMESTAMP) "minute", EXTRACT(SECOND FROM SYSTIMESTAMP) "second" FROM dual;
結果:
20、ROUND(d[,fmt])函數:將日期d按照由fmt指定的格式進行四舍五入處理.如果沒有給fmt則使用缺省設置'DD'.
① 如果 fmt 為“YEAR”則舍入到某年的 1 月 1 日,即前半年舍去,后半年作為下一年。
② 如果 fmt 為“MONTH”則舍入到某月的 1 日,即前月舍去,后半月作為下一月。
③ 默認為“DD”,即月中的某一天,最靠近的天,前半天舍去,后半天作為第二天。
④ 如果 fmt 為“DAY”則舍入到最近的周的周日,即上半周舍去,下半周作為下一周周日。
SELECT SYSDATE,ROUND(SYSDATE),ROUND(SYSDATE,'day'),ROUND(SYSDATE,'month'),ROUND(SYSDATE,'year') FROM dual;
結果:
21、TRUNC(d[,format]):截斷日期時間數據,計算截尾到由format指定單位的日期d.缺省參數同ROUNG(d[,fmt]).
select sysdate,trunc(sysdate),trunc(sysdate,'year') YEAR,to_char(trunc(sysdate,'hh'),'hh24')Hours from dual;
結果:
1 select Days, 2 A, 3 trunc(A * 24) Hours, 4 trunc(A * 24 * 60 - 60 * TRUNC(A * 24)) Minutes, 5 trunc(A * 24 * 60 * 60 - 60 * TRUNC(A * 24 * 60)) Seconds, 6 trunc(A * 24 * 60 * 60 * 100 - 100 * TRUNC(A * 24 * 60 * 60)) mSeconds 7 from (select trunc(sysdate) Days, sysdate - trunc(sysdate) A from dual)
結果:
22、組合用法:
方式一:使用TO_CHAR(SYSDATE,'D')可以求得當前日期是一周的第幾天,得到的結果是星期日開始作為第1天的,那么星期一就是第2天,星期日就是第8天。
select to_char(sysdate, 'yyyy-mm-dd') 今天, decode(to_char(sysdate, 'D'), '1', '星期日', '2', '星期一', '3', '星期二', '4', '星期三', '5', '星期四', '6', '星期五', '7', '星期六') 星期幾, to_char(sysdate - to_number(to_char(sysdate, 'D')) + 2, 'yyyy-mm-dd') 星期一, to_char(sysdate - to_number(to_char(sysdate, 'D')) + 8, 'yyyy-mm-dd') 星期日 from dual;
方式二:SUBSTR代替DECODE函數,NEXT_DAY函數可以指定當前日期的下一個星期幾的日期,比如:今天是2018-5-14日,星期五,那么Next_Day(sysdate,'星期一'),得到的日期就是5-21,那么這個星期一的日期就是5-21減去7天,而星期日的日期就是5-21減去1天.
select to_char(sysdate, 'yyyy-mm-dd') 今天,'星期'||substr('日一二三四五六',to_number(to_char(sysdate,'d')),1) 星期幾, to_char(next_day(sysdate,'星期一')-7,'yyyy-mm-dd') 星期一, to_char(next_day(sysdate,'星期一')-1,'yyyy-mm-dd') 星期日 from dual;
結果:
22.2、查找2018-05-14至2018-05-01間除星期一和七的天數
select count(*) from (select rownum - 1 rnum from all_objects where rownum <= to_date('2018-05-14', 'yyyy-mm-dd') - to_date('2018-05-01', 'yyyy-mm-dd') + 1) where to_char(to_date('2018-05-01', 'yyyy-mm-dd') + rnum - 1, 'D') not in ('1', '7')
結果:
22.3、找出今年的天數:
select add_months(trunc(sysdate,'year'),12)-trunc(sysdate,'year') from dual;
結果:365
閏年的處理方法:
select to_char(last_day(to_date('2018'||'02','yyyymm')),'dd') from dual;
如果是28就不是閏年
22.4、五秒鍾一個間隔:
select to_char(sysdate, 'SSSSS') / 300, floor(to_char(sysdate, 'SSSSS') / 300), floor(to_char(sysdate, 'SSSSS') / 300) * 300, to_date(floor(to_char(sysdate, 'SSSSS') / 300) * 300, 'SSSSS')隔五秒一個間隔 from dual;
結果:
22.5、查找月的第一天,最后一天
SELECT sysdate, Trunc(SYSDATE, 'MONTH') - 1 / 86400 Last_Day_Last_Month, Trunc(SYSDATE, 'MONTH') First_Day_Cur_Month, (Trunc(SYSDATE, 'MONTH')) + 1 - 1 / 86400 Last_Day_Cur_Month FROM dual;
結果:
22.6、查詢某周的第一天,例如2018年第二周。
方法一:
select trunc(decode(ww, 53, to_date(yy || '1231', 'yyyymmdd'), to_date(yy || '-' || to_char(ww * 7), 'yyyy-ddd')), 'd') - 6 first_day from (select substr('2018-2', 1, 4) yy, to_number(substr('2018-2', 6)) ww from dual);
方法二:
select trunc(to_date(substr('2018-2',1,5)||to_char((to_number(substr('2018-2',6)))*7),'yyyy-ddd'),'d')-6 first_day from dual;
方法三:
-
select min(v_date) first_day
-
from (select (to_date('201801', 'yyyymm') + rownum-1) v_date
-
from all_tables
-
where rownum < 370)
-
where to_char(v_date, 'yyyy-iw') = '2018-02';
結果:
22.7、查詢某周的最后一天
方法一:
-
select trunc(decode(ww,
-
53,
-
to_date(yy || '1231', 'yyyymmdd'),
-
to_date(yy || '-' || to_char(ww * 7), 'yyyy-ddd')),
-
'd') last_day
-
from (select substr('2018-02', 1, 4) yy, to_number(substr('2018-02', 6)) ww
-
from dual);
方法二:
select trunc(to_date(substr('2018-02',1,5)||to_char((to_number(substr('2018-02',6)))*7),'yyyy-ddd'),'d') last_day from dual
方法三:
-
select max(v_date) last_day
-
from (select (to_date('201801', 'yyyymm') + rownum-1) v_date
-
from all_tables
-
where rownum < 370)
-
where to_char(v_date, 'yyyy-iw') = '2018-02';
22.8、查詢某周的日期
一、
select v_date,to_char( v_date, 'day') day from (select (to_date('201801', 'yyyymm') + rownum - 1) v_date from all_tables where rownum < 370) where to_char(v_date, 'yyyy-ww') = '2018-01';
二、
select min_date, to_char(min_date, 'day') day from (select to_date(substr('2018-01', 1, 4) || '001' + rownum - 1, 'yyyyddd') min_date from all_tables where rownum <= decode(mod(to_number(substr('2018-01', 1, 4)), 4), 0, 366, 365) union select to_date(substr('2018-01', 1, 4) - 1 || decode(mod(to_number(substr('2018-01', 1, 4)) - 1, 4), 0, 359, 358) + rownum, 'yyyyddd') min_date from all_tables where rownum <= 7 union select to_date(substr('2018-01', 1, 4) + 1 || '001' + rownum - 1, 'yyyyddd') min_date from all_tables where rownum <= 7) where to_char(min_date, 'yyyy-ww') = '2018-01';
結果: