<p>DateTime クラスをよく使用していましたが、最近、月を追加するときにバグだと思われる問題に遭遇しました。いくつかの調査の結果、これは実際にはバグではなく、期待どおりに動作することが判明しました。ここにあるドキュメントによると、</p>
<ブロック引用>
<p>例 2 またはを追加するときは注意してください
月を引く</p>
</blockquote>
<pre class="brush:php;toolbar:false;"><?php
$date = new DateTime('2000-12-31');
$date->modify(' 1 か月');
echo $date->format('Y-m-d') . "n";
$date->modify(' 1 か月');
echo $date->format('Y-m-d') . "n";
?></pre>
<ブロック引用>
<pre class="brush:php;toolbar:false;">上記の例は次のように出力します。
2001-01-31
2001-03-03前>
</blockquote>
<p>これがバグとみなされない理由を誰か説明できますか? <br /><br />また、1 か月が設計どおりではなく期待どおりに機能するようにこれを修正するエレガントな解決策を持っている人はいますか? </p>
これは、DateTime メソッドを完全に使用し、クローンを作成せずにオブジェクトを直接変更する、もう 1 つの優れたソリューションです。
リーリーその出力は次のとおりです:
リーリーこれがバグではない理由:
現在の動作は正しいです。内部的には次のようになります:
1 month は月 (元は 1) を 1 増やします。これにより、日付が 2010-02-31 に変更されます。
2010 年の 2 月は 28 日しかないため、PHP はこの問題を自動的に修正し、2 月 1 日から引き続き日数をカウントします。最終的に得られた日付は3月3日でした。
希望の結果を得る方法:
希望の結果を得るには、次の月を手動で確認し、次の月の日数を追加します。
このコードを自分で書けることを願っています。具体的な手順を紹介しているだけです。
PHP 5.3 の方法:
正しい動作を得るには、PHP 5.3 で導入された相対時間ステートメント「first day of」を使用できます。このステートメントを「next month」、「fifth month」、または「8 months」と組み合わせて使用すると、指定した月の 1 日に移動できます。現在使用している「1 か月」と比較して、次のコードを使用して翌月の 1 日を取得できます。
リーリーこのスクリプトは 2 月を正しく出力します。 PHP がこの「来月の最初の日」ステートメントを処理すると、次のことが起こります:
next month では、月 (元は 1) が 1 ずつ増えます。これにより、日付が 2010-02-31 に変更されます。
first day of は日付の日数を 1 に設定し、日付は 2010-02-01 になります。