【PHP8.x】subメソッドの使い方

subメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

subメソッドは、DateTimeオブジェクトから指定された期間を減算するメソッドです。このメソッドは、日付や時刻の計算において、現在の日時や特定の日時から過去の日時を求めたい場合に非常に役立ちます。例えば、「現在の日時から5日前の日時」や「特定の日付から3ヶ月前の日時」を簡単に算出することができます。

subメソッドの唯一の引数には、減算したい期間を定義したDateIntervalオブジェクトを指定します。DateIntervalオブジェクトは、年、月、日、時間、分、秒といった時間の差を表現するために使用されます。

このメソッドの大きな特徴として、呼び出し元のDateTimeオブジェクト自体を変更する(破壊的な操作である)点が挙げられます。そのため、元のDateTimeオブジェクトを変更したくない場合は、事前にクローンを作成するか、DateTimeImmutableクラスの使用を検討してください。メソッドが正常に実行されると、減算された日時を持つDateTimeオブジェクトが返されます。これにより、メソッドチェーンとしてさらに他のDateTimeメソッドと組み合わせて使用することも可能です。

日付と時刻を扱うアプリケーション開発において、特定の期間を遡る計算が必要な場面で頻繁に利用されます。

構文(syntax)

1<?php
2// 現在の日時を表すDateTimeオブジェクトを作成します。
3$date = new DateTime('2023-01-01 12:00:00');
4
5// 減算したい期間をDateIntervalオブジェクトで定義します。
6// 例: 1ヶ月と2週間と3日と4時間と5分と6秒
7$interval = new DateInterval('P1M2W3DT4H5M6S');
8
9// subメソッドを使用して、DateTimeオブジェクトから指定した期間を減算します。
10$date->sub($interval);
11
12// 結果の日時を表示します。
13echo $date->format('Y-m-d H:i:s');
14?>

引数(parameters)

DateInterval $interval

  • DateInterval $interval: 引き算する期間を表すDateIntervalオブジェクト

戻り値(return)

DateTime|false

指定された期間(DateInterval オブジェクトで表される)を元の DateTime オブジェクトから減算した新しい DateTime オブジェクトを返します。減算に失敗した場合は false を返します。

サンプルコード

PHPで日付を減算する

