Oracle・SQL Server・PostgreSQL・MySQL で、システム日付を取って整形する方法を試しました。4 つとも Docker で動かしています。忘れないようにまとめておきます。
早見表
システム日付の取得をまとめた表です。
| DB | システム日付の取得 | 「YYYY/MM/DD HH24:MI:SS」に整形 |
|---|---|---|
| Oracle | SYSDATE | TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') |
| SQL Server | GETDATE() | FORMAT(GETDATE(), 'yyyy/MM/dd HH:mm:ss') |
| PostgreSQL | current_timestamp | to_char(current_timestamp, 'YYYY/MM/DD HH24:MI:SS') |
| MySQL | NOW() | 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なら、問題なく動きました。
書式記号の対応表
| 意味 | Oracle | SQL Server | PostgreSQL | MySQL |
|---|---|---|---|---|
| 年(4 桁) | YYYY | yyyy | YYYY | %Y |
| 月 | MM | MM | MM | %m |
| 日 | DD | dd | DD | %d |
| 時(24 時間制) | HH24 | HH | HH24 | %H |
| 分 | MI | mm | MI | %i |
| 秒 | SS | ss | SS | %s |
| ミリ秒 | FF3 | fff | MS | なし(%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)は、処理を始めた時刻を返す
同じことで困っている方の参考になれば幸いです。
今回は、以上です。
参考資料
- TO_CHAR(日時)|Oracle SQL言語リファレンス
- 書式モデル|Oracle SQL言語リファレンス
- FORMAT (Transact-SQL)|Microsoft Learn
- CAST および CONVERT (Transact-SQL)|Microsoft Learn
- データ型書式設定関数|PostgreSQL 18 文書
- 日付/時刻関数と演算子|PostgreSQL 18 文書
- Date and Time Functions|MySQL 9.7 Reference Manual
- microsoft/mssql-docker #974(SQL Server 2025 のコンテナが起動時に落ちる件)

