+48 695 115 215 biuro@webkom.pl

Programując w PHP czasami natykamy się na problemy operując na datach w języku polskim. Chcąc uzyskać nazwy miesięcy i/lub dni tygodnia nie zawsze możemy polegać na wbudowanych w PHP funkcjach. Tym bardziej jeśli w grę wchodzi ich odmiana. Bardzo łatwo możemy sobie z tym poradzić. Wystarczy dopisać swoją funkcję.
Konfiguracja wbudowanych funkcji

Do dyspozycji mamy funkcje date() oraz strftime(). Pierwsza z nich niestety nie zwraca daty z lokalnymi nazwami. Za to strftime() jest możliwe do ustawienia.

Co należy ustawić, aby domyślnie PHP korzystał z lokalizacji polskiej?

$arrLocales = array('pl_PL', 'pl','Polish_Poland.28592');
setlocale( LC_ALL, $arrLocales );

Funkcja setlocale() ustawia opcje regionalne. Za pierwszy parametr może przyjmować:

LC_ALL dla wszystkich poniżej
LC_COLLATE ciąg dla porównania, patrz strcoll ()
LC_CTYPE na charakter i klasyfikację konwersji, na przykład strtoupper ()
LC_MONETARY dla localeconv ()
LC_NUMERIC dla separator (Patrz także localeconv ())
LC_TIME do formatowania daty i czasu z strftime ()
LC_MESSAGES dla systemu odpowiedzi (dostępna jeśli PHP zostało skompilowane z libintl)

Dzięki temu zabiegowi ustawiliśmy język polski jako domyślny. Jednak problemy zaczynają się w przypadku, gdy zechcemy użyć kodowania innego niż ISO-8859-2 (które jest ustawiane poprzez Polish_Poland.28592′). Musimy niestety przekonwertować zwracane dane z ISO-8859-2 na UTF-8. Zrobimy to za pomocą prostej funkcji:

function strftimeV($format,$timestamp){
return iconv("ISO-8859-2","UTF-8",ucfirst(strftime($format,$timestamp)));
}

Użycie:

<!--?php echo strftimeV('%A %d %B %Y',strtotime('2009-09-02')); ?-->

Daje w wyniku Środa 02 wrzesień 2009, co jest troszeczkę nie po polsku.
Utworzenie własnej funkcji obsługi formatu daty

Pozostaje nam stworzenie własnej funkcji, która odpowiednio zamieni format.
Na początku skryptu ustawiamy domyślną strefę czasową używaną przez funkcje date/time:

date_default_timezone_set('Europe/Warsaw');

Następnie tworzymy naszą funkcję, która odpowiednio przekonwertuje standardowy format daty dla funkcji date(). Najlepiej aby była zgodna, tak aby w przypadku zamiany jej na zwykłą date() nie trzeba było przepisywać formatów. Niestety w języku polskim mamy odmianę, co skutecznie uniemożliwia nam pełną zgodność. Problem pojawia się właściwie tylko w przypadku miesięcy, dni tygodnia zwykle używa się w formie podstawowej, natomiast miesiące już różnie. Raz jest styczeń, innym razem stycznia. Aby móc skorzystać z kilku form będziemy musieli rozszerzyć format daty o własne znaczniki.
Interesujące nas znaczniki formatu daty to l (małe L) oraz F. Dodamy własne oznaczenie f, Które nie występuje na liście parametrów formatu date. Utwórzmy zatem własną funkcję dateV() – czyli funkcję dateVokiel() 😉

function dateV($format,$timestamp=null){
$to_convert = array(
'l'=>array('dat'=>'N','str'=>array('Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota','Niedziela')),
'F'=>array('dat'=>'n','str'=>array('styczeń','luty','marzec','kwiecień','maj','czerwiec','lipiec','sierpień','wrzesień','październik','listopad','grudzień')),
'f'=>array('dat'=>'n','str'=>array('stycznia','lutego','marca','kwietnia','maja','czerwca','lipca','sierpnia','września','października','listopada','grudnia'))
);
if ($pieces = preg_split('#[:/.-, ]#', $format)){
if ($timestamp === null) { $timestamp = time(); }
foreach ($pieces as $datepart){
if (array_key_exists($datepart,$to_convert)){
$replace[] = $to_convert[$datepart]['str'][(date($to_convert[$datepart]['dat'],$timestamp)-1)];
}else{
$replace[] = date($datepart,$timestamp);
}
}
$result = strtr($format,array_combine($pieces,$replace));
return $result;
}
}

Edit: Listing został zaktualizowany ze względu na wykryte błędy, szczegóły w komentarzach
Krótkie omówienie funkcji dla wywołania:

echo dateV('l j f Y',strtotime('2009-09-02'));
// Środa 2 września 2009

W linii 2 definiujemy tablicę, która zawiera polskie odpowiedniki dni tygodnia oraz nazw miesięcy w odpowiedniej formie. Tablica zawiera indeksy odpowiadające standardowym znacznikom funkcji date, które zamienimy na nasze. Wewnątrz tablicy pola dat mają za zadanie wskazanie znacznika dla funkcji date, który zostanie użyty jako index dla tablicy str. Taki zabieg jest konieczny, gdyż musimy utworzyć znaczniki liczbowe danego dnia tygodnia bądź miesiąca, aby móc wyciągnąć ich polskie nazwy.
Linia 7 rozbija nam podany format na pojedyncze znaczniki.
W linii 8 tworzymy aktualny znacznik czasu, jeśli nie został podany.

Linie 10-16 są kluczowe dla zrozumienia sposobu zamiany podanego formatu aby zwracał poprawne dane.
W linii 10 sprawdzamy, czy aktualnie wybrany znacznik formatu występuje w naszej tablicy kwalifikującej go do zmiany.
Jeśli tak, to w linii 11 do tablicy $replace dodajemy kolejny wiersz zawierający już utworzony element daty. Sposób jego utworzenia może wydawać się skomplikowany, jednak nie jest 😉
Rozbijmy wpis na części składowe. W pierwszej iteracji $datepart==’l’

$replace[] = // dopisanie wiersza tablicy
$to_convert[$datepart]['str'][( // odwołanie $to_convert['l']['str'][] czyli tablica dni tygodnia o indeksie:
date( // data w formacie:
$to_convert[$datepart]['dat'], //tablica dni tygodnia - format N (czyli numery dni od 1 (dla Poniedziałku) aż do 7 (dla Niedzieli))
$timestamp // znacznik czasu
)-1) // pomniejszony o 1 (indexy w tablicy zaczynają się od 0 )
];

Natomiast jeśli $datepart nie zawiera się w tablicy $to_convert wykona się linia 13.
W linii 13 do tablicy $replace dodawane jest standardowe wywołanie funkcji date()

Na koniec po przejściu przez wszystkie elementy formatu, w linii 16, dokonuje się zamiana każdego z elementów formatu na odpowiadający mu, utworzony w pętli wcześniej, wynik działania funkcji date.

No i to wszystko 😉 Wystarczy teraz dodać własne znaczniki i odpowiadające im dane, aby móc cieszyć się poprawnymi, polskimi nazwami 😉

http://blog.vokiel.com/php-date-polskie-nazwy-dni-i-miesiecy-funkcje-date-strftime