2016-06-01 10 views
1

Ich habe das folgende Beispiel von mir die DateInterval von DateTimeImmutable SubtrahierenPHP Datetime-sub führt zu unerwarteten Ergebnissen

$dateA = new DateTimeImmutable('2016-06-30'); 
    $dateB = new DateTimeImmutable('2016-05-31'); 
    $dateInterval = new DateInterval('P3M'); 
    // print 2016-03-30 as expected 
    echo $dateA->sub($dateInterval)->format('Y-m-d'); 
    // print 2016-03-02 which i would expect 2016-02-29 
    echo $dateB->sub($dateInterval)->format('Y-m-d'); 

Wenn ich die Zeit zu ‚P8M‘ gesetzt funktioniert es wie erwartet. Wie kommt es, dosent funktioniert für Februar?

+0

Es, weil 30. Februar 2016-03-02 werden. Aber wenn Sie das Datum auf 1-28 setzen, funktioniert es wie erwartet – splash58

+0

Warum ist das immer "unerwartet"? –

+0

@MarkBaker wahrscheinlich, während das Datum auf den letzten Tag eines Monats, jemand möchte auf diese Weise den letzten Tag eines anderen Monats bekommen – splash58

Antwort

2

Ok, es ist wirklich einfach (irgendwie). Jedes 'Monat' Intervall wird zum vorherigen (oder X Nummer des vorherigen) Monat entsprechenden Tag ausgewertet. Wenn es im aktuellen Monat mehr Tage gibt, als der Monat, in dem der Monat gelandet wird, fließt der Überschuss in den Folgemonat über.

Also, wenn Sie ein Datum haben, das 31. Mai 2016 und soll 3 Monate Intervalle subtrahieren, wird sie:

  • Zurück 3 Monaten (in der Liste der Monate, denken Sie nicht Tage noch), resultierend in 'Februar'
  • Dann schauen Sie für den 31. Februar. Dies ist nicht vorhanden, also bluten Sie zum nächsten Monat 2 Tage (2016 Februar hat 29 Tage, also 2 zusätzliche Tage)
  • Viola! 2. März.

Go vorwärts können, sagen, Sie sind in 31. Mai 2016 und wollen 1 Monat

  • Go vorwärts 1 Monat bis Juni hinzuzufügen.
  • Suchen Sie nach 31. Juni, nein, 1 Extratag, bluten Sie bis Juli.
  • Wie erwartet, ist der 1. Juli die Antwort.

Die Lektion in dieser: saugt Addition und Subtraktion Monat Intervalle, ist verwirrend und kann zu nicht-intuitive Ergebnissen führen, wenn Sie Ihre Monat Berechnung rosetta mit Ihnen haben.

0

Erklärung vom PHP Docs

Hinweis: Relative Monatswerte basieren auf der Länge der Monate berechnet, dass sie durchlaufen. Ein Beispiel wäre "+2 Monate 2011-11-30", was "2012-01-30" ergeben würde. Dies liegt daran, dass der November 30 Tage lang ist und der Dezember 31 Tage lang ist, was insgesamt 61 Tage ergibt.

+0

Danke, ich hatte keine Ahnung, dass es eine Seite im Relativen Format gab. Ich finde die Monatsangabe immer noch etwas verwirrend, kannst du meine Antwort anschauen und sehen, ob sie intuitiver (oder inkorrekter) ist? – Ray