サーチ…


時間コンポーネントなしの日付の生成

すべてのDATEは時間要素があります。しかし、時間情報を含める必要のない日付を時間/分/秒がゼロ(すなわち真夜中)に設定して格納することが慣例である。

ANSI DATEリテラルを使用する( ISO 8601の日付形式を使用)。

SELECT DATE '2000-01-01' FROM DUAL;

TO_DATE()を使用して文字列リテラルから変換します。

SELECT TO_DATE( '2001-01-01', 'YYYY-MM-DD' ) FROM DUAL;

日付書式モデルの詳細は、Oracleのマニュアルを参照してください。)

または:

SELECT TO_DATE(
         'January 1, 2000, 00:00 A.M.',
         'Month dd, YYYY, HH12:MI A.M.',
         'NLS_DATE_LANGUAGE = American'
       )
FROM   DUAL;

(月名などの言語固有の用語を変換する場合は、3番目のnlsparamパラメータをTO_DATE()関数にTO_DATE() 、予想される言語を指定することをお勧めします)。

時刻コンポーネントを使用した日付の生成

TO_DATE()を使用して文字列リテラルから変換します。

SELECT TO_DATE( '2000-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;

または、 TIMESTAMPリテラルを使用しTIMESTAMP

CREATE TABLE date_table(
  date_value DATE
);

INSERT INTO date_table ( date_value ) VALUES ( TIMESTAMP '2000-01-01 12:00:00' );

Oracleは、表のDATE列にTIMESTAMPを格納するときに、暗黙的にTIMESTAMPDATEにキャストしTIMESTAMP 。ただし、明示的に値をDATE CAST()することができます。

SELECT CAST( TIMESTAMP '2000-01-01 12:00:00' AS DATE ) FROM DUAL;

日付の書式

Oracleでは、 DATEデータ型にはフォーマットがありません。 Oracleがクライアントプログラム(SQL / Plus、SQL / Developer、Toad、Java、Pythonなど)にDATEを送信すると、日付を表す7バイトまたは8バイトが送信されます。

テーブルに格納されていない(つまり、 SYSDATEによって生成され、 DUMP()コマンドを使用するときに "タイプ13"を持つ) DATEは、8バイトで構成されています(右の数字は2012-11-26 16:41:09内部表現2012-11-26 16:41:09 ):

BYTE VALUE                           EXAMPLE
---- ------------------------------- --------------------------------------
1    Year modulo 256                 220
2    Year multiples of 256           7   (7 * 256 + 220 = 2012)
3    Month                           11
4    Day                             26
5    Hours                           16
6    Minutes                         41
7    Seconds                         9
8    Unused                          0

テーブルに格納されているDATEDUMP()コマンドを使用する場合は「タイプ12」)は7バイトで構成されています(右の数字は2012-11-26 16:41:09内部表現です):

BYTE VALUE                           EXAMPLE
---- ------------------------------- --------------------------------------
1    ( Year multiples of 100 ) + 100 120
2    ( Year modulo 100 ) + 100       112 ((120-100)*100 + (112-100) = 2012)
3    Month                           11
4    Day                             26
5    Hours + 1                       17
6    Minutes + 1                     42
7    Seconds + 1                     10

日付に特定の形式を使用する場合は、形式(つまり文字列)を持つものに変換する必要があります。 SQLクライアントは暗黙的にこれを行うか明示的にTO_CHAR( date, format_model, nls_params )TO_CHAR( date, format_model, nls_params ) て値を文字列に変換できます。

日付を文字列に変換する

TO_CHAR( date [, format_model [, nls_params]] )ます。

