Oracleデータベースで日付を和暦(令和・平成・昭和など)で表示するには、TO_CHAR関数とNLS_CALENDARパラメータを組み合わせます。帳票出力や官公庁システムなど、和暦表示が必須となる場面は多く、正しい設定方法を知っておくことは実務で非常に重要です。
この記事では、TO_CHARとNLS_CALENDAR=’Japanese Imperial’による基本的な和暦変換から、ALTER SESSIONでの設定、元号一覧、和暦→西暦変換、CASE文による手動変換、PL/SQL関数化、他RDBMS比較、よくあるエラーと対処法、実務パターンまで網羅的に解説します。
この記事で学べること
- TO_CHAR + NLS_CALENDAR による和暦表示の基本
- 和暦フォーマット要素(EE / E / RR / EEYYなど)の使い分け
- NLS_DATE_LANGUAGE の設定と影響
- ALTER SESSION でのNLSパラメータ設定方法
- 明治〜令和の元号一覧テーブル
- 和暦→西暦の変換方法
- CASE文による手動変換テクニック
- PL/SQL関数化で再利用可能にする方法
- 他RDBMS比較(SQL Server・MySQL・PostgreSQL)
- よくあるエラーと対処法
- 実務パターン(帳票出力・年度計算等)
和暦とは?
和暦とは日本独自の暦法で、西暦を元号(明治・大正・昭和・平成・令和)と組み合わせて表記します。たとえば西暦2025年は令和7年、1989年は平成元年に相当します。
官公庁や金融機関の帳票、契約書、公文書などでは和暦表記が求められることが多く、データベースレベルで正しく変換できることが重要です。
| 元号 |
読み |
開始日 |
終了日 |
略称 |
| 明治 |
めいじ |
1868年1月25日 |
1912年7月29日 |
M |
| 大正 |
たいしょう |
1912年7月30日 |
1926年12月24日 |
T |
| 昭和 |
しょうわ |
1926年12月25日 |
1989年1月7日 |
S |
| 平成 |
へいせい |
1989年1月8日 |
2019年4月30日 |
H |
| 令和 |
れいわ |
2019年5月1日 |
(現在) |
R |
TO_CHAR + NLS_CALENDARによる和暦変換の基本
Oracleで和暦表示を行うには、TO_CHAR関数の第3引数にNLS_CALENDAR=’Japanese Imperial’を指定します。これにより、日本の元号に基づいた日付フォーマットが有効になります。
基本構文
構文
TO_CHAR(
日付値,
'フォーマット',
'NLS_CALENDAR=Japanese Imperial'
)
最も基本的な和暦変換
SQL
-- SYSDATEを和暦で表示
SELECT
TO_CHAR(
SYSDATE,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS wareki
FROM DUAL;
実行結果
WAREKI
-----------------
令和07年06月15日
EEが元号の正式名称(令和・平成など)、YYが元号内の年数を2桁で表示します。ダブルクォーテーションで囲んだ「年」「月」「日」はリテラル文字としてそのまま出力されます。
和暦フォーマット要素の詳細
TO_CHARで和暦を表示する際に使えるフォーマット要素を確認しましょう。NLS_CALENDARをJapanese Imperialに設定した場合のみ有効になる要素があります。
| 要素 |
説明 |
出力例 |
| EE |
元号の正式名称(漢字) |
令和 |
| E |
元号の略称(アルファベット1文字) |
R |
| YY |
元号内の年数(2桁ゼロ埋め) |
07 |
| Y |
元号内の年数(ゼロ埋めなし) |
7 |
| MM |
月(2桁ゼロ埋め) |
06 |
| DD |
日(2桁ゼロ埋め) |
15 |
| “文字列” |
リテラル文字(そのまま出力) |
年、月、日 |
さまざまなフォーマットパターン
SQL
SELECT
-- 正式表記: 令和07年06月15日
TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS full_wareki,
-- 略称表記: R07/06/15
TO_CHAR(SYSDATE, 'EYY/MM/DD',
'NLS_CALENDAR=Japanese Imperial') AS short_wareki,
-- 略称+年付き: R07.06.15
TO_CHAR(SYSDATE, 'EYY.MM.DD',
'NLS_CALENDAR=Japanese Imperial') AS dot_wareki,
-- 元号と年のみ: 令和07年
TO_CHAR(SYSDATE, 'EEYY"年"',
'NLS_CALENDAR=Japanese Imperial') AS year_only
FROM DUAL;
実行結果
FULL_WAREKI SHORT_WAREKI DOT_WAREKI YEAR_ONLY
----------------- ------------ ---------- ---------
令和07年06月15日 R07/06/15 R07.06.15 令和07年
注意:NLS_CALENDARを指定しない場合、EEやEフォーマットは西暦のまま「AD」等が出力されます。必ずNLS_CALENDAR=Japanese Imperialをセットで使いましょう。
NLS_DATE_LANGUAGEの設定
NLS_DATE_LANGUAGEは日付の言語設定を制御するパラメータです。和暦表示で元号を日本語(漢字)で出力するには、NLS_DATE_LANGUAGEをJAPANESEに設定する必要があります。
SQL
-- NLS_DATE_LANGUAGEによる出力の違い
SELECT
-- JAPANESE: 令和07年06月15日
TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial NLS_DATE_LANGUAGE=JAPANESE'
) AS jp_wareki,
-- ENGLISH: Reiwa 07/06/15
TO_CHAR(SYSDATE, 'EE YY/MM/DD',
'NLS_CALENDAR=Japanese Imperial NLS_DATE_LANGUAGE=ENGLISH'
) AS en_wareki
FROM DUAL;
実行結果
JP_WAREKI EN_WAREKI
------------------ ----------------
令和07年06月15日 Reiwa 07/06/15
NLS_DATE_LANGUAGEがJAPANESEの場合は元号が漢字(令和)で、ENGLISHの場合は英語(Reiwa)で出力されます。デフォルトのセッション言語設定によって変わるため、確実に日本語で出力したい場合は明示的にJAPANESEを指定しましょう。
| NLS_DATE_LANGUAGE |
EE出力 |
E出力 |
| JAPANESE |
令和 |
R |
| ENGLISH |
Reiwa |
R |
| AMERICAN |
Reiwa |
R |
ALTER SESSIONでの設定方法
毎回TO_CHARの第3引数にNLSパラメータを指定するのが面倒な場合は、ALTER SESSIONでセッション全体のカレンダーを変更できます。一度設定すれば、そのセッション内のすべてのTO_CHAR呼び出しで和暦が使われます。
セッション設定の変更
SQL
-- セッションのカレンダーを和暦に変更
ALTER SESSION SET NLS_CALENDAR = 'Japanese Imperial';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'JAPANESE';
-- 以降、NLSパラメータ指定なしで和暦が使える
SELECT
TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"') AS wareki
FROM DUAL;
実行結果
WAREKI
-----------------
令和07年06月15日
現在のNLS設定を確認する
SQL
-- セッションのNLSパラメータを確認
SELECT parameter, value
FROM NLS_SESSION_PARAMETERS
WHERE parameter IN (
'NLS_CALENDAR',
'NLS_DATE_LANGUAGE',
'NLS_DATE_FORMAT'
);
実行結果
PARAMETER VALUE
-------------------- --------------------
NLS_CALENDAR Japanese Imperial
NLS_DATE_LANGUAGE JAPANESE
NLS_DATE_FORMAT RR/MM/DD
元に戻す(西暦に戻す)
SQL
-- セッションを西暦(グレゴリオ暦)に戻す
ALTER SESSION SET NLS_CALENDAR = 'Gregorian';
注意:ALTER SESSIONの設定はそのセッション内でのみ有効です。新しい接続を確立すると、データベースのデフォルト設定に戻ります。永続的に変更したい場合はデータベースレベルまたは初期化パラメータで設定する必要があります。
特定の日付を和暦に変換する
SYSDATEだけでなく、任意の日付を和暦に変換するケースも多くあります。TO_DATEで作成した日付値にTO_CHARを適用します。
SQL
-- さまざまな時代の日付を和暦で表示
SELECT
TO_CHAR(TO_DATE('2025-06-15', 'YYYY-MM-DD'),
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS reiwa,
TO_CHAR(TO_DATE('2015-04-01', 'YYYY-MM-DD'),
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS heisei,
TO_CHAR(TO_DATE('1985-03-20', 'YYYY-MM-DD'),
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS showa
FROM DUAL;
実行結果
REIWA HEISEI SHOWA
----------------- ----------------- -----------------
令和07年06月15日 平成27年04月01日 昭和60年03月20日
テーブルの日付列を和暦で表示する
SQL
-- 社員テーブルの入社日を和暦で表示
SELECT
emp_name,
hire_date,
TO_CHAR(hire_date,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS hire_date_wareki
FROM employees
ORDER BY hire_date;
実行結果
EMP_NAME HIRE_DATE HIRE_DATE_WAREKI
---------- ----------- -----------------
田中太郎 2018-04-01 平成30年04月01日
鈴木花子 2020-04-01 令和02年04月01日
佐藤一郎 2023-10-15 令和05年10月15日
和暦→西暦変換
和暦文字列を西暦の日付に変換する場合は、TO_DATE関数にNLS_CALENDARパラメータを指定します。
SQL
-- 和暦文字列を西暦DATEに変換
SELECT
TO_DATE(
'令和07年06月15日',
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial NLS_DATE_LANGUAGE=JAPANESE'
) AS seireki_date
FROM DUAL;
実行結果
SEIREKI_DATE
------------
2025-06-15
略称からの変換
SQL
-- 略称形式(R07/06/15)から西暦に変換
SELECT
TO_DATE(
'R07/06/15',
'EYY/MM/DD',
'NLS_CALENDAR=Japanese Imperial'
) AS seireki_date
FROM DUAL;
実行結果
SEIREKI_DATE
------------
2025-06-15
ポイント:TO_DATEとTO_CHARで同じフォーマット文字列とNLSパラメータを指定すれば、和暦→西暦→和暦の相互変換が正確に行えます。
CASE文による手動変換方法
NLS_CALENDARが使えない環境や、独自のフォーマットで和暦を出力したい場合は、CASE文を使って手動で元号を判定・変換できます。
西暦→和暦の手動変換
SQL
-- CASE文で元号を判定して和暦を組み立てる
SELECT
hire_date,
CASE
WHEN hire_date >= TO_DATE('2019-05-01', 'YYYY-MM-DD')
THEN '令和' || LPAD(EXTRACT(YEAR FROM hire_date) - 2018, 2, '0')
WHEN hire_date >= TO_DATE('1989-01-08', 'YYYY-MM-DD')
THEN '平成' || LPAD(EXTRACT(YEAR FROM hire_date) - 1988, 2, '0')
WHEN hire_date >= TO_DATE('1926-12-25', 'YYYY-MM-DD')
THEN '昭和' || LPAD(EXTRACT(YEAR FROM hire_date) - 1925, 2, '0')
WHEN hire_date >= TO_DATE('1912-07-30', 'YYYY-MM-DD')
THEN '大正' || LPAD(EXTRACT(YEAR FROM hire_date) - 1911, 2, '0')
WHEN hire_date >= TO_DATE('1868-01-25', 'YYYY-MM-DD')
THEN '明治' || LPAD(EXTRACT(YEAR FROM hire_date) - 1867, 2, '0')
ELSE '対象外'
END
|| '年'
|| TO_CHAR(hire_date, 'MM"月"DD"日"') AS wareki_manual
FROM employees;
実行結果
HIRE_DATE WAREKI_MANUAL
----------- ------------------
2023-10-15 令和05年10月15日
2015-04-01 平成27年04月01日
1985-03-20 昭和60年03月20日
元年表記への対応
日本の慣習では、各元号の最初の年を「元年」と表記します。CASE文を使えばこの対応も可能です。
SQL
-- 元年表記に対応した和暦変換
SELECT
CASE
WHEN hire_date >= TO_DATE('2019-05-01', 'YYYY-MM-DD') THEN
'令和' ||
CASE WHEN EXTRACT(YEAR FROM hire_date) = 2019
THEN '元'
ELSE TO_CHAR(EXTRACT(YEAR FROM hire_date) - 2018)
END
WHEN hire_date >= TO_DATE('1989-01-08', 'YYYY-MM-DD') THEN
'平成' ||
CASE WHEN EXTRACT(YEAR FROM hire_date) = 1989
THEN '元'
ELSE TO_CHAR(EXTRACT(YEAR FROM hire_date) - 1988)
END
ELSE 'その他'
END
|| '年'
|| TO_CHAR(hire_date, 'MM"月"DD"日"') AS wareki_gannen
FROM employees;
実行結果
WAREKI_GANNEN
------------------
令和元年06月15日 ← 2019年の場合
令和05年10月15日 ← 2023年の場合
PL/SQL関数で和暦変換を再利用可能にする
和暦変換のロジックをPL/SQL関数にまとめておけば、SQL文やアプリケーションから簡単に呼び出せます。元年対応やNULLチェックも組み込んだ実用的な関数を紹介します。
PL/SQL
CREATE OR REPLACE FUNCTION to_wareki(
p_date IN DATE
) RETURN VARCHAR2
IS
v_year NUMBER;
v_era VARCHAR2(10);
v_offset NUMBER;
v_era_yr NUMBER;
BEGIN
-- NULL チェック
IF p_date IS NULL THEN
RETURN NULL;
END IF;
v_year := EXTRACT(YEAR FROM p_date);
-- 元号と基準年を判定
IF p_date >= TO_DATE('2019-05-01', 'YYYY-MM-DD') THEN
v_era := '令和'; v_offset := 2018;
ELSIF p_date >= TO_DATE('1989-01-08', 'YYYY-MM-DD') THEN
v_era := '平成'; v_offset := 1988;
ELSIF p_date >= TO_DATE('1926-12-25', 'YYYY-MM-DD') THEN
v_era := '昭和'; v_offset := 1925;
ELSIF p_date >= TO_DATE('1912-07-30', 'YYYY-MM-DD') THEN
v_era := '大正'; v_offset := 1911;
ELSIF p_date >= TO_DATE('1868-01-25', 'YYYY-MM-DD') THEN
v_era := '明治'; v_offset := 1867;
ELSE
RETURN '対象外';
END IF;
v_era_yr := v_year - v_offset;
-- 元年対応
IF v_era_yr = 1 THEN
RETURN v_era || '元年'
|| TO_CHAR(p_date, 'MM"月"DD"日"');
ELSE
RETURN v_era
|| LPAD(v_era_yr, 2, '0') || '年'
|| TO_CHAR(p_date, 'MM"月"DD"日"');
END IF;
END;
/
関数の使用例
SQL
-- 関数を使って和暦変換
SELECT
to_wareki(SYSDATE) AS today_wareki,
to_wareki(TO_DATE('2019-05-01', 'YYYY-MM-DD')) AS reiwa_first,
to_wareki(TO_DATE('1989-01-08', 'YYYY-MM-DD')) AS heisei_first
FROM DUAL;
実行結果
TODAY_WAREKI REIWA_FIRST HEISEI_FIRST
----------------- --------------- ----------------
令和07年06月15日 令和元年05月01日 平成元年01月08日
ポイント:PL/SQL関数にしておけば、将来新しい元号が追加された場合も関数内のIF文を1か所修正するだけで対応できます。保守性が大幅に向上します。
他RDBMSとの和暦変換比較
和暦変換の方法はRDBMSによって異なります。主要なRDBMSでの和暦対応状況を比較します。
| RDBMS |
和暦対応 |
方法 |
| Oracle |
ネイティブ対応 |
TO_CHAR + NLS_CALENDAR='Japanese Imperial' |
| SQL Server |
ネイティブ対応 |
FORMAT(date, 'ggy年M月d日', 'ja-JP') |
| PostgreSQL |
非対応 |
独自関数の作成が必要 |
| MySQL |
非対応 |
独自関数の作成が必要 |
SQL Serverでの和暦変換
SQL Server
-- SQL Server: FORMAT関数で和暦
SELECT
FORMAT(GETDATE(), 'ggy年M月d日', 'ja-JP') AS wareki;
-- 出力例: 令和7年6月15日
-- SQL Server: 略称表記
SELECT
FORMAT(GETDATE(), 'gy/MM/dd', 'ja-JP') AS wareki_short;
-- 出力例: R7/06/15
SQL ServerではFORMAT関数の第3引数にカルチャja-JPを指定するだけで和暦が使えます。Oracleと違ってALTER SESSIONは不要で、より直感的に記述できます。
Oracle vs SQL Server フォーマット対応表
| 表示内容 |
Oracle |
SQL Server |
| 元号(正式) |
EE → 令和 |
gg → 令和 |
| 元号(略称) |
E → R |
g → R |
| 年(2桁) |
YY → 07 |
yy → 07 |
| NLSパラメータ |
NLS_CALENDAR |
ja-JPカルチャ |
よくあるエラーと対処法
和暦変換で遭遇しやすいエラーとその対処法をまとめます。
ORA-01821: 日付書式が無効です
| 項目 |
内容 |
| エラー |
ORA-01821: 日付書式が無効です |
| 原因 |
NLS_CALENDARを指定せずにEE/Eフォーマットを使用した |
| 対処 |
TO_CHARの第3引数にNLS_CALENDAR=Japanese Imperialを追加する |
エラーになるSQL
-- NG: NLS_CALENDARなしでEEを使用
SELECT TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"') FROM DUAL;
-- → ORA-01821
-- OK: NLS_CALENDARを指定
SELECT TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') FROM DUAL;
ORA-01898: リテラルが長すぎます
| 項目 |
内容 |
| エラー |
ORA-01898: リテラルが長すぎます |
| 原因 |
フォーマット文字列内のリテラル(ダブルクォート部分)が長すぎる |
| 対処 |
リテラル部分を短くするか、複数のTO_CHARを連結(||)する |
元号が英語で表示される
| 項目 |
内容 |
| 症状 |
「令和」ではなく「Reiwa」と表示される |
| 原因 |
NLS_DATE_LANGUAGEがENGLISHまたはAMERICANに設定されている |
| 対処 |
NLS_DATE_LANGUAGE=JAPANESEを明示的に指定する |
SQL
-- 日本語で元号を表示するにはNLS_DATE_LANGUAGEを指定
SELECT TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial NLS_DATE_LANGUAGE=JAPANESE'
) FROM DUAL;
明治以前の日付でエラーが発生する
注意:OracleのJapanese Imperialカレンダーは明治(1868年)以降の日付のみ対応しています。それ以前の日付を和暦変換しようとするとエラーが発生します。明治以前の日付はCASE文による手動変換で対応するか、西暦のまま扱いましょう。
実務パターン
実際のシステム開発で和暦が必要となる代表的なパターンを紹介します。
帳票出力での和暦表示
帳票やレポートで和暦を使用する場合のSQLパターンです。
SQL
-- 帳票ヘッダー用の日付(和暦フル表記)
SELECT
'発行日:' ||
TO_CHAR(SYSDATE, 'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS issue_date,
'作成者:管理部' AS author
FROM DUAL;
実行結果
ISSUE_DATE AUTHOR
------------------------ -----------
発行日:令和07年06月15日 作成者:管理部
年度計算(和暦ベース)
日本の会計年度(4月始まり)を和暦で表示するパターンです。
SQL
-- 年度(4月始まり)を和暦で取得
SELECT
TO_CHAR(
ADD_MONTHS(SYSDATE, -3),
'EEYY',
'NLS_CALENDAR=Japanese Imperial'
) || '年度' AS fiscal_year_wareki
FROM DUAL;
実行結果
FISCAL_YEAR_WAREKI
------------------
令和07年度
ADD_MONTHS(SYSDATE, -3)で3か月前の日付を基準にすることで、4月〜翌3月を同一年度として扱えます。
契約書の日付範囲を和暦で表示
SQL
-- 契約期間を和暦で表示
SELECT
contract_id,
TO_CHAR(start_date,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) || ' 〜 ' ||
TO_CHAR(end_date,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS contract_period
FROM contracts;
実行結果
CONTRACT_ID CONTRACT_PERIOD
----------- ----------------------------------------
1001 令和05年04月01日 〜 令和08年03月31日
1002 平成30年10月01日 〜 令和03年09月30日
元号をまたぐ期間の処理
平成から令和にまたがるデータを扱う場合の注意点です。
SQL
-- 元号の境界日付を確認
SELECT
TO_CHAR(TO_DATE('2019-04-30', 'YYYY-MM-DD'),
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS heisei_last,
TO_CHAR(TO_DATE('2019-05-01', 'YYYY-MM-DD'),
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial') AS reiwa_first
FROM DUAL;
実行結果
HEISEI_LAST REIWA_FIRST
----------------- -----------------
平成31年04月30日 令和01年05月01日
注意:元号をまたぐ期間の日数計算や比較は、必ず西暦(DATE型)ベースで行いましょう。和暦文字列同士の比較は正しくソートできません。和暦はあくまで表示用として使い、内部処理は西暦で行うのが鉄則です。
VIEWでの和暦活用
頻繁に和暦表示が必要なテーブルには、VIEWを作成しておくと便利です。
SQL
-- 和暦付きの社員VIEW
CREATE OR REPLACE VIEW v_employees_wareki AS
SELECT
emp_id,
emp_name,
hire_date,
TO_CHAR(hire_date,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS hire_date_wareki,
birth_date,
TO_CHAR(birth_date,
'EEYY"年"MM"月"DD"日"',
'NLS_CALENDAR=Japanese Imperial'
) AS birth_date_wareki
FROM employees;
-- VIEWを使って和暦で検索
SELECT emp_name, hire_date_wareki
FROM v_employees_wareki
WHERE hire_date >= TO_DATE('2019-05-01', 'YYYY-MM-DD');
実行結果
EMP_NAME HIRE_DATE_WAREKI
---------- -----------------
鈴木花子 令和02年04月01日
佐藤一郎 令和05年10月15日
まとめ
Oracleで日付を和暦で取得する方法を体系的に解説しました。最後に重要なポイントを整理します。
| 方法 |
用途 |
特徴 |
| TO_CHAR + NLS_CALENDAR |
標準的な和暦変換 |
最も簡潔、Oracle標準 |
| ALTER SESSION |
セッション全体で和暦を使用 |
毎回NLSパラメータ指定不要 |
| CASE文による手動変換 |
カスタムフォーマット・元年対応 |
柔軟性が高い |
| PL/SQL関数 |
再利用可能な和暦変換 |
保守性が高い |
| VIEW |
和暦列の定常的な利用 |
アプリ側の修正不要 |
実務で押さえておくべきポイント
- TO_CHAR + NLS_CALENDARが最も簡潔な和暦変換方法
- 元号を日本語で表示するにはNLS_DATE_LANGUAGE=JAPANESEを指定する
- 元年対応が必要な場合はCASE文またはPL/SQL関数を使う
- 日付の比較・計算は必ず西暦(DATE型)で行い、和暦は表示用に限定する
- 頻繁に使うテーブルはVIEWで和暦列を用意すると便利
- 他RDBMSへの移行時は和暦変換方法の違いに注意する