2016-07-09 7 views
1

Ich habe DateTime Diff (in php) verwendet, um verschiedene Einstellungen für Datenpaare zu erhalten - zwei formatierte Daten zur Anzeige, eine Abweichung vom Datum bis jetzt (zB "Anfangsdatum war 3 Monate vor 2 Tagen") und a Länge zwischen den beiden Daten ("Länge ist 2 Monate 3 Tage").php DateTime diff - beide Daten im Bereich?

Das Problem ist, dass DateTime Diff einen der Tage ignoriert, also wenn der Start gestern ist und das Ende morgen ist, gibt es 2 Tage, während ich 3 möchte, da beide Daten in der Länge enthalten sein sollten. Wenn es nur Tage wären, könnte ich einfach 1 zu dem Ergebnis hinzufügen, aber ich wollte die Jahre/Monate/Tage-Ergebnisse von dem Diff verwenden und diese werden am Konstrukt bestimmt.

Der einzige Weg, den ich gefunden habe, um die gewünschten Ergebnisse zu erhalten, ist eine DateTime für Start und Ende zu erstellen (um die formatierten Daten und die Unterschiede zu erhalten). Dann nehmen Sie das Ende DateTime, fügen Sie 1 Tag hinzu, dann berechnen Sie die Länge.

Es ist ein wenig klobig, aber es scheint keine Möglichkeit zu geben, DateTime Diff mitzuteilen, dass sowohl Start- als auch Enddatum im Ergebnis enthalten sein sollen.

+0

Ab jetzt nicht. Dasselbe gilt für DatePeriod. Es ist sicherlich ein Manko, aber wie Sie bereits wissen, kann es überwunden werden. –

Antwort

1

DateTime kapselt einen bestimmten Zeitpunkt ein. "gestern" ist kein Moment, aber ein Zeitbereich. Das gleiche für "morgen".

DateTime::diff() ignoriert nichts; es gibt Ihnen nur den genauen Unterschied (in Tag, Stunden, Minuten a.s.o.) zwischen zwei Zeitpunkten.

Wenn Sie den Diff zwischen "morgen" und "gestern" als "3 Tage" erhalten möchten, können Sie die erste Sekunde von "gestern" von (eine Sekunde nach der letzten Sekunde von "morgen") subtrahieren.

So:

// Always set the timezone of your DateTime objects to avoid troubles 
$tz = new DateTimeZone('Europe/Bucharest'); 
// Some random time yesterday 
$date1 = new DateTime('2016-07-08 21:30:15', $tz); 
// Other random time tomorrow 
$date2 = new DateTime('2016-07-10 12:34:56', $tz); 

// Don't mess with $date1 and $date2; 
// clone them and do whatever you want with the clones 
$yesterday = clone $date1; 
$yesterday->setTime(0, 0, 0);   // first second of yesterday (the midnight) 
$tomorrow = clone $date2; 
$tomorrow->setTime(23, 59, 59)    // last second of tomorrow 
     ->add(new DateInterval('PT1S')); // one second 

// Get the difference; it is the number of days between and including $date1 and $date2 
$diff = $tomorrow->diff($yesterday); 

printf("There are %d days between %s and %s (including the start and end date).\n", 
    $diff->days, $date1->format('Y-m-d'), $date2->format('Y-m-d') 
); 
+0

Anstatt zu klonen, könnten Sie stattdessen DateTimeImmutable verwenden. – vascowhite

+0

Wenn es zum Ändern kommt, erstellt der Teil mit "mach was du willst" mit "DateTimeImmutable" stillschweigend neue Objekte. Dennoch ist die Verwendung von "DateTimeImmutable", wann immer es möglich ist, ein guter Rat, insbesondere wenn die Datetime-Objekte Funktionsargumente sind. – axiac

+1

Ja, ich halte DateTime-Objekte für Value-Objekte, daher bevorzuge ich sie unveränderlich. Ich bin mit veränderlichen DateTime-Objekten umgegangen, die ein paar Mal seltsame Bugs erzeugt haben, bis ich mehr Erfahrung damit hatte :) – vascowhite