posts - 262,  comments - 221,  trackbacks - 0
          目錄
          =========================================
          1.Oracle的日期函數
          2.日期加減
          3.月份加減
          4.年份加減
          5.求每月的最后一天
          6.求每月的第一天
          7.求下一個星期幾

          入門知識:

          ①Oracle中的日期時間存儲:
          oracle數據庫中存放時間格式的數據,是以oracle特定的格式存貯的,占7個字節,與查詢時顯示的時間格式無關。不存貯秒以下的時間單位。
          ②Oracle中的日期時間顯示:
          通常,客戶端與數據庫建立起連接后,oracle就會給一個缺省的時間格式數據的顯示形式,與所使用的字符集有關。一般顯示年月日,而不顯示時分秒。
          ③Oracle中的日期時間插入:
          向表中插入數據時,如果不使用轉換函數,則時間字段的格式必須遵從會話環境的時間格式,否則不能插入。
          ④Oracle中的日期時間格式修改:
          a.SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
          b.冊表\hkey_local_machine\software\oracle\home0主鍵中增加一個字串(8i版本),字串名為nls_date_format,字串的值為你希望定義的時間格式
          前者只對當前會話有效,也即是一旦你關閉了SQL*PLUS窗口或重新打開一個SQL*PLUS窗口,日期時間格式依然采用本地字符集對應的日期時間格式。后者對所有客戶端應用有效。當兩者同時應用時,以alter session的修改為準。


          一、Oracle的日期函數:

          Oracle從8i開始就提供了大量的日期函數,這些日期函數包括對日期進行加減、轉換、截取等功能。下面是Oracle提供的日期函數一覽表 

          Function

          Use

          ADD_MONTHS

          Adds months to a date

          LAST_DAY

          Computes the last day of the month

          MONTHS_BETWEEN

          Determines the number of months between two dates

          NEW_TIME

          Translates a time to a new time zone

          NEXT_DAY

          Returns the date of the next specified weekday

          ROUND

          Rounds a date/time value to a specified element

          SYSDATE

          Returns the current date and time

          TO_CHAR

          Converts dates to strings

          TO_DATE

          Converts strings and numbers to dates

          TRUNC

          Truncates a date/time value to a specific element


          二、日期加減:

          在Oralce中,對日期進行加減操作的默認單位是天,也就是說如果我們向當前日期加1的話是加上一天,而不是一秒或一小時。那么對一天中的一段時間進行加減要怎么做呢?很簡單!只需將它們轉化為以天為單位即可。

          【1】為當前時間加上30分鐘:
          SQL> select to_char(sysdate, 'yyyy-mm-dd hh:mi:ss') now_date,
            
          2             to_char(sysdate+(30/24/60), 'yyyy-mm-dd hh:mi:ss'new_date
            
          3    from dual;

          NOW_DATE                               NEW_DATE
          -------------------------------------- --------------------------------------
          2008-06-30 10:47:31                    2008-06-30 11:17:31

          SQL
          > 

          我們看到了在綠色高亮處使用30/24/60將分鐘轉換成天。另外一個要注意的地方是:SQL*PLUS環境下默認的日期格式:NLS_DATE_FORMAT是DD-MM-YYYY,也即是不包含時、分、秒,所以我們這里必須采用to_char的方式指定輸入的日期格式。

          除此之外也可以通過在SQL*PLUS中執行下列語句修改默認的日期輸出格式,這樣的話就不需要通過to_char來轉換了,直接輸出就行。
          alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

          【2】為當前時間減去30分鐘:
          SQL> select to_char(sysdate+(-30/24/60),'yyyy-mm-dd hh:mi:ss') new_date from dual;

          NEW_DATE
          --------------------------------------
          2008-06-30 10:24:59

          只需要加上一個負數即可以了。

          三、月份加減:

          月份的加減和日期加減相比要難了很多,因為每個月份的天數并不是固定的,可能是31,30,29,28。如果采用上面的方法將月份轉換成實際天數將不可避免地出現多個判斷,幸虧Oracle為我們提供了一個add_months函數,這個函數會自動判斷月份的天數??纯聪旅娴睦樱?br />
          【1】為當前時間加上6個月:
          SQL> select add_months(sysdate, 6from dual;

          ADD_MONTHS
          ----------

          31-12月-08

          【2】為當前時間減去6個月:
          SQL> select add_months(sysdate, -6from dual;

          ADD_MONTHS
          ----------

          31-12月-07

          【3】求兩個日期相差的月數:

          通常情況下兩個時間相減將得到以天數為單位的結果,可是有時我們更希望得到以月為單位的結果,如果手動轉換這太麻煩了,所以Oracle又提供了一個函數,這個函數就是months_between。
          SQL> select months_between(sysdate,
            
          2         to_date('2008-01-01 01:00:00''yyyy-mm-dd hh:mi:ss')) result
            
          3    from dual;

              RESULT
          ----------
          5.94928203

          months_between函數有2個參數,第一個參數是結束日期,第二個參數是開始日期,Oracle用第一個參數減去第二個參數得到月份數。所以結果有可能會是負數的。

          四、年份加減:

          Oracle并不直接提供對年份進行加減的函數,不過有了add_months和months_between函數,我們照樣可以做到。

          【1】為當前日期加上2年:
          SQL> select add_months(sysdate, 2*12) two_years_later
            
          2      from dual;

          TWO_YEARS_
          ----------
          30-6月 -10

          【2】求兩個日期相差幾年:
          SQL> select months_between(sysdate, 
            
          2         to_date('2006-06-30''yyyy-mm-dd')) / 12 years_between
            
          3    from dual;

          YEARS_BETWEEN
          -------------
                      2

          直接將兩個日期相減,然后除以365天并不準確,但是不管一年有多少天它總是只有12個月,所以利用這一點我們可以先求出兩個日期相差的月數,再除以12就得出相差的年數了

          五、求每月的最后一天:

          SQL> select last_day(add_months(sysdate,2)) last_day
            
          2    from dual;

          LAST_DAY
          ----------
          31-8月 -08

          六、求每月的第一天:

          Oracle提供了last_day讓我們能夠求出所在月份的最后一天,但沒有對應的first_day函數,如果有這方面的需求,只需要稍微動一下腦筋,利用last_day函數即可。例如下面的SQL語句就是求出下個月的第一天:
          SQL> select last_day(sysdate)+1 fisrt_day
            
          2      from dual;

          FISRT_DAY
          ----------
          01-7月 -08

          在這里我們將“每月的第一天”轉換成“上個月最后一天的下一天”,問題就解決了!

          七、求下一個星期幾:

          有時候我們會碰上“下個星期五是幾號???”這樣常見的問題。Oracle為此提供了一個函數:next_day,它的語法是這樣的:next_day(date, string)。其中第一個參數date告訴Oracle從什么時候開始算起,第二個參數string則告訴Oracle要取的工作日。

          下面我們看看如何得到下個星期五的日期:
          SQL> select next_day(sysdate, 'Friday') "Next Friday" from dual;
          select next_day(sysdate, 'Friday') "Next Friday" from dual
                                   
          *
          ERROR at line 
          1:
          ORA
          -01846: 周中的日無效

          很奇怪!是不?明明語法沒有問題,但為什么會說“周中的日無效”呢?這里就不得不說到Oracle中的語言和時區的問題了。下面這張圖是使用TOAD截取出來的客戶端session的語言和時區信息:


          圖一

          從圖中我們知道了客戶端的語言是簡體中文,日期使用的語言也是簡體中文,這就是為什么上面的SQL語句出錯的原因了,因為在中文中只有“星期一,星期二”這樣的工作日表示,而沒有“Monday,Firday”這樣的寫法!

          SQL> select next_day(sysdate,'星期五') "下周五" from dual;

          下周五
          ----------
          04-7月 -08

          如果你不確定自己的時區或者你擔心從一個時區移植到另一個時區時,SQL語句會出錯,Oracle還允許你用數字的形式來表示工作日。但是要記得一點:1表示的是周日,2表示的是周一,3表示的是周二,依此類推。

          例如我要查下個周三是什么時候,則函數是這樣寫的:next_day(sysdate, 4)。
          SQL> select next_day(sysdate,4) from dual;

          NEXT_DAY(S
          ----------
          02-7月 -08



          看一下日歷是不是正確的,確實不錯!呵呵


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-06-30 10:23 Paul Lin 閱讀(8750) 評論(11)  編輯  收藏 所屬分類: Oracle 開發


          FeedBack:
          # re: 【原】Oracle開發專題之:時間運算
          2008-12-30 13:02 | 北京時間
          確實不錯!呵呵   回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2009-04-02 17:19 | Bluesand
          如何用SQL查詢一年中每個月的第一天是星期幾?請高手幫忙  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2009-04-19 00:03 | JSB
          很強!從這學到了不少,謝謝分享!  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2009-04-24 10:04 | d
          頂一個  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2009-12-02 13:30 | 夭夭
          非常感謝,很受用  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2010-08-23 17:34 | horrsion
          好,太好了  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2011-05-12 11:00 | xiaofen
          SQL> select to_char(sysdate, 'yyyy-mm-dd hh:mi:ss') now_date,
          2 to_char(sysdate+(30/24/60), 'yyyy-mm-dd hh:mi:ss') new_date
          3 from dual;
          中的(30/24/60)不懂  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算[未登錄]
          2011-05-12 23:03 | Paul Lin
          @xiaofen

          (30/24/60)= (1/24/60 *30) ,也就是一天有24個小時,小時有60分鐘。那么1分鐘等于多少天呢?就是 1/24/60啊。如果是30分鐘就是乘以 30   回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算
          2011-05-23 15:51 | HJX
          很有幫助!  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算[未登錄]
          2011-08-18 16:45 | df
          @xiaofen
          30分鐘轉化為以天為單位  回復  更多評論
            
          # re: 【原】Oracle開發專題之:時間運算[未登錄]
          2011-08-18 17:14 | df
          @Bluesand
          select to_char( last_day(add_months(sysdate,-8))+1,'yyyy-mm-dd')日期,
          to_char( last_day(add_months(sysdate,-8))+1,'DAY') 星期幾 from dual
          union
          select to_char( last_day(add_months(sysdate,-7))+1,'yyyy-mm-dd')日期,
          to_char( last_day(add_months(sysdate,-7))+1,'DAY') 星期幾 from dual
          union
          select to_char( last_day(add_months(sysdate,-6))+1,'yyyy-mm-dd')日期,
          to_char( last_day(add_months(sysdate,-6))+1,'DAY') 星期幾 from dual
          union
          select to_char( last_day(add_months(sysdate,-5))+1,'yyyy-mm-dd')日期,
          to_char( last_day(add_months(sysdate,-5))+1,'DAY') 星期幾 from dual  回復  更多評論
            
          <2008年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 环江| 尼玛县| 淮南市| 醴陵市| 连江县| 丰原市| 郧西县| 扎囊县| 体育| 仙桃市| 仁怀市| 鄂托克旗| 余干县| 吴堡县| 平谷区| 扬中市| 塔河县| 家居| 清徐县| 贵南县| 武定县| 百色市| 绥宁县| 云和县| 万全县| 视频| 金川县| 交口县| 朝阳县| 勐海县| 宝山区| 彭水| 凤台县| 琼海市| 佛教| 崇仁县| 盐边县| 工布江达县| 望江县| 崇左市| 老河口市|