2012-10-29 9 views
5

Die DateTime-Klasse in PHP (5.3+) funktioniert einfach großartig, solange der erste Tag der Woche in Ihrem Land Sonntag ist. In den Niederlanden ist der erste Tag der Woche Montag und das macht die Klasse einfach nutzlos, um einen Kalender mit Wochenansicht und Berechnungen zu erstellen.PHP DateTime() -Klasse, ändern Sie den ersten Tag der Woche auf Montag

Ich kann nicht scheinen, eine Antwort auf Stackoverflow oder dem Rest des Internets zu finden, wie man DateTime so verhält, als wäre der erste Wochentag Montag.

Ich fand dieses Stück auf Stackoverflow, aber es repariert nicht alle Wege, die Sie in Schwierigkeiten geraten können, und es ist keine elegante Lösung.

$dateTime = new DateTime('2012-05-14'); 
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week'); 

Gibt es eine Möglichkeit, dieses oder Extent DateTime zu ändern? Ich kann mir nicht vorstellen, dass es nicht eine Einstellung ist, da die meisten von Europa ihre Wochen am Montag beginnen.

Hinzugefügt: Das Posten des vollen Kalender- und Funktionscodes macht die Dinge nicht klarer. Aber hier ist zum Beispiel eine Zeile. Ich muss oft überprüfen, was der erste Tag der Woche ist oder berechnen vom ersten Tag der Woche zu einem anderen Datum und Uhrzeit in dieser Woche. Mein Code ist immer voll von diesen:

$startOfWeek = $date->modify(('Sunday' == $date->format('l')) ? 'Monday last week' : 'Monday this week')->modify('+3 hours')->format(DATETIME); 

ich auch ein unerwünschtes Ergebnis erhalten versuchen, die erste volle Woche des Monats oder des Jahres zu erhalten. Da mein $ date-Objekt nicht immer das gleiche Datum enthält, muss ich es auf diese Weise überprüfen, wodurch der Code schwer zu lesen ist. Da ich in diesem Kalender noch viel mehr programmieren kann, kann ich nicht vorhersehen, wo es wieder hinfliegen wird.

EDIT Es gibt jedoch einige Inkonsistenzen. Aus irgendeinem seltsamen Grund bekommt Datetime diese nächste rechts:

$test = new DateTime('2012-10-29'); // Monday 
echo $test->modify('Sunday this week')->format('Y-m-d'); // 2012-11-04 

// But... 

$test = new DateTime('2012-11-04'); // Sunday 
echo $test->modify('Monday this week')->format('Y-m-d'); // 2012-11-05 instead of 2012-10-29 

Aber ich glaube, ich kann die Frage klarer machen: Kann die Datetime() der Klasse mit Montag als erster Tag der Woche verwendet werden. Wenn nicht, kann die Klasse auf Montag als ersten Tag der Woche erweitert werden.

UPDATE: Ok, ich glaube, ich bin immer irgendwo ... Ich bin kein Profi bei Codierung classes..but dies für die Wochen zu arbeiten scheint. Aber es braucht noch Regeln für den ersten Tag, den zweiten Tag ... und auch für den Namen Sonntag. Ich denke nicht, dass das narrensicher ist. Ich würde jede Hilfe schätzen, um es zu beheben.

class EuroDateTime extends DateTime { 

// Fields 
private $weekModifiers = array (
    'this week', 
    'next week', 
    'previous week', 
    'last week' 
); 

// Override "modify()" 
public function modify($string) { 

    // Search pattern 
    $pattern = '/'.implode('|', $this->weekModifiers).'/'; 

    // Change the modifier string if needed 
    if ($this->format('N') == 7) { // It's Sunday 
     $matches = array(); 
     if (preg_match($pattern, $string, $matches)) { 
      $string = str_replace($matches[0], '-7 days '.$matches[0], $string); 
     } 
    } 
    return parent::modify($string); 

} 

} 
// This works 
$test = new EuroDateTime('2012-11-04'); 
echo $test->modify('Monday this week')->format('Y-m-d'); 
// And I can still concatenate calls like the DateTime class was intended 
echo $test->modify('Monday this week')->modify('+3 days')->format('Y-m-d'); 
+2

Was ist das Problem, dem Sie genau gegenüberstehen? – Jon

+2

Klingt wie ein XY-Problem. Die Tatsache, dass Sonntag auf 0 abgebildet ist, sollte Sie nicht davon abhalten, eine andere Technik zu verwenden, um den Beginn der Wochen wie jeden anderen Tag zu bestimmen. – cmbuckley

+0

Ihre Frage ist abstrakt. Geben Sie den Code an, mit dem Sie den Kalender erstellen. Für jetzt gibt es keine Antwort auf Ihre Frage – BeRocket

Antwort

5

Ich fand, dass dies funktioniert, dennoch gibt es einige Inkonsistenzen in der DateTime-Klasse von PHP.

Wenn der Abreisetag ein Sonntag ist, wird der vorherige Montag nicht als dieselbe Woche betrachtet (festgelegt durch diese Klasse). Aber ab einem Montag wird der nächste Sonntag als dieselbe Woche betrachtet. Wenn sie das in der Zukunft beheben, wird diese Klasse einige Ergänzungen benötigen.

class EuroDateTime extends DateTime { 

// Override "modify()" 
public function modify($string) { 

    // Change the modifier string if needed 
    if ($this->format('N') == 7) { // It's Sunday and we're calculating a day using relative weeks 
     $matches = array(); 
     $pattern = '/this week|next week|previous week|last week/i'; 
     if (preg_match($pattern, $string, $matches)) { 
      $string = str_replace($matches[0], '-7 days '.$matches[0], $string); 
     } 
    } 
    return parent::modify($string); 

} 

} 
2

Es gibt nichts manuell zu stoppen ein Datum Modifizieren den „ersten“ Tag der Woche zu bekommen, je nach Definition von „first“. Zum Beispiel:

$firstDayOfWeek = 1; // Monday 
$dateTime = new DateTime('2012-05-16'); // Wednesday 

// calculate how many days to remove to get back to the "first" day 
$difference = ($firstDayOfWeek - $dateTime->format('N')); 
if ($difference > 0) { $difference -= 7; } 
$dateTime->modify("$difference days"); 

var_dump($dateTime->format('r')); // "Mon, 14 May 2012 00:00:00 +0000" 

Beachten Sie, wie die Ausgangs Änderungen, wie Sie $firstDayOfWeek variieren; Wenn es oben (Donnerstag) in 4 geändert wurde, würde es Thu, 10 May 2012 als den "ersten" Tag betrachten.

Bearbeiten: Dies ist ein ziemlich einfaches Beispiel. Der richtige Weg dazu besteht darin, das Gebietsschema des Benutzers/Systems zu verwenden, um Ihnen den "ersten" Tag zu geben und von dort zu berechnen. Weitere Informationen finden Sie unter this question.

+0

Danke cbuckley, bedeutet dies, dass die DateTime-Klasse selbst nicht so eingestellt werden kann, dass sie Montag als ersten Wochentag verwendet? – Edward

+0

Für etwas schlauer wäre die Verwendung des Gebietsschemas der richtige Weg. Ich habe ein Update zu diesem Zweck hinzugefügt. – cmbuckley

+0

cuckuckly, ich glaube nicht, dass das Gebietsschema-Update durchkam. Ich versuche jetzt einen Kurs zu schreiben, der auf deinem Beispiel basiert und alles abfangen wird, was wie "nächste Woche", "diese Woche", "letzte Woche" aussieht und es ändert. Weiß nicht, wenn ich nur meine Zeit verschwende .. – Edward

0

ich zu verwirrt bin über das, was das Problem ist, weil DateTimehat hat eine Vorstellung von der Woche ab Montag: Die N format gibt Ihnen die Tage der Woche von Montag bis Sonntag zu zählen, mit Montag, 1. und Sonntag sein 7. Außerdem startet das W Format, die einzige Möglichkeit, eine Wochennummer zu erhalten, auch die Woche am Montag. (Ich glaube mich zu erinnern, dass die niederländischen Wochennummern nicht genau wie ISO-Wochennummern sind, aber das ist eine andere Geschichte). Welche Eigenschaft vermisst du genau?

Bearbeiten Also das Problem ist (nur?), Dass die relative datetime formats, wie "Montag diese Woche" das falsche Ergebnis geben, wenn das Referenzdatum ein Sonntag ist. Aus der Dokumentation klingt es wie DateTime nur auf strtotime, die locale-abhängig sein soll. Also wenn Sie haben Ihr Gebietsschema richtig eingestellt und das funktioniert nicht, es klingt wie ein Bug (für das, was das wert ist).

+1

Probieren Sie dies aus: $ test = new DateTime ('2012-11-04'); echo $ test-> modify ('Montag diese Woche') -> format ('Y-m-d'); // 2012-11-05 // Ich erwarte 2012-10-29 – Edward

+1

Ich verstehe; daher kommen die englischen Spezifikationen für relative Offsets nicht in einer Montag-1-Variante vor. – alexis

+0

Genau .... ist schlecht für die Länder, die Montag den ersten Tag der Woche betrachten. Und ich habe gerade herausgefunden, dass die PHP DateTime-Erweiterung von einem Holländer geschrieben wurde ... #WayToGoDerickRethans – Edward

Verwandte Themen