あなたは言う:-
確実で正確な日付操作が必要な場合はstrotimeを使用できないようです
できます。それがどのように動作するかを知る必要があるだけです。あなたの質問により、いくつかのテストを実行するようになりました。
PHP は、1 か月を減算するときに日付から 30 日を単純に減算するわけではありませんが、あなたが見ている単一のケースからは減算しているように見えます。実際、ここでの私のテストでは、この場合、前月の初めに 31 日が追加されることが示唆されています (3 月 3 日の結果は、これを示唆しています)。
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$oneMonth = new \DateInterval('P1M');
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = new \DateTime("2013-{$month}-31 00:00:01");
var_dump($date->format($format));
$date->sub($oneMonth);
var_dump($date->format($format));
}
2013-11-12 と 2013-10-12 の間には 31 日あり、PHP はここで見られるように月の減算を正しく計算します。
$date = new \DateTime('2013-11-12 00:00:01');
var_dump($date);
$interval = new DateInterval('P1M');
$date->sub($interval);
var_dump($date);
あなたの特定のケースでは、2013-10-31 - 1 か月は存在しない 2013-09-31 です。日付/時刻関数は有効な日付を返す必要がありますが、2013-09-31 はそうではありません。
この場合、PHP は、上で述べたように、有効な日付に到達するために前月の月初に 31 日を追加するようです。
期待される動作がわかれば、それに応じてプログラムできます。現在の動作がユース ケースに合わない場合は、DateTime クラスを拡張して、適切な動作を提供できます。
私はそれを仮定し、同じように動作strtotime
します。このテストは、それらがそうであることを示唆しています。DateTime::sub()
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = date($format, strtotime('-1 month', strtotime("2013-{$month}-31 00:00:01")));
var_dump($date);
}