(注: フォーマット・モデルが提供されていない場合は、 NLS_DATE_FORMATセッション・パラメータがデフォルト・フォーマット・モデルとして使用されますが、これはすべてのセッションで異なる可能性がありますので、依存する必要はありません。

CREATE TABLE table_name (
  date_value DATE
);

INSERT INTO table_name ( date_value ) VALUES ( DATE '2000-01-01' );
INSERT INTO table_name ( date_value ) VALUES ( TIMESTAMP '2016-07-21 08:00:00' );
INSERT INTO table_name ( date_value ) VALUES ( SYSDATE );

次に:

SELECT TO_CHAR( date_value, 'YYYY-MM-DD' ) AS formatted_date FROM table_name;

出力:

FORMATTED_DATE
--------------
2000-01-01
2016-07-21
2016-07-21

そして:

SELECT TO_CHAR(
         date_value,
         'FMMonth d yyyy, hh12:mi:ss AM',
         'NLS_DATE_LANGUAGE = French'
       ) AS formatted_date
FROM   table_name;

出力:

FORMATTED_DATE
-----------------------------
Janvier   01 2000, 12:00:00 AM
Juillet   21 2016, 08:00:00 AM
Juillet   21 2016, 19:08:31 PM

デフォルトの日付書式モデルの設定

OracleがDATEから文字列に暗黙的に変換する場合、またはTO_CHAR()またはTO_DATE()が書式モデルなしで明示的に呼び出された場合は、 NLS_DATE_FORMATセッション・パラメータが変換のフォーマット・モデルとして使用されます。リテラルが書式モデルと一致しない場合、例外が発生します。

このパラメータは次の方法で確認できます。

SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';

現在のセッション内でこの値を設定するには、次のようにします。

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

(注:他のユーザーの値は変更されません)。

TO_DATE()またはTO_CHAR()フォーマット・マスクを提供するためにNLS_DATE_FORMATを使用する場合は、この値が変更された場合に照会が中断しても驚かないはずです。

SQL / PlusまたはSQL Developerによる日付の表示方法の変更

SQL / PlusまたはSQL Developerで日付が表示されると、デフォルトの日付書式モデルを使用して文字列への暗黙的な変換が実行されます(「既定の日付書式モデルの設定」の例を参照)。

NLS_DATE_FORMATパラメータを変更すると、日付の表示方法を変更できます。

日付演算 - 日、時、分および/または秒単位の日付の違い

オラクルでは、2つのDATE間の差異(日数および/またはその分数)は、減算を使用して見つけることができます。

SELECT DATE '2016-03-23' - DATE '2015-12-25' AS difference FROM DUAL;

2つの日付間の日数を出力します。

DIFFERENCE
----------
        89

そして:

SELECT TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
         - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' )
         AS difference
FROM   DUAL

2つの日付間の日数を出力します。

DIFFERENCE
----------
    1.0425

時間、分、秒の差がで、この数を掛けることにより求めることができる2424*60または24*60*60それぞれ。

前の例を変更すると、次のように2つの日付間の日、時間、分、秒を取得できます。

SELECT TRUNC( difference                       ) AS days,
       TRUNC( MOD( difference * 24,       24 ) ) AS hours,
       TRUNC( MOD( difference * 24*60,    60 ) ) AS minutes,
       TRUNC( MOD( difference * 24*60*60, 60 ) ) AS seconds
FROM   (
  SELECT TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
         - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' )
         AS difference
  FROM   DUAL

);

(注:負の違いを正しく処理するには、 FLOOR()ではなくTRUNC()を使用します。

出力:

DAYS HOURS MINUTES SECONDS
---- ----- ------- -------
   1     1       1      12

前の例は、 NUMTODSINTERVAL()を使用して数値の差を間隔に変換することによっても解決できます。

SELECT EXTRACT( DAY    FROM difference ) AS days,
       EXTRACT( HOUR   FROM difference ) AS hours,
       EXTRACT( MINUTE FROM difference ) AS minutes,
       EXTRACT( SECOND FROM difference ) AS seconds
FROM   (
  SELECT NUMTODSINTERVAL(
           TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
             - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' ),
           'DAY'
         ) AS difference
  FROM   DUAL
);

日付算術 - 月または年の日付の違い

2つの日付間の月数の違いは、 MONTHS_BETWEEN( date1, date2 )を使用してMONTHS_BETWEEN( date1, date2 )できます。

SELECT MONTHS_BETWEEN( DATE '2016-03-10', DATE '2015-03-10' ) AS difference FROM DUAL;

出力:

DIFFERENCE
----------
        12

差異に部分的な月が含まれている場合は、毎月31日に基づいてその月の割合を返します。

SELECT MONTHS_BETWEEN( DATE '2015-02-15', DATE '2015-01-01' ) AS difference FROM DUAL;

出力:

DIFFERENCE
----------
 1.4516129

MONTHS_BETWEENため、1か月間に31日MONTHS_BETWEEN仮定すると、月間の日数が少なくなる可能性があるため、月間の境界にまたがる差異の値が異なることがあります。

例:

SELECT MONTHS_BETWEEN( DATE'2016-02-01', DATE'2016-02-01' - INTERVAL '1' DAY ) AS "JAN-FEB",
       MONTHS_BETWEEN( DATE'2016-03-01', DATE'2016-03-01' - INTERVAL '1' DAY ) AS "FEB-MAR",
       MONTHS_BETWEEN( DATE'2016-04-01', DATE'2016-04-01' - INTERVAL '1' DAY ) AS "MAR-APR",
       MONTHS_BETWEEN( DATE'2016-05-01', DATE'2016-05-01' - INTERVAL '1' DAY ) AS "APR-MAY"
FROM   DUAL;

出力:

JAN-FEB FEB-MAR MAR-APR APR-MAY
------- ------- ------- -------
0.03226 0.09677 0.03226 0.06452

年の違いは月差を12で割って求められます。

年、月、日、時、分または秒のコンポーネントを抽出する

DATEデータ型の年、月、日のコンポーネントは、 EXTRACT( [ YEAR | MONTH | DAY ] FROM datevalue )を使用して検索できます。

SELECT EXTRACT (YEAR  FROM DATE '2016-07-25') AS YEAR,
       EXTRACT (MONTH FROM DATE '2016-07-25') AS MONTH,
       EXTRACT (DAY   FROM DATE '2016-07-25') AS DAY
FROM DUAL;

出力:

YEAR MONTH DAY
---- ----- ---
2016     7  25

時間(分、秒)のコンポーネントは、次のいずれかによって検出できます。

例えば:

SELECT EXTRACT( HOUR   FROM CAST( datetime AS TIMESTAMP ) ) AS Hours,
       EXTRACT( MINUTE FROM CAST( datetime AS TIMESTAMP ) ) AS Minutes,
       EXTRACT( SECOND FROM CAST( datetime AS TIMESTAMP ) ) AS Seconds
FROM   (
  SELECT TO_DATE( '2016-01-01 09:42:01', 'YYYY-MM-DD HH24:MI:SS' ) AS datetime FROM DUAL
);

出力:

HOURS MINUTES SECONDS
----- ------- -------
    9      42       1

タイムゾーンと夏時間

DATEデータ型は、タイムゾーンや夏時間の変更を処理しません。

どちらか:

DATEは協定世界時(UTC)として保存し、次のように現在のセッションのタイムゾーンに変換できます。

SELECT FROM_TZ(
         CAST(
           TO_DATE( '2016-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS' )
           AS TIMESTAMP
         ),
         'UTC'
       )
       AT LOCAL AS time
FROM   DUAL;

ALTER SESSION SET TIME_ZONE = '+01:00';出力は次のようになります。

TIME
------------------------------------
2016-01-01 13:00:00.000000000 +01:00

およびALTER SESSION SET TIME_ZONE = 'PST';出力は次のようになります。

TIME
------------------------------------
2016-01-01 04:00:00.000000000 PST

うるう秒

Oracle は閏秒を処理しません 。詳細は、My Oracleサポート・ノート2019397.2および730795.1を参照してください。

今週の曜日を取得する

TO_CHAR( date_value, 'D' )を使用して曜日を取得できます。

ただし、これはNLS_TERRITORYセッション・パラメータに依存します。

ALTER SESSION SET NLS_TERRITORY = 'AMERICA';        -- First day of week is Sunday
SELECT TO_CHAR( DATE '1970-01-01', 'D' ) FROM DUAL;

出力5

ALTER SESSION SET NLS_TERRITORY = 'UNITED KINGDOM'; -- First day of week is Monday
SELECT TO_CHAR( DATE '1970-01-01', 'D' ) FROM DUAL;

アウトプット4

これをNLS設定とは無関係に行うには、現在の日の午前0時を切り捨て(何分の一かの日数を削除する)、現在のiso-week(常に月曜日に始まります)の開始時刻を切り捨てます。

SELECT TRUNC( date_value ) - TRUNC( date_value, 'IW' ) + 1 FROM DUAL


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow