【Apex】Date / Datetime もう迷わない!現在日時や日付計算を柔軟に扱う方法

  • URLをコピーしました!

Apex開発では、レコードの作成日・更新日、期限、通知タイミングなど、 ”日付や日時を基にした処理” が頻繁に登場します。
例えば以下のような状況はありませんか?

  • 「30日以内に作成されたレコードを抽出したい」
  • 「来月の1日を基準に処理を組みたい」
  • 「今日から3営業日後を期限にしたい」

本記事では、Apexで日付や日時を自在に扱うための基本と活用パターンについて解説します。

目次

Date / Datetime の基本的な使用方法

DateとDatetimeの違い

クラス特徴主な用途
Date2025-04-01日付のみ(時刻なし)期日、スケジュール日
Datetime2025-04-01 15:00:00日付+時刻レコード作成日、ログ

公式リファレンス
Date クラス
DateTime クラス

よく使用する関数一覧

現在の日付・時刻を取得

以下の通り、Date.today()System.now()Datetime.now()を使用します。

// Date型の場合
Date today = Date.today();

// Datetime型の場合
// どちらであっても同じGMTタイムゾーンを返します
Datetime now = System.now();
Datetime nowDt = Datetime.now();

日付を加算・減算

以下の通り、addDays()を使用します。
(減算の場合は、マイナス値を指定)

// 30日前の日付
Date thirtyDaysAgoDate = Date.today().addDays(-30);
Datetime thirtyDaysAgoDatetime = System.now().addDays(-30);

// 7日後の日付
Date nextWeekDate = Date.today().addDays(7);
Datetime nextWeekDateTime = System.now().addDays(7);

年や月も上記と同様に加算・減算が可能であり、年の場合はaddYears()を、月の場合はaddMonths()を使用します。

年・月・日を個別に取得

以下の通り、year()month()day() を使用します。

// 年 を取得
Integer dateYear = Date.today().year();
Integer datetimeYear = System.now().year();

// 月 を取得
Integer dateMonth = Date.today().month();
Integer datetimeMonth = System.now().month();

// 日 を取得
Integer dateDay = Date.today().day();
Integer datetimeDay = System.now().day();

Datetime → Date 変換

以下の通り、Datetime型に対して、date()を使用します。

// Datetime → Date 変換
Date onlyDate = System.now().date();

Date → Datetime 変換

以下の通り、DateTime.newInstanceGMT(Date, Time) を使用します。

// Date → Datetime 変換
Datetime fullDatetime = DateTime.newInstanceGMT(Date.today(), Time.newInstance(0, 0, 0, 0));

DateTime.newInstanceGMT() の第一引数はDate型、第二引数はTime型 を渡しており、
Time型 の Time.newInstance(0, 0, 0, 0) では、”00:00:00″の時刻を指定しています。

文字列からの日付、日時変換

String → Date / Datetime の違いとフォーマット制約

String → Date 変換

Date.valueOf(String)を使用

// String → Date 変換
Date dateVal = Date.valueOf('2025-04-01');

フォーマットが yyyy-MM-dd(4桁年-2桁月-2桁日) 以外の場合はエラーになります。
(”2025/04/01″ や “04-01-2025” )

String → Datetime 変換

Datetime.valueOf(String)を使用

// String → Datetime 変換
Datetime datetimeVal = Datetime.valueOf('2025-04-01 15:00:00');

フォーマットが yyyy-MM-dd HH:mm:ss(4桁年-2桁月-2桁日 時間:分:秒) 以外の場合はエラーになります。
(”2025/04/01 15:00:00″ や “04-01-2025 15:00:00” )
タイムゾーンは ログインユーザーのタイムゾーンが自動的に適用されます(例:JSTなら+09:00)

Date / Datetime を使い分ける

Datetime のみ可能なこと

Datetime型は Date型の機能を含んでおり、Date型でできる操作の多くはDatetime型でも可能です。
ただし、時間や秒単位の処理など、Datetime型にしかできない操作も存在します。

  • 現在時刻の取得
  • タイムゾーンを考慮した時刻表示
  • 秒単位の計算

Date のメリット

  • 簡潔で読みやすくバグが発生しづらい
  • 意図しない時間計算による抽出ミスや比較ミスを防ぐことができる

Datetime=で比較する際、時刻まで一致しなければ false になります。
単純に日付だけの比較であれば、Date型を使用する方が適切です。

日付ロジック活用例

過去30日以内に作成されたレコードを取得

// 30日前の日付を取得
Date limitDate = Date.today().addDays(-30);

// 上記を元にCreatedDateを条件にしてレコードを取得
List recentAccounts = [
    SELECT Id, Name, CreatedDate FROM Account
    WHERE CreatedDate >= :limitDate
];

今月中に期限がくるToDoの抽出

// 当月の最終日を取得
Date endOfMonth = Date.today().toStartOfMonth().addMonths(1).addDays(-1);

// 上記を元にDueDate__cを条件にしてレコードを取得
List<Task__c> tasks = [
    SELECT Id, Subject__c, DueDate__c FROM Task__c
    WHERE DueDate__c <= :endOfMonth
];

現在の時刻と比較して、直近1時間以内に作成されたAccountを抽出

// 1時間前の時刻を取得
Datetime oneHourAgo = System.now().addHours(-1);

// 上記を元にCreatedDate を条件にしてレコードを取得
List<Account> recentAccounts = [
    SELECT Id, Name, CreatedDate FROM Account
    WHERE CreatedDate >= :oneHourAgo
];

処理の所要時間を計測する(パフォーマンス測定)

// 処理開始前の時刻を取得
Datetime startTime = System.now();

// 実行したい処理
doHeavyCalculation();

// 処理完了後の時刻を取得
Datetime endTime = System.now();

// 処理時間を取得
Long execTime = endTime.getTime() - startTime.getTime();

まとめ

日付や日時の扱いは、Apex開発において非常に重要かつ実用性の高いスキルです。
単純な比較や抽出処理から、複雑なスケジュール制御、バッチの実行条件など、あらゆるロジックに関わってきます。

本記事では、DateとDatetime の違いや変換方法、よく使う関数、具体的な活用例までを解説いたしました。
これらの知識を正しく使い分けることで、実装ミスや意図しない挙動を未然に防ぎ、保守性の高いコードを書くことが可能となります。
ぜひ今回の内容を、ご自身の開発業務に取り入れてみてください!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次