2012-10-29 11 views
5

Klasa DateTime w PHP (5.3+) działa świetnie, o ile pierwszy dzień tygodnia w Twoim kraju to niedziela. W Holandii pierwszym dniem tygodnia jest poniedziałek, co czyni klasę bezużyteczną do budowania kalendarza z widokiem tygodniowym i obliczeniami.PHP DateTime() klasy, zmiana pierwszego dnia tygodnia na poniedziałek

Nie mogę znaleźć odpowiedzi na Stackoverflow lub resztę Internetu na temat tego, jak ustawić DateTime tak, jakby pierwszy dzień tygodnia przypada na poniedziałek.

Znalazłem ten fragment na Stackoverflow, ale nie rozwiązuje on wszystkich problemów, które można wpakować w kłopoty i nie jest to eleganckie rozwiązanie.

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

Czy istnieje sposób na zmianę tego lub zakresu DateTime? Nie mogę sobie wyobrazić, że to nie jest miejsce, ponieważ większość Europy zaczyna się od poniedziałku.

Dodano: Opublikowanie pełnego kalendarza i kodu funkcji nie spowoduje, że sprawy staną się bardziej przejrzyste. Ale tutaj jest jedna linia na przykład. Często muszę sprawdzić, co oznacza pierwszy dzień tygodnia, lub obliczyć od pierwszego dnia tygodnia do innej daty i godziny w tym tygodniu. Mój kod jest coraz pełny z nich:

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

uzyskać również niepożądany rezultat próbuje uzyskać pierwszy pełny tydzień miesiąca lub roku. Ponieważ mój obiekt $ date nie zawsze zawiera tę samą datę, muszę to sprawdzać w ten sposób, co sprawia, że ​​kod jest trudny do odczytania. Mając o wiele więcej programów do zrobienia w tym kalendarzu, nie mogę przewidzieć, gdzie znowu będzie się pojawiać.

EDYCJA Mimo to istnieją pewne niespójności. Z jakiegoś dziwnego powodu DateTime robi się to następny jedno prawo:

$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 

Ale myślę, że mogę sprawić, że pytanie jaśniej: Czy DateTime() Klasa być stosowany w poniedziałek jako pierwszy dzień tygodnia. Jeśli nie, czy klasa może zostać rozszerzona na poniedziałek jako pierwszy dzień tygodnia.

UPDATE: Ok, myślę, że jestem coraz gdzieś ... Nie jestem pro na kodowanie classes..but to wydaje się działać za kilka tygodni. Ale nadal potrzebuje zasad na pierwszy dzień, drugi dzień ... a także na sam dzień na niedzielę. Nie sądzę, że to jest niezawodny. Byłbym wdzięczny za każdą pomoc, aby to naprawić.

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

Na czym dokładnie polega problem? – Jon

+2

Brzmi jak problem XY. Fakt, że niedziela jest mapowana na 0, nie powinien powstrzymywać cię przed użyciem innej techniki do określenia początku tygodni jak każdego innego dnia. – cmbuckley

+0

Twoje pytanie jest abstrakcyjne. Podaj kod, którego używasz do tworzenia kalendarza. Na razie nie ma odpowiedzi na twoje pytanie. – BeRocket

Odpowiedz

5

Znalazłem, że to działa, ale są pewne niespójności w klasie DateTime PHP.

Jeśli datą odjazdu jest niedziela, poprzedni poniedziałek nie jest uważany za ten sam tydzień (ustalony przez tę klasę). Ale odchodząc od poniedziałku, najbliższa niedziela jest uważana za ten sam tydzień. Jeśli naprawią to w przyszłości, ta klasa będzie wymagać pewnych dodatków.

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

Nie ma nic, aby zatrzymać ręcznie modyfikując datę, aby uzyskać „pierwszy” dzień tygodnia, w zależności od definicji „pierwszy”. Na przykład:

$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" 

Wskazówki jak zmiany wyjściowych, jak zmieniać $firstDayOfWeek; jeśli zostałby zmieniony na 4 powyżej (czwartek), wówczas byłby to "pierwszy" dzień.

Edytuj: jest to raczej podstawowy przykład. Prawidłowy sposób to zrobić, korzystając z ustawień regionalnych użytkownika/systemu, aby dać ci "pierwszy" dzień i obliczyć stamtąd. Aby uzyskać więcej informacji, patrz this question.

+0

Dzięki cbuckley, czy to oznacza, że ​​sama klasa DateTime nie może być ustawiona na poniedziałek jako pierwszy dzień roboczy? – Edward

+0

Dla wszystkiego, co inteligentniejsze, właściwym sposobem na to byłoby użycie ustawień narodowych. Dodałem aktualizację tego efektu. – cmbuckley

+0

cbuckly, nie sądzę, aby aktualizacja locale przeszła. Próbuję teraz napisać klasę opartą na twoim przykładzie, który przechwyci wszystko, co będzie wyglądać jak "następny tydzień", "w tym tygodniu", "ostatni tydzień" i zmieni ją. Dunno, jeśli tylko tracę czas ... – Edward

0

ja też jestem zagubiony w czym jest problem, bo DateTimema mieć pojęcie tydzień, począwszy od poniedziałku: the N format daje dni tygodnia, licząc od poniedziałku do niedzieli, od poniedziałku wynosi 1 i niedzielę jest 7. Ponadto, format W, jedyny sposób, aby uzyskać numer tygodnia, również rozpoczyna się w poniedziałek. (Wydaje mi się, że pamiętam, że liczby w holenderskim tygodniu nie są dokładnie takie same jak numery w tygodniu ISO, ale to inna historia). Więc jakiej dokładnie funkcji brakuje?

Edytuj Tak więc problemem jest (tylko?), Że relative datetime formats, na przykład "Poniedziałek w tym tygodniu", daje zły wynik, gdy datą odniesienia jest niedziela. Od dokumentów brzmi jak DateTime po prostu odradza się do strtotime, który ma być zależny od ustawień regionalnych. Tak więc jeśli masz ustawione ustawienia regionalne poprawnie i to nie działa, brzmi jak błąd (o ile to jest warte).

+1

Spróbuj tego: $ test = new DateTime ('2012-11-04'); echo $ test-> modify ("Poniedziałek w tym tygodniu") -> format ("Y-m-d"); // 2012-11-05 // Spodziewam się uzyskać 2012-10-29 – Edward

+1

Widzę; więc specyfikacja angielska dotycząca przesunięć względnych nie występuje w wariancie od poniedziałku do pierwszego. – alexis

+0

Dokładnie .... jest do bani dla wszystkich krajów, które rozważają poniedziałek pierwszego dnia tygodnia. I właśnie odkryłem, że rozszerzenie PHP DateTime zostało napisane przez holenderskiego faceta .... #WayToGoDerickRethans – Edward

Powiązane problemy