1<?php
2
3/**
4 * DateTime::sub メソッドのサンプルコード
5 *
6 * このスクリプトは、HTMLフォームからの入力を受け取り、指定された日付から特定の日数を減算します。
7 * システムエンジニアを目指す初心者向けに、フォーム処理(submit)とPHPの日付操作の基本を示します。
8 */
9
10// フォームがPOST送信された場合の処理
11if ($_SERVER['REQUEST_METHOD'] === 'POST') {
12    // フォームから基準日と減算する日数を取得
13    // null合体演算子 (??) で未定義の場合に備える
14    $baseDateStr = $_POST['base_date'] ?? null;
15    $daysToSubtract = $_POST['days_to_subtract'] ?? null;
16
17    $resultDate = null; // 減算後の日付を格納する変数
18    $errorMessage = null; // エラーメッセージを格納する変数
19
20    try {
21        // 入力値の検証
22        if ($baseDateStr && is_numeric($daysToSubtract) && (int)$daysToSubtract >= 0) {
23            // 基準日を DateTime オブジェクトとして生成
24            // 無効な日付文字列の場合、Exception がスローされる
25            $dateTime = new DateTime($baseDateStr);
26
27            // 減算する期間を DateInterval オブジェクトとして生成
28            // 'P' は Period(期間)、'D' は Days(日)を表すISO 8601形式
29            $interval = new DateInterval("P{$daysToSubtract}D");
30
31            // DateTime::sub メソッドで日付を減算
32            // 成功すると新しい DateTime オブジェクトを返し、失敗すると false を返す
33            $modifiedDateTime = $dateTime->sub($interval);
34
35            if ($modifiedDateTime) {
36                // 減算後の日付を指定したフォーマットで取得
37                $resultDate = $modifiedDateTime->format('Y-m-d H:i:s');
38            } else {
39                // sub メソッドが false を返した場合(稀だが念のため)
40                $errorMessage = "日付の減算処理に失敗しました。";
41            }
42        } else {
43            // 入力値が不正な場合のエラーメッセージ
44            $errorMessage = "有効な基準日と0以上の減算日数を入力してください。";
45        }
46    } catch (Exception $e) {
47        // DateTime や DateInterval の生成時にエラーが発生した場合のハンドリング
48        $errorMessage = "日付処理中にエラーが発生しました: " . $e->getMessage();
49    }
50}
51?>
52<!DOCTYPE html>
53<html lang="ja">
54<head>
55    <meta charset="UTF-8">
56    <meta name="viewport" content="width=device-width, initial-scale=1.0">
57    <title>PHP DateTime::sub サンプル</title>
58    <style>
59        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 20px; background-color: #f4f7f6; color: #333; }
60        .container { max-width: 600px; margin: 30px auto; background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
61        h1 { color: #0056b3; text-align: center; margin-bottom: 25px; }
62        p { line-height: 1.6; }
63        form div { margin-bottom: 15px; }
64        label { display: block; margin-bottom: 5px; font-weight: bold; color: #555; }
65        input[type="date"],
66        input[type="number"] {
67            width: calc(100% - 20px);
68            padding: 10px;
69            border: 1px solid #ccc;
70            border-radius: 5px;
71            box-sizing: border-box;
72            font-size: 16px;
73        }
74        input[type="submit"] {
75            display: block;
76            width: 100%;
77            padding: 12px;
78            background-color: #007bff;
79            color: white;
80            border: none;
81            border-radius: 5px;
82            font-size: 18px;
83            cursor: pointer;
84            transition: background-color 0.3s ease;
85        }
86        input[type="submit"]:hover {
87            background-color: #0056b3;
88        }
89        .result, .error {
90            margin-top: 25px;
91            padding: 15px;
92            border-radius: 5px;
93            font-size: 16px;
94        }
95        .result {
96            background-color: #e6f7ff;
97            border: 1px solid #91d5ff;
98            color: #0050b3;
99        }
100        .error {
101            background-color: #fff0f6;
102            border: 1px solid #ffadd2;
103            color: #cf1322;
104        }
105        .result p, .error p { margin: 5px 0; }
106        .code-explanation { font-size: 0.9em; color: #666; margin-top: 20px; padding: 10px; background-color: #f9f9f9; border-left: 3px solid #007bff; }
107    </style>
108</head>
109<body>
110    <div class="container">
111        <h1>日付減算ツール (<code>DateTime::sub</code>)</h1>
112        <p>
113            基準日と減算したい日数を入力し、「日付を減算」ボタンを押してください。
114            PHPの<code>DateTime::sub</code>メソッドを使用して、新しい日付を計算します。
115        </p>
116
117        <form method="POST" action="">
118            <div>
119                <label for="base_date">基準日:</label>
120                <!-- 現在日付を初期値として設定 -->
121                <input type="date" id="base_date" name="base_date" value="<?= htmlspecialchars($baseDateStr ?? date('Y-m-d')) ?>" required>
122            </div>
123            <div>
124                <label for="days_to_subtract">減算する日数:</label>
125                <!-- 7日を初期値として設定、0以上の整数のみ入力可能 -->
126                <input type="number" id="days_to_subtract" name="days_to_subtract" value="<?= htmlspecialchars($daysToSubtract ?? '7') ?>" min="0" required>
127            </div>
128            <div>
129                <input type="submit" value="日付を減算">
130            </div>
131        </form>
132
133        <?php if (isset($resultDate)): ?>
134            <div class="result">
135                <p><strong>元の基準日:</strong> <?= htmlspecialchars($baseDateStr) ?></p>
136                <p><strong>減算した日数:</strong> <?= htmlspecialchars($daysToSubtract) ?></p>
137                <p><strong>減算後の日付:</strong> <?= htmlspecialchars($resultDate) ?></p>
138            </div>
139        <?php elseif (isset($errorMessage)): ?>
140            <div class="error">
141                <p><strong>エラー:</strong> <?= htmlspecialchars($errorMessage) ?></p>
142            </div>
143        <?php endif; ?>
144    </div>
145</body>
146</html>

PHP 8 の DateTime::sub メソッドは、DateTime クラスに属し、特定の日付から指定された期間を減算するために使用されます。このメソッドは、引数として DateInterval オブジェクトを受け取ります。DateInterval は「2日」や「1ヶ月」といった期間を定義するためのPHPのクラスで、例えば現在の日付から7日間前の日付を計算したい場合に便利です。

サンプルコードでは、HTMLフォームからのデータ送信(php submit)を受け取り、ユーザーが入力した基準日から、指定された日数を減算する処理を行っています。具体的には、まずフォームから受け取った日付文字列を基に DateTime オブジェクトを作成し、次に減算したい日数を DateInterval オブジェクトとして生成します。その後、この DateIntervalDateTime::sub メソッドに渡すことで日付を減算します。成功した場合、減算後の新しい DateTime オブジェクトが戻り値として返され、これを format メソッドで表示に適した文字列に変換して出力します。もし減算処理に失敗した場合は false が返されることがありますが、通常は有効な DateInterval が与えられれば DateTime オブジェクトが返されます。このコードは、ウェブフォームの処理とPHPでの日付操作の基本を学ぶための良い例であり、エラー発生時には try-catch で例外を捕捉し、適切なメッセージを表示する堅牢性も備えています。

このサンプルコードでは、フォームから受け取った入力値は、常に不正な値が送られる可能性があるため、is_numericなどで必ず検証することが重要です。また、DateTimeDateIntervalのオブジェクト生成時に無効な値が渡されると例外が発生しますので、try-catch構文でエラーを捕捉し適切に処理すると安全性が高まります。DateTime::subメソッドは、成功すると変更後の新しいDateTimeオブジェクトを返しますが、処理に失敗した場合はfalseを返す可能性も考慮し、戻り値をチェックする習慣をつけましょう。さらに、ユーザーの入力をHTMLに出力する際は、htmlspecialchars()関数を使用して必ずサニタイズし、クロスサイトスクリプティング(XSS)攻撃を防ぐことがセキュリティ上不可欠です。

PHP DateTime::subで日付を減算する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * DateTime::sub() を使用して、特定の日時から一定期間を引く例を示します。
7 *
8 * この関数は、現在の日時から1ヶ月と10日を引いた結果を表示します。
9 * DateTime::sub() は、指定された DateInterval の期間を
10 * DateTime オブジェクトから減算するためのメソッドです。
11 */
12function demonstrateDateTimeSub(): void
13{
14    try {
15        // 現在の日時でDateTimeオブジェクトを生成します。
16        $date = new DateTime();
17        echo '現在の日時: ' . $date->format('Y-m-d H:i:s') . PHP_EOL;
18
19        // 減算する期間(1ヶ月と10日)を表すDateIntervalオブジェクトを生成します。
20        // 'P1M10D' は Period(期間) 1 Month(月) 10 Days(日) を意味します。
21        $interval = new DateInterval('P1M10D');
22
23        // sub()メソッドを呼び出して、期間を減算します。
24        // このメソッドは、元の$dateオブジェクトを直接変更します。
25        $date->sub($interval);
26
27        // 結果をフォーマットして表示します。
28        echo '1ヶ月と10日前の日時: ' . $date->format('Y-m-d H:i:s') . PHP_EOL;
29    } catch (Exception $e) {
30        // 例外が発生した場合にエラーメッセージを表示します。
31        echo 'エラー: ' . $e->getMessage() . PHP_EOL;
32    }
33}
34
35// 関数を実行してデモを表示します。
36demonstrateDateTimeSub();

DateTime::sub()は、DateTimeオブジェクトが示す特定の日時から、指定した期間を引き算するためのメソッドです。日付や時刻の計算を簡単に行うことができます。

サンプルコードでは、まずnew DateTime()を使って現在の日時を持つオブジェクトを生成します。次に、new DateInterval('P1M10D')で、引き算したい期間である「1ヶ月と10日」を表現するDateIntervalオブジェクトを作成しています。この'P1M10D'という文字列は、期間(Period)が1ヶ月(Month)と10日(Day)であることを示す特別な形式です。

ハイライトとなる$date->sub($interval)の部分で、$dateオブジェクトが持つ日時から$intervalの期間が減算されます。このメソッドの重要な特徴は、新しいDateTimeオブジェクトを返すのではなく、呼び出し元である$dateオブジェクト自身の値を直接変更する点です。

引数には、減算したい期間を表すDateIntervalオブジェクトを渡します。戻り値は、処理が成功した場合には変更後のDateTimeオブジェクト自身を、失敗した場合にはfalseを返します。

DateTime::sub()メソッドを使用する際の最も重要な注意点は、呼び出したオブジェクトの値を直接変更する点です。つまり、$date->sub($interval)を実行すると、元の$dateの値は計算後の過去の日時に上書きされ、元の値は失われます。もし計算前の日時も保持したい場合は、sub()を呼び出す前にオブジェクトをcloneで複製するか、元の値が変更されないDateTimeImmutableクラスの利用を検討してください。また、DateIntervalで月単位の計算をする際は、月によって日数が異なるため、単純な日数計算とは結果が異なる場合がある点も覚えておきましょう。

【PHP8.x】subメソッドの使い方 | いっしー@Webエンジニア