MySQLで現在時刻を取得・操作・管理する完全ガイド【NOW(), TIMESTAMP, タイムゾーン設定】

目次

1. はじめに

MySQLで現在時刻を扱うケースとは?

MySQLでは、現在時刻を取得することがさまざまな場面で必要になります。たとえば、以下のようなユースケースが考えられます。

  • データ登録時のタイムスタンプ自動入力
  • 例えば、注文データやログデータを保存する際に、データの作成日時を記録する。
  • 現在時刻を基準にデータをフィルタリング
  • たとえば、過去7日間のデータだけを取得したり、未来の日付のデータを検索したりする場合。
  • 日付や時間を加工して表示
  • レポート作成時に、日時のフォーマットを整えて見やすくする。
  • 現在時刻を使ってデータの有効期限を管理
  • 例えば、クーポンの有効期限を現在時刻と比較して判定する。

このように、MySQLで現在時刻を適切に取得・操作することは、データベースの運用において重要なスキルです。

この記事で学べること

本記事では、以下の内容について詳しく解説していきます。

  • MySQLで現在時刻を取得する方法 (NOW(), CURRENT_TIMESTAMP など)
  • 日付や時間のフォーマット変更 (DATE_FORMAT() の使い方)
  • 現在時刻を使った日時計算 (INTERVAL を用いた日付操作)
  • タイムゾーンの変更方法 (SET SESSION time_zone)
  • 現在時刻をデフォルト値として使用する (CURRENT_TIMESTAMP の活用)
  • よくあるエラーの原因と対処法(FAQ)

MySQLを使って「現在時刻」を扱う際の基本から応用まで、実践的なSQLを交えて解説しますので、ぜひ最後までご覧ください。

2. MySQLで現在時刻を取得する方法

MySQLの現在時刻を取得する関数一覧

MySQLでは、現在時刻を取得するための関数がいくつかあります。それぞれの違いを理解し、適切に使い分けましょう。

関数取得内容
NOW()現在の日時(年月日+時間)SELECT NOW();2025-02-11 16:00:00
CURRENT_TIMESTAMPNOW()と同じ(SQL標準)SELECT CURRENT_TIMESTAMP;
CURDATE()現在の日付のみSELECT CURDATE();2025-02-11
CURTIME()現在の時間のみSELECT CURTIME();16:00:00

NOW() 関数を使う

NOW() は、MySQLで現在時刻を取得する最も一般的な関数です。
日付と時間の両方を取得できます。

SELECT NOW();

出力例:

2025-02-11 16:00:00
  • NOW() は、現在のシステム時刻を返します。
  • タイムゾーンの影響を受けるため、環境によっては想定とは異なる時間が表示されることがあります(詳細は「タイムゾーンの設定」の項で解説)。

CURRENT_TIMESTAMP の使い方

CURRENT_TIMESTAMPNOW() とほぼ同じ動作をします。SQL標準に準拠しており、他のデータベースでも同様に使用できる点が特徴です。

SELECT CURRENT_TIMESTAMP;

出力例:

2025-02-11 16:00:00

CURDATE() で日付のみを取得

CURDATE() は、現在の日付(年月日)だけを取得したい場合に使用します。

SELECT CURDATE();

出力例:

2025-02-11

CURTIME() で時間のみを取得

現在の時間(時・分・秒)のみを取得したい場合は、CURTIME() を使います。

SELECT CURTIME();

出力例:

16:00:00

どの関数を使うべきか?

目的推奨関数
日付と時間の両方を取得したいNOW() または CURRENT_TIMESTAMP
日付のみを取得したいCURDATE()
時間のみを取得したいCURTIME()

3. MySQLで現在時刻をフォーマットする方法

DATE_FORMAT() を使ったカスタムフォーマット

DATE_FORMAT() の基本構文

MySQLでは DATE_FORMAT() 関数を使うことで、日付や時間のフォーマットを自由に変更できます。

SELECT DATE_FORMAT(取得する日時, 'フォーマット指定子');

例: NOW()YYYY/MM/DD HH:MM 形式に変換する

SELECT DATE_FORMAT(NOW(), '%Y/%m/%d %H:%i');

出力:

2025/02/11 16:45

フォーマット指定子の一覧

指定子意味例 (2025-02-11 16:45:30)
%Y4桁の西暦2025
%m2桁の月(01-12)02
%d2桁の日(01-31)11
%H24時間表記の時(00-23)16
%i分(00-59)45
%s秒(00-59)30

TIME() で時間部分のみを取得

NOW() で取得した日時から 時間部分のみ を抜き出したい場合、TIME() 関数を使います。

SELECT TIME(NOW());

出力:

16:45:30

YEAR()MONTH()DAY() で部分的に取得

特定の部分だけを抜き出す場合は、以下の関数を使います。

関数取得内容SQL出力例 (2025-02-11 16:45:30)
YEAR()SELECT YEAR(NOW());2025
MONTH()SELECT MONTH(NOW());2
DAY()SELECT DAY(NOW());11

フォーマット変更の実践例

以下のSQLは、さまざまなフォーマットを実際に試すのに便利です。

SELECT 
    NOW() AS '元の日時',
    DATE_FORMAT(NOW(), '%Y/%m/%d') AS 'YYYY/MM/DD形式',
    DATE_FORMAT(NOW(), '%H:%i:%s') AS '時:分:秒',
    TIME(NOW()) AS '時間のみ',
    YEAR(NOW()) AS '年',
    MONTH(NOW()) AS '月',
    DAY(NOW()) AS '日';

4. MySQLで現在時刻を使った日時計算

INTERVAL を使った加算・減算

基本構文

SELECT 現在時刻 + INTERVAL 数値 単位;
SELECT 現在時刻 - INTERVAL 数値 単位;

NOW() を基準にした加算

例えば、「1週間後の日時」を取得したい場合:

SELECT NOW() + INTERVAL 7 DAY;

出力例:

2025-02-18 16:30:00
単位意味
SECONDNOW() + INTERVAL 10 SECOND
MINUTENOW() + INTERVAL 5 MINUTE
HOURNOW() + INTERVAL 2 HOUR
DAYNOW() + INTERVAL 10 DAY
MONTHNOW() + INTERVAL 3 MONTH

DATEDIFF() を使った2つの日付の差分計算

SELECT DATEDIFF(NOW(), '2025-01-01');

出力例:

30

BETWEEN を使った日付範囲の絞り込み

SELECT * FROM orders
WHERE created_at BETWEEN '2025-02-01 00:00:00' AND '2025-02-28 23:59:59';

5. MySQLのタイムゾーン設定

現在のタイムゾーンを確認する

SHOW VARIABLES LIKE '%time_zone%';

出力例:

+------------------+----------------+
| Variable_name    | Value          |
+------------------+----------------+
| system_time_zone | UTC            |
| time_zone       | SYSTEM         |
+------------------+----------------+

セッション単位でタイムゾーンを変更する

SET SESSION time_zone = 'Asia/Tokyo';

サーバーのデフォルトタイムゾーンを変更する

設定ファイル (my.cnf) に以下を追加:

[mysqld]
default_time_zone = 'Asia/Tokyo'

UTC_TIMESTAMP を使ってUTC時間を取得

SELECT UTC_TIMESTAMP();

CONVERT_TZ() を使ってローカルタイムに変換

SELECT CONVERT_TZ(UTC_TIMESTAMP(), 'UTC', 'Asia/Tokyo');

6. MySQLで現在時刻をデフォルト値に設定する方法

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

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ON UPDATE CURRENT_TIMESTAMP で自動更新

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

DATETIME 型と TIMESTAMP 型の違い

タイムゾーンの影響CURRENT_TIMESTAMP のデフォルト値設定
TIMESTAMP受ける可能
DATETIME受けない不可

NOW() をデフォルト値にできない理由と解決策

ERROR 1067 (42000): Invalid default value for 'created_at'

解決策:

CREATE TRIGGER set_created_at
BEFORE INSERT ON logs
FOR EACH ROW
SET NEW.created_at = NOW();

7. MySQLのよくあるエラーと解決方法(FAQ)

NOW() をデフォルト値にできない

エラー例

CREATE TABLE logs (
    created_at DATETIME DEFAULT NOW()
);
ERROR 1067 (42000): Invalid default value for 'created_at'

解決策

CREATE TABLE logs (
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CURRENT_TIMESTAMP の時間がずれる

SHOW VARIABLES LIKE 'time_zone';

解決策

SET SESSION time_zone = 'Asia/Tokyo';

NOW() の結果が1時間ズレている

SHOW VARIABLES LIKE 'system_time_zone';

解決策

SET GLOBAL time_zone = 'Asia/Tokyo';

BETWEEN の範囲指定がうまくいかない

SELECT * FROM orders
WHERE created_at BETWEEN '2025-02-01' AND '2025-02-28';

解決策

SELECT * FROM orders
WHERE created_at BETWEEN '2025-02-01 00:00:00' AND '2025-02-28 23:59:59';

8. MySQLで現在時刻を扱う際のベストプラクティス

NOW() vs CURRENT_TIMESTAMP の使い分け

使用シーン推奨
SELECT 文で現在時刻を取得NOW()
INSERT 時に自動で現在時刻を設定CURRENT_TIMESTAMP
TIMESTAMP 型のデフォルト値として設定CURRENT_TIMESTAMP

TIMESTAMP vs DATETIME の使い分け

データ型タイムゾーンの影響ストレージサイズ
TIMESTAMP受ける4バイト
DATETIME受けない8バイト

UTCで保存し、ローカルタイムに変換する設計

SELECT CONVERT_TZ(event_time, 'UTC', 'Asia/Tokyo');

BETWEEN の代わりに >=< を使う

SELECT * FROM orders
WHERE created_at >= '2025-02-01 00:00:00' 
AND created_at < '2025-03-01 00:00:00';

INTERVAL の使い方を統一する

SELECT NOW() + INTERVAL 1 DAY;

データを正しくクリーンアップする

DELETE FROM logs WHERE created_at < NOW() - INTERVAL 1 YEAR LIMIT 1000;