Oracle Database
日付
サーチ…
時間コンポーネントなしの日付の生成
すべての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
を格納するときに、暗黙的にTIMESTAMP
をDATE
にキャストし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
テーブルに格納されているDATE
( DUMP()
コマンドを使用する場合は「タイプ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
時間、分、秒の差がで、この数を掛けることにより求めることができる24
、 24*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
時間(分、秒)のコンポーネントは、次のいずれかによって検出できます。
- 使用
CAST( datevalue AS TIMESTAMP )
変換するDATE
にTIMESTAMP
使用して、その後し、EXTRACT( [ HOUR | MINUTE | SECOND ] FROM timestampvalue )
または -
TO_CHAR( datevalue, format_model )
を使用して値を文字列として取得します。
例えば:
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
データ型は、タイムゾーンや夏時間の変更を処理しません。
どちらか:
-
TIMESTAMP WITH TIME ZONE
データ型を使用しTIMESTAMP WITH TIME ZONE
。または - アプリケーションロジックの変更を処理します。
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