Wir können diese Anforderungen in zwei verschiedene Dinge vereinfachen.
- Definieren Sie einen bestimmten Monat in 2 Perioden. Der erste Tag ist der 1. Tag des Monats bis zum 15. Tag des Monats. Der zweite, der 16. Tag des Monats bis zum letzten Tag des Monats.
- Geben Sie für ein Datum die letzten 3 Perioden nach der aktuellen Periode ab diesem Datum an.
Schritt 1
Der erste Teil ist einfach.
$date = new DateTimeImmutable("Sep 22, 2016");
// Period 1 (from 1st day of month to 15th)
$p1Start = $date->modify("first day of this month");
$p1End = $p1Start->add(new DateInterval("P14D"));
// Period 2 (from 16th day of month to last day of month)
$p2Start = $p1End->add(new DateInterval("P1D"));
$p2End = $p2Start->modify("last day of this month");
echo "Period 1 Starts On: {$p1Start->format('M j, Y')}\n";
echo "Period 1 Ends On: {$p1End->format('M j, Y')}\n\n";
echo "Period 2 Starts On: {$p2Start->format('M j, Y')}\n";
echo "Period 2 Ends On: {$p2End->format('M j, Y')}\n";
Output Sie von diesem erhalten ist wie erwartet:
Period 1 Starts On: Sep 1, 2016
Period 1 Ends On: Sep 15, 2016
Period 2 Starts On: Sep 16, 2016
Period 2 Ends On: Sep 30, 2016
Jetzt müssen Sie nur all dies in einer Funktion gesetzt und die gleiche Lösung wiederverwenden zu 2.
function getPeriods($dateString) {
$date = new DateTimeImmutable($dateString);
// Period 1 (from 1st day of month to 15th)
$p1Start = $date->modify("first day of this month");
$p1End = $p1Start->add(new DateInterval("P14D"));
// Period 2 (from 16th day of month to last day of month)
$p2Start = $p1End->add(new DateInterval("P1D"));
$p2End = $p2Start->modify("last day of this month");
return [
"period1" => ["start" => $p1Start, "end" => $p1End],
"period2" => ["start" => $p2Start, "end" => $p2End],
];
}
Schritt zu erhalten
Also sagen wir, Sie beginnen mit einem Datum wie 12. September 2016. Sie können herausfinden, in welchem Zeitraum dieses Datum fällt, indem Sie den Rückgabewert von dieser Funktion wie folgt überprüfen.
$date = "Sep 12, 2016";
$periods = getPeriods($date);
if ($date >= $periods["period1"]["start"] && $date <= $periods["period1"]["end"]) {
// It's in Period1
} else {
// It's in Period2
}
Schritt 2
Lassen Sie uns jetzt nur diese Funktion ein wenig ändern, so zu vereinfachen, dass die Lösung auf erweitert werden kann. So nennen wir es getPeriod
anstelle von getPeriods
und haben es nur eine Periode von einem bestimmten Datum zurückgeben.
function getPeriod($dateString) {
$periods = [];
$date = new DateTimeImmutable($dateString);
// Period 1 (from 1st day of month to 15th)
$p1Start = $date->modify("first day of this month");
$p1End = $p1Start->add(new DateInterval("P14D"));
// Period 2 (from 16th day of month to last day of month)
$p2Start = $p1End->add(new DateInterval("P1D"));
$p2End = $p2Start->modify("last day of this month");
// Figure out which period the given date belongs in
if ($date >= $p1Start && $date <= $p1End) {
$period = ["start" => $p1Start, "end" => $p1End];
} else {
$period = ["start" => $p2Start, "end" => $p2End];
}
return $period;
}
So den vorherigen Zeitraum ab diesem Zeitpunkt bekommen wir nur einfach das start
Datum der aktuellen Periode, von dieser Funktion zurück, subtrahieren 1 Tag ab, dass, und das neue Datum zurückschicken zu die Funktion erneut, um die vorherige Periode zu erhalten.
Ebenso erhalten die nächste Zeit nehmen Sie nur das end
Datum, 1 Tag hinzu, und das zurück an die Funktion zu senden.
Endergebnis
Hier ist ein Beispiel.
// We want up to 3 periods previous to this given date's period.
$date = "Sep 12, 2016";
$periods = [];
$currentPeriod = getPeriod($date);
for ($i = 0; $i < 3; $i++) {
$currentPeriod = $periods[] = getPeriod($currentPeriod["start"]->sub(new DateInterval("P1D"))->format("c"));
}
// Print out the period dates
$i = 1;
foreach($periods as $period) {
echo "Period $i: {$period['start']->format('M j, Y')} - {$period['end']->format('M j, Y')}\n";
$i++;
}
Output ist das, was man erwarten würde ...
Period 1: Aug 16, 2016 - Aug 31, 2016
Period 2: Aug 1, 2016 - Aug 15, 2016
Period 3: Jul 16, 2016 - Jul 31, 2016
Ihre Anforderungen tatsächlich nicht aufaddieren. Sie betrachten den 1.-15. August als einen Zeitraum von 15 Tagen, aber Sie betrachten auch den 16.-31. August als einen Zeitraum von 15 Tagen, was keinen Sinn ergibt, da der August 31 Tage hat. Das eine ist eine exklusive Auswahl und das andere ist ein integrativer Bereich, was sie ** nicht 15 Tage ** macht. Vielleicht möchten Sie * den * Monat stattdessen in 2 Teile aufteilen? Zum Beispiel, wie bekommt man 2 15 Tage im Februar? – Sherif
Ich nehme an, du hast Recht, ich möchte nur einen Monat in 2 Teile brechen. Der erste Teil ist immer der 1. bis zum 15. eines Monats und der zweite Teil ist der 16. bis zum letzten Tag eines Monats. – clueless