2

strotime確実で正確な日付操作が必要な場合は使えないようです。たとえば、1 か月が 31 日ある場合、1 か月strtotime全体ではなく、単に 30 日を差し引いたように見えます。

たとえば、$event["EndDate"]が「2013-10-31 00:00:01」と等しい場合、次のコード:

echo date("Y/n/j", strtotime('-1 month', strtotime($event["EndDate"]));

出力:2013/10/1の代わりに2013/09/30.

質問:どうしたらいけないのかわかりましたが、30 日だけでなく、正確に 1 か月分を PHP で減算 (または加算) する別のより正確な方法はありますか?

4

2 に答える 2

1

あなたは言う:-

確実で正確な日付操作が必要な場合は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);
}
于 2013-05-08T18:15:43.437 に答える