スポンサーリンク

【SQL】各データベースの日付取得と日付フォーマット(Oracle・SQL Server・PostgreSQL・MySQL)

SQL DB

Oracle・SQL Server・PostgreSQL・MySQL で、システム日付を取って整形する方法を試しました。4 つとも Docker で動かしています。忘れないようにまとめておきます。

早見表

システム日付の取得をまとめた表です。

DBシステム日付の取得「YYYY/MM/DD HH24:MI:SS」に整形
OracleSYSDATETO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS')
SQL ServerGETDATE()FORMAT(GETDATE(), 'yyyy/MM/dd HH:mm:ss')
PostgreSQLcurrent_timestampto_char(current_timestamp, 'YYYY/MM/DD HH24:MI:SS')
MySQLNOW()DATE_FORMAT(NOW(), '%Y/%m/%d %H:%i:%s')

気をつけたいのは、月と分の記号が DB ごとにバラバラなところです。 しかも間違えてもエラーにならないんですよね。

環境

  • OS:Windows 11 Pro(Docker Desktop 4.72.0)
  • Oracle AI Database 26ai Free(23.26.3)
  • SQL Server 2025(RTM-CU9)
  • PostgreSQL 18.6
  • MySQL 9.7.2

コンテナは、どれも -e TZ=Asia/Tokyo を付けて起動しています。理由は「ハマったこと」で書きますね。動作確認は 2026 年 10 月 9 日です。

nano:SQL Server 2025 の 2025-latest イメージは、僕の環境だと起動した直後に落ちてしまいました。Ubuntu 22.04 ベースの 2025-CU9-ubuntu-22.04 なら、問題なく動きました。

書式記号の対応表

意味OracleSQL ServerPostgreSQLMySQL
年(4 桁)YYYYyyyyYYYY%Y
月MMMMMM%m
日DDddDD%d
時(24 時間制)HH24HHHH24%H
分MImmMI%i
秒SSssSS%s
ミリ秒FF3fffMSなし(%f はマイクロ秒)

分の記号、見事にバラバラですね。Oracle と PostgreSQL は MI、SQL Server は小文字の mm、MySQL は %i です。

各 DB で実行してみた

Oracle

SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') AS now_str;
SELECT TO_CHAR(SYSTIMESTAMP, 'YYYY/MM/DD HH24:MI:SS.FF3') AS now_ms;
NOW_STR
--------------------
2026/10/09 23:20:07

NOW_MS
------------------------
2026/10/09 23:20:07.743

23ai からは、FROM DUAL を書かなくても動くようになりました。地味にうれしい変更です。

ミリ秒がほしいときは SYSTIMESTAMP を使います。SYSDATE は秒より細かい値を持っていないので、FF3 を付けると怒られます。

ORA-01821: date format not recognized

SQL Server

SELECT FORMAT(GETDATE(), 'yyyy/MM/dd HH:mm:ss') AS now_str;
SELECT FORMAT(SYSDATETIME(), 'yyyy/MM/dd HH:mm:ss.fff') AS now_ms;
SELECT CONVERT(varchar(19), GETDATE(), 120) AS style120;
GO
now_str
-------
2026/10/09 23:20:08

(1 rows affected)
now_ms
------
2026/10/09 23:20:08.558

(1 rows affected)
style120
--------
2026-10-09 23:20:08

(1 rows affected)

区切りが - でいいなら、CONVERT のスタイル番号 120 でも整形できます。

PostgreSQL

SELECT to_char(current_timestamp, 'YYYY/MM/DD HH24:MI:SS') AS now_str;
SELECT to_char(clock_timestamp(), 'YYYY/MM/DD HH24:MI:SS.MS') AS now_ms;
       now_str
---------------------
 2026/10/09 23:20:09
(1 row)

         now_ms
-------------------------
 2026/10/09 23:20:09.176
(1 row)

書き方は Oracle とほぼ同じです。ミリ秒だけ MS になります。

MySQL

SELECT DATE_FORMAT(NOW(), '%Y/%m/%d %H:%i:%s') AS now_str;
SELECT DATE_FORMAT(NOW(3), '%Y/%m/%d %H:%i:%s.%f') AS now_us;
+---------------------+
| now_str             |
+---------------------+
| 2026/10/09 23:20:09 |
+---------------------+
+----------------------------+
| now_us                     |
+----------------------------+
| 2026/10/09 23:20:09.805000 |
+----------------------------+

MySQL には、ミリ秒(3 桁)の記号がありません。%f はマイクロ秒(6 桁)なので、NOW(3) と組み合わせると末尾が 000 になります。

ハマったこと

分のつもりで月を書いても、エラーにならない

わざと「分」の位置に「月」の記号を書いてみました。どの DB もエラーにならず、しれっとそれっぽい時刻を返してきます。

DB書いた書式出力
Oracle'YYYY/MM/DD HH24:MM:SS'2026/10/09 22:10:02
SQL Server'yyyy/mm/dd hh:mm:ss'2026/53/09 10:53:14
PostgreSQL'YYYY/MM/DD HH24:MM:SS'2026/10/09 22:10:57
MySQL'%Y/%m/%d %H:%m:%s'2026/10/09 22:10:00

分のところに、月の 10 が入っちゃっていますね。SQL Server は逆で、月のところに分の 53 が入りました。hh は 12 時間制なので、時も 10 になっています。

何度実行しても「分」が今月の数字のままなら、記号の取り違えを疑うのがよさそうです。

コンテナの中の時刻が、9 時間ずれていた

最初は TZ を付けずにコンテナを起動していました。すると、PC の時計は 22 時台なのに、どの DB も 13 時台の時刻を返してきたんです。

 2026-10-09 13:40:51.832123+00

これは PostgreSQL の current_timestamp です。末尾が +00 で、UTC になっていますね。原因は、コンテナのタイムゾーンが UTC だったことでした。

docker run に -e TZ=Asia/Tokyo を付けて作り直したら、4 つとも日本時間を返すようになりました。

current_timestamp と NOW() は「今この瞬間」ではない

PostgreSQL の current_timestamp は、トランザクションを始めた時刻を返します。MySQL の NOW() は、文を実行し始めた時刻です。MySQL で、途中に 2 秒待ちを入れて試してみました。

SELECT NOW(), SYSDATE(), SLEEP(2), NOW(), SYSDATE();
+---------------------+---------------------+----------+---------------------+---------------------+
| NOW()               | SYSDATE()           | SLEEP(2) | NOW()               | SYSDATE()           |
+---------------------+---------------------+----------+---------------------+---------------------+
| 2026-10-09 22:56:38 | 2026-10-09 22:56:38 |        0 | 2026-10-09 22:56:38 | 2026-10-09 22:56:40 |
+---------------------+---------------------+----------+---------------------+---------------------+

NOW() は止まったままで、SYSDATE() だけが 2 秒進んでいます。本当に「今」の時刻がほしいときは、PostgreSQL なら clock_timestamp()、MySQL なら SYSDATE() を使います。

まとめ

  • 整形は、Oracle と PostgreSQL が TO_CHAR、SQL Server が FORMAT、MySQL が DATE_FORMAT
  • 月と分の記号は DB ごとに違う。間違えてもエラーにならないので要注意
  • Docker で試すなら、TZ=Asia/Tokyo を付けて起動する
  • current_timestamp(PostgreSQL)と NOW()(MySQL)は、処理を始めた時刻を返す

同じことで困っている方の参考になれば幸いです。

今回は、以上です。

参考資料

あわせて読みたい

タイトルとURLをコピーしました