2016-10-13 6 views
0

私は先月同じ日にepochを見つけるPLSQLコードがありますが、月末に31日目と01日目に実行すると失敗します。先月末の同じ日にエポックを見つける方法は?

SET serveroutput ON 
    DECLARE 
     vDay  VARCHAR2(30) := '&Enter_current_day'; 
     vDate  VARCHAR2(30); 
     vEpoch  NUMBER; 
    BEGIN 
     vDate := TO_CHAR(sysdate, 'MM')||'-'||vDay||'-'||TO_CHAR(sysdate, 'YYYY'); 
     vEpoch := (ADD_MONTHS(TO_DATE(vDate, 'MM-DD-YYYY HH24:MI:SS'), -1) - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) * 24 * 60 * 60; 
     vDate := TO_DATE(vDate, 'MM-DD-YYYY HH24:MI:SS'); 
     dbms_output.put_line('Current Date: '||to_number(vDay)||' Epoch: '||vEpoch||' Date: '||vDate); 
    END; 

今日の日付が

A. 30-Sep and if I enter '31' then it should return epoch for the 01-Sep 
B. 30-Sep and if I enter '01' then it should return epoch for the 01-Sep 
C. 30-Mar and if I enter '31' then it should return epoch for the 01-Mar 
D. 30-Mar and if I enter '01' then it should return epoch for the 01-Mar 
+0

ケースBとDの場合は、実際に月の最初の方が必要でしたか?今月の最後の日ではないでしょうか? – Boneist

答えて

0

このようなことはおそらくトリックですか?

DECLARE 
    vday VARCHAR2(30) := '&Enter_current_day'; 
    vdate DATE; 
    vepoch NUMBER; 
    v_today DATE := SYSDATE - 30; 
BEGIN 
    vdate := to_date(to_char(v_today, 'MM') || '-' || 
         least(to_number(vday), 
         to_number(to_char(last_day(v_today), 'dd'))) || '-' || 
         to_char(v_today, 'YYYY'), 
        'MM-DD-YYYY'); 
    vepoch := (add_months(vdate, -1) - 
       to_date('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) * 24 * 60 * 60; 

    dbms_output.put_line('Current Date: ' || to_number(vday) || ' Epoch: ' || 
       vepoch || ' Date: ' || to_char(vdate, 'mm-dd-yyyy')); 
END; 

Current Date: 1 Epoch: 1470009600 Date: 09-01-2016 
Current Date: 15 Epoch: 1471219200 Date: 09-15-2016 
Current Date: 30 Epoch: 1472601600 Date: 09-30-2016 
Current Date: 31 Epoch: 1472601600 Date: 09-30-2016 

は、この単純v_today日付によって返された月の最終日を検出し、入力vdayと比較して最も低い値を選びます。したがって、9月の場合、vday = 31とすると、31と30(9月の最終日)を比較して30を出力します。

月の最初の日を返すと死んでしまう場合は、 セクションを次のように変更します。

CASE WHEN to_number(to_char(last_day(v_today), 'dd')) < to_number(vday) 
      THEN '01' 
    ELSE vday 
END 

NBコードをより堅牢にするためにいくつかの変更を行ったことに注意してください。最初はvDateが文字列として使用されていたので、少し不便なのはvDate := TO_DATE(vDate, 'MM-DD-YYYY HH24:MI:SS');でした。これにより、Oracleは文字列を暗黙的に日付に変換してから文字列に戻すよう強制しています。

代わりにvDateを日付として宣言し、コードの残りの部分で使用した日付形式で結果の文字列に日付を出力しました。つまり、決定するNLS nls_date_formatパラメータに依存しなくなりました必ずしも皆のために同じではありません!)。

関連する問題