【Oracle】システム日付を取得する方法|SYSDATE・SYSTIMESTAMP・CURRENT_DATEの違いと実務パターン

【Oracle】システム日付を取得する方法|SYSDATE・SYSTIMESTAMP・CURRENT_DATEの違いと実務パターン Oracle

Oracleデータベースでシステム日付(現在の日時)を取得するには、SYSDATESYSTIMESTAMPCURRENT_DATEなどの関数を使います。

この記事では、それぞれの関数の違い、TO_CHARによるフォーマット変換、日付計算PL/SQLでの活用法、タイムゾーンの注意点まで、実務で必要なパターンを網羅的に解説します。

この記事で学べること

  • SYSDATEでシステム日付を取得する基本構文
  • SYSTIMESTAMPでミリ秒・タイムゾーン付き日時を取得する方法
  • CURRENT_DATE / CURRENT_TIMESTAMPとセッションタイムゾーンの関係
  • TO_CHARで日付を任意のフォーマットに変換する方法
  • 日付計算(加算・減算・TRUNC・月末取得)の実務パターン
  • INSERT / UPDATEでのタイムスタンプ記録
  • PL/SQLでの変数への格納と条件分岐
  • EXTRACT関数で年・月・日・時を個別に取り出す方法
  • INTERVAL型で日時を加算する方法
  • よくあるエラーとFIXED_DATEによるテスト対策
スポンサーリンク

SYSDATE関数の基本

SYSDATEは、Oracleで最もよく使われるシステム日付取得関数です。データベースサーバーのOS日時をDATE型で返します。

SQL
SELECT SYSDATE FROM DUAL;

実行結果

SYSDATE
-------------------
2025-03-05 14:30:22

SYSDATEのポイント

  • 引数なし(括弧を付けない)
  • 戻り値はDATE型(年月日 時分秒)
  • データベースサーバーのOS時刻を返す(セッションのタイムゾーンは無関係)
  • DUAL表を使って1行で取得するのが定番

SYSTIMESTAMP関数

SYSTIMESTAMPは、SYSDATEよりも高精度なシステム日時を取得する関数です。小数秒タイムゾーンの情報も含まれます。

SQL
SELECT SYSTIMESTAMP FROM DUAL;

実行結果

SYSTIMESTAMP
--------------------------------------
2025-03-05 14:30:22.847362 +09:00
比較項目 SYSDATE SYSTIMESTAMP
戻り値の型 DATE TIMESTAMP WITH TIME ZONE
精度 秒まで 小数秒(最大9桁)
タイムゾーン なし あり(+09:00等)
基準時刻 DBサーバーのOS時刻 DBサーバーのOS時刻

ポイント:ログのタイムスタンプや処理時間の計測など、秒未満の精度が必要な場面ではSYSTIMESTAMPを使います。

CURRENT_DATE / CURRENT_TIMESTAMP

CURRENT_DATECURRENT_TIMESTAMPは、セッションのタイムゾーンに基づいた日時を返します。

SQL
-- セッションタイムゾーンを確認
SELECT SESSIONTIMEZONE FROM DUAL;

-- セッションのタイムゾーンに基づく日時
SELECT CURRENT_DATE      AS curr_date,
       CURRENT_TIMESTAMP AS curr_ts
FROM   DUAL;
関数 戻り値の型 基準 用途
SYSDATE DATE DBサーバーOS 一般的な日時取得
SYSTIMESTAMP TIMESTAMP WITH TZ DBサーバーOS 高精度タイムスタンプ
CURRENT_DATE DATE セッションTZ ユーザーのローカル日時
CURRENT_TIMESTAMP TIMESTAMP WITH TZ セッションTZ 高精度ローカル日時

注意:DBサーバーが日本(JST)にあり、セッションタイムゾーンがUTCの場合、SYSDATEとCURRENT_DATEは9時間ずれます。タイムゾーンを意識しない環境ではSYSDATEで十分です。

タイムゾーンの違いを実感する

SYSDATEとCURRENT_DATEの違いをセッションタイムゾーンを変更して確認してみましょう。

タイムゾーンの違いを確認
-- セッションをUTCに変更
ALTER SESSION SET TIME_ZONE = 'UTC';

SELECT
  SYSDATE       AS sys_date,      -- DBサーバーの時刻(JST)
  CURRENT_DATE AS current_date_  -- セッションの時刻(UTC)
FROM DUAL;

実行結果(DBサーバーがJSTの場合)

SYS_DATE             CURRENT_DATE_
-------------------  -------------------
2025-03-05 14:30:22  2025-03-05 05:30:22   ← 9時間の差

TO_CHARで日付をフォーマットする

SYSDATEの結果を任意の書式で表示するには、TO_CHAR関数を使います。

よく使うフォーマット一覧

書式 SQL 出力例
年月日 TO_CHAR(SYSDATE, 'YYYY/MM/DD') 2025/03/05
年月日 時分秒 TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') 2025/03/05 14:30:22
年月日(ハイフン) TO_CHAR(SYSDATE, 'YYYY-MM-DD') 2025-03-05
年月(6桁) TO_CHAR(SYSDATE, 'YYYYMM') 202503
年月日(8桁) TO_CHAR(SYSDATE, 'YYYYMMDD') 20250305
時分秒のみ TO_CHAR(SYSDATE, 'HH24:MI:SS') 14:30:22
曜日 TO_CHAR(SYSDATE, 'DY')
和暦 TO_CHAR(SYSDATE, 'EEYY/MM/DD', 'NLS_CALENDAR='Japanese Imperial'') 令和07/03/05
実行例
SELECT
  TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') AS full_datetime,
  TO_CHAR(SYSDATE, 'YYYYMMDD')              AS date_key,
  TO_CHAR(SYSDATE, 'DY')                    AS day_of_week
FROM   DUAL;

関連: 【Oracle】日付フォーマットを変更する方法 / 【Oracle】日付を和暦で取得する方法

EXTRACT関数で年・月・日を取り出す

EXTRACT関数を使うと、日付から年・月・日・時・分・秒を個別に数値で取得できます。

EXTRACT関数の基本
SELECT
  EXTRACT(YEAR   FROM SYSDATE) AS yr,    -- 2025
  EXTRACT(MONTH  FROM SYSDATE) AS mon,   -- 3
  EXTRACT(DAY    FROM SYSDATE) AS dy     -- 5
FROM   DUAL;

実行結果

  YR   MON   DY
----  ----  ---
2025     3    5

SYSTIMESTAMPから時・分・秒を取得

時分秒の取得
SELECT
  EXTRACT(HOUR   FROM SYSTIMESTAMP) AS hr,
  EXTRACT(MINUTE FROM SYSTIMESTAMP) AS mi,
  EXTRACT(SECOND FROM SYSTIMESTAMP) AS sec
FROM   DUAL;

注意:HOUR・MINUTE・SECONDはTIMESTAMP型からのみ取得可能です。EXTRACT(HOUR FROM SYSDATE)はエラーになるため、SYSTIMESTAMPまたはCAST(SYSDATE AS TIMESTAMP)を使います。

EXTRACT vs TO_CHAR の使い分け

比較項目 EXTRACT TO_CHAR
戻り値 NUMBER VARCHAR2
用途 数値で比較・計算する場合 書式付き文字列が欲しい場合
EXTRACT(MONTH FROM SYSDATE) = 3 TO_CHAR(SYSDATE, 'MM') = '03'

ポイント:数値として条件分岐や計算に使う場合はEXTRACT、表示用の文字列が欲しい場合はTO_CHARを選びましょう。WHERE句での月指定にはEXTRACTが直感的です。

日付計算の実務パターン

日数の加算・減算

OracleのDATE型は日数の加減算が可能です。

日数の加算・減算
SELECT
  SYSDATE       AS today,
  SYSDATE + 1   AS tomorrow,        -- 明日
  SYSDATE - 1   AS yesterday,       -- 昨日
  SYSDATE + 7   AS next_week,       -- 1週間後
  SYSDATE + 1/24 AS plus_one_hour    -- 1時間後
FROM   DUAL;

月の加算・減算(ADD_MONTHS)

月の操作
SELECT
  ADD_MONTHS(SYSDATE, 1)  AS next_month,    -- 1ヶ月後
  ADD_MONTHS(SYSDATE, -1) AS prev_month,    -- 1ヶ月前
  ADD_MONTHS(SYSDATE, 12) AS next_year      -- 1年後
FROM   DUAL;

日付の切り捨て(TRUNC)

TRUNCで日付を切り捨て
SELECT
  TRUNC(SYSDATE)             AS today_00,       -- 今日の0:00:00
  TRUNC(SYSDATE, 'MM')      AS month_first,    -- 月初
  TRUNC(SYSDATE, 'Q')       AS quarter_first,  -- 四半期初
  TRUNC(SYSDATE, 'YYYY')    AS year_first      -- 年初
FROM   DUAL;

関連: 【Oracle】今日の0:00を取得する方法

月末の取得(LAST_DAY)

月末と残日数
SELECT
  LAST_DAY(SYSDATE)                  AS month_end,
  LAST_DAY(SYSDATE) - SYSDATE        AS remaining_days
FROM   DUAL;

関連: 【Oracle】月末を取得する方法

2つの日付間の差

日数差と月数差
SELECT
  SYSDATE - TO_DATE('2025-01-01', 'YYYY-MM-DD') AS days_diff,
  MONTHS_BETWEEN(SYSDATE, TO_DATE('2025-01-01', 'YYYY-MM-DD')) AS months_diff
FROM   DUAL;

INTERVAL型で日時を加算する

Oracle 9i以降では、INTERVAL型を使って可読性の高い日時加算ができます。

INTERVAL型での加算
SELECT
  SYSDATE + INTERVAL '1' DAY     AS plus_1day,
  SYSDATE + INTERVAL '2' HOUR    AS plus_2hours,
  SYSDATE + INTERVAL '30' MINUTE AS plus_30min,
  SYSDATE - INTERVAL '90' SECOND AS minus_90sec
FROM   DUAL;

数値加算との比較

目的 数値加算 INTERVAL
1日後 SYSDATE + 1 SYSDATE + INTERVAL '1' DAY
1時間後 SYSDATE + 1/24 SYSDATE + INTERVAL '1' HOUR
30分後 SYSDATE + 30/1440 SYSDATE + INTERVAL '30' MINUTE
90秒後 SYSDATE + 90/86400 SYSDATE + INTERVAL '90' SECOND

ポイント:数値加算(+ 1/24)は簡潔ですが、INTERVAL型の方が意図が明確でコードレビュー時に読みやすくなります。チーム開発ではINTERVALがおすすめです。

INSERT / UPDATEでの活用

SYSDATEは登録日時や更新日時の記録に頻繁に使われます。

INSERT文でタイムスタンプを記録

登録日時をSYSDATEで記録
INSERT INTO audit_log (user_id, action, created_at)
VALUES (1001, 'LOGIN', SYSDATE);

UPDATE文で更新日時を記録

更新日時の記録
UPDATE employees
SET    salary = 500000,
       updated_at = SYSDATE
WHERE  employee_id = 1001;

デフォルト値としてSYSDATEを設定

テーブル定義でのDEFAULT SYSDATE
CREATE TABLE orders (
  order_id   NUMBER PRIMARY KEY,
  product_id NUMBER,
  quantity   NUMBER,
  order_date DATE DEFAULT SYSDATE  -- 省略時は現在日時
);

ポイント:DEFAULT SYSDATEを設定すると、INSERT時にorder_dateを省略しても自動的に現在日時が入ります。

WHERE句での日付条件

今日のデータを取得

今日のデータを抽出
SELECT * FROM orders
WHERE  order_date >= TRUNC(SYSDATE)
  AND order_date <  TRUNC(SYSDATE) + 1;

過去N日間のデータを取得

直近7日間のデータ
SELECT * FROM orders
WHERE  order_date >= SYSDATE - 7;

今月のデータを取得

当月のデータ
SELECT * FROM orders
WHERE  order_date >= TRUNC(SYSDATE, 'MM')
  AND order_date <  ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1);

注意:DATE型には時分秒が含まれるため、WHERE order_date = SYSDATEでは秒単位まで一致するデータしか取得できません。日付のみで比較する場合は必ずTRUNCを使います。

PL/SQLでの活用

PL/SQL – 変数に格納して使用
DECLARE
  v_now  DATE := SYSDATE;
  v_text VARCHAR2(50);
BEGIN
  v_text := TO_CHAR(v_now, 'YYYY/MM/DD HH24:MI:SS');
  DBMS_OUTPUT.PUT_LINE('現在日時: ' || v_text);

  -- 営業時間内かどうかの判定
  IF TO_NUMBER(TO_CHAR(v_now, 'HH24')) BETWEEN 9 AND 17 THEN
    DBMS_OUTPUT.PUT_LINE('営業時間内です');
  ELSE
    DBMS_OUTPUT.PUT_LINE('営業時間外です');
  END IF;
END;
/
PL/SQL – 処理時間の計測
DECLARE
  v_start TIMESTAMP := SYSTIMESTAMP;
  v_end   TIMESTAMP;
BEGIN
  -- 何かの処理
  FOR i IN 1..100000 LOOP
    NULL;
  END LOOP;

  v_end := SYSTIMESTAMP;
  DBMS_OUTPUT.PUT_LINE('処理時間: ' || (v_end - v_start));
END;
/

よくあるエラーと対処法

エラー・問題 原因 対処法
SYSDATE()でエラー 括弧を付けている 括弧なしのSYSDATEを使用
日付比較で結果が0件 DATE型に時分秒が含まれている TRUNCで時刻を切り捨てて比較
SYSDATEとCURRENT_DATEが異なる セッションタイムゾーンがDBサーバーと異なる ALTER SESSION SET TIME_ZONEで確認・変更
ORA-01843: not a valid month NLS_DATE_FORMATと文字列の形式不一致 TO_DATEで明示的にフォーマット指定
テスト時にSYSDATEを固定したい テスト用に日付を変更したい ALTER SYSTEM SET FIXED_DATEを使用

テスト用にSYSDATEを固定する

FIXED_DATEでSYSDATEを固定
-- SYSDATEを固定(DBA権限が必要)
ALTER SYSTEM SET FIXED_DATE = '2025-01-01-00:00:00';

-- 確認
SELECT SYSDATE FROM DUAL;  -- 2025-01-01 00:00:00

-- 解除
ALTER SYSTEM SET FIXED_DATE = NONE;

注意:FIXED_DATEはインスタンス全体に影響します。本番環境では絶対に使用しないでください。テスト・開発環境専用の機能です。

他のRDBMSとの比較

RDBMS 現在日時の取得 備考
Oracle SYSDATE / SYSTIMESTAMP FROM DUALが必要
MySQL NOW() / SYSDATE() 括弧が必要
PostgreSQL NOW() / CURRENT_TIMESTAMP FROM不要
SQL Server GETDATE() / SYSDATETIME() 括弧が必要
SQLite datetime('now') 関数形式が異なる

まとめ

用途 推奨関数 理由
一般的な日時取得 SYSDATE 最もシンプルで高速
ログ・監査記録 SYSTIMESTAMP 小数秒+TZで正確に記録
マルチタイムゾーン環境 CURRENT_DATE / CURRENT_TIMESTAMP ユーザーのローカル時刻に対応
日付の比較・検索 TRUNC(SYSDATE) 時刻を除外して日付のみ比較
フォーマット変換 TO_CHAR(SYSDATE, …) 任意の書式で文字列化

Oracleでシステム日付を取得するには、まずSYSDATEを覚えれば大半の場面で対応できます。高精度が必要ならSYSTIMESTAMP、タイムゾーンを意識するならCURRENT_DATEと、用途に応じて使い分けましょう。

関連記事