PHP/Data i czas

Z Wikibooks, biblioteki wolnych podręczników.
< PHP
Poprzedni rozdział: System plików
Następny rozdział: Ćwiczenia

Data i czas[edytuj]

Przeglądając wiele dynamicznych stron internetowych, można napotkać multum różnych przykładów użycia daty i czasu. W księgach gości i forach dyskusyjnych zapisywana jest godzina wysłania wiadomości. Większość liczników dziennych opiera się na tych funkcjach. W niektórych serwisach można zmieniać strefy czasowe, a wszystkie najskuteczniejsze zabezpieczenia przed spamem są bazowane na limitach czasowych. Ten rozdział będzie poświęcony właśnie funkcjom służącym do zadań związanych z operowaniem obecnym czasem.

Formatowanie daty[edytuj]

Podstawową funkcją do zwracania obecnej daty jest date(), która przyjmuje jako parametr wartość tekstową. I tutaj pojawia się pierwsza zagadka, wielu na początku zastanawiałoby się czemu akurat wartość tekstowa - tekst nie ma wiele wspólnego z datą.

I tutaj kłania się PHP, pomagając wielu programistom. Łańcuch ten, mówi jak należy przeformatować datę - nie trzeba pisać własnych funkcji. W tym parametrze funkcji można umieszczać własne znaczniki, mówiące jakie informacje należy wyświetlić:

<?php
echo date('d-m-Y');
?>

Powyższy kod zwróci wartość podobną do 17-04-2004. Spróbuj usunąć myślniki pomiędzy literami. Co zauważyłeś?

Pamiętaj też, iż nie należy sugerować się nazwą funkcji. Funkcja date() umożliwia również wyświetlenie godziny, strefy czasowej, a nawet informacji, czy czas jest letni:

<?php
echo date('H:i:s'); // Godzina, np. 09:39:21
echo date('e / Z'); // Różnica dla strefy czasowej i identyfikator dla niej (np. Europe/Berlin / 3600)
if (date('I')=="1"){ echo "Czas letni"; }else{ echo "Czas zimowy"; }
// date('I') zwraca 1 gdy czas jest letni - można to wykorzystać
?>

Problemy z formatowaniem[edytuj]

Przyjmijmy, że na końcu daty chcesz dodać wyraz "rok". Wiele osób korzystając z możliwości bezpośredniego formatowania daty zrobiłoby tak:

echo date('d-m-Y rok');

Wynik tego kodu byłby podobny do przykładu poniżej:

 06-03-2010 Sat, 06 Mar 2010 21:17:44 +01002010k

To co widzimy, jest zupełnie inny wynik, niż był oczekiwany. Dlaczego? Duża część liter w pierwszym parametrze funkcji date() jest używana do wypisywania danych. PHP widząc fragment:

 rok

Zamienił litery na dane i uzyskano:

 Sat, 06 Mar 2010 21:17:44 +01002010k

Jak to ominąć? Umieszczając tekst poza funkcją, np.:

echo date('d-m-Y ')."rok";

Jest jeszcze jedna metoda nie zapisana w dokumentacji tego języka, ale poprawnie działająca. Polega ona na poprzedzeniu liter backslashem. Trzeba pamiętać, że jeżeli format daty zostałby podany pomiędzy podwójnymi cudzysłowami, to przykładową literę "r" należałoby poprzedzić podwójnym ukośnikiem ( zrobiłby się wówczas z nich tylko jeden ). W przeciwnym wypadku zrobiłaby się z niej tabulacja, a nie litera.

echo date('d-m-Y \r\o\k');

Ten sposób jest bardziej przenośny oraz można go umieścić w jednej stałej i odwoływać się do niego w innych skryptach. W poprzednim sposobie nie ma takiego komfortu.

Lista znaczników[edytuj]

d - Dzień miesiąca, 2 cyfry z wiodącymi zerami

D - Tekstowy opis angielskiej nazwy dnia, trzy litery

j - Dzień miesiąca bez zer wiodących

l (mała litera 'L') - Pełen angielski opis dnia tygodnia

N - Liczbowa forma dnia tygodnia, zgodna z normą ISO-8601 (dodana w PHP 5.1.0)

S - Angielski przyrostek porządkowy dla dnia miesiąca, 2 litery

w - Liczbowa forma dnia tygodnia

z - Dzień roku (Zaczynając od 0)

W - Numer tygodnia w roku, zgodny z normą ISO-8601, Tygodnie rozpoczynają Poniedziałki (dostępne od PHP 4.1.0)

F - Pełen angielski opis, dnia miesiąca, taki jak January czy March

m - Liczbowa forma miesiąca, z zerami wiodącymi

M - Krótki, angielski opis miesiąca, trzy litery

n - Liczbowa forma miesiąca, bez zer wiodących

t - Ilość dni w danym miesiącu

L - Informacja o tym, czy rok jest przestępnym

o - Numer roku, zgodny z normą ISO-8601. Zwraca to taką samą wartość jak Y, z takim wyjątkiem, że numer tygodnia ISO (W) należy do poprzedniego lub następnego roku, niż rok użyty w tym miejscu. (dodane w PHP 5.1.0)

Y - Pełna liczbowa forma roku, 4 cyfry

y - Dwie cyfry reprezentujące rok

a - Pora dnia - dwie małe litery (przed/po południu) (ang. Ante/Post meridiem)

A - Pora dnia - dwie duże litery (przed/po południu) (ang. Ante/Post meridiem)

g - Godzina, w formacie 12-godzinnym, bez zer wiodących

G - Godzina, w formacie 24-godzinnym, bez zer wiodących

h - Godzina, w formacie 12-godzinnym, z zerami wiodącymi

H - Godzina, w formacie 24-godzinnym, z zerami wiodącymi

i - Minuty z zerami wiodącymi

s - Sekundy, z zerami wiodącymi

e - Identyfikator strefy czasowej (dodano w PHP 5.1.0)

I (duże i) - Informacja o tym, czy czas jest letni

O - Różnica z czasem Greenwich (GMT) w godzinach

P - Różnica z czasem Greenwich (GMT) z dwukropkiem pomiędzy godzinami i minutami (dodano w PHP 5.1.3)

T - Skrót dla strefy czasowej

Z - Różnica dla strefy czasowej w sekundach. Wyrównanie to jest zawsze ujemne dla stref położonych na zachód od południka 0, oraz dodatnie dla tych leżących na wschód od niego.

c - Data w standardzie ISO 8601 (dodana w PHP 5)

r - Data sformatowana zgodnie z RFC 2822

U - Sekundy liczone od ery UNIX-a (1 stycznia 1970 00:00:00 czasu Greenwich - GMT)

Zmiana daty[edytuj]

Wyświetlanie daty i czasu nie ogranicza się do wyświetlania informacji obecnych. Drugi parametr funkcji date() przyjmuje wartość czasu w sekundach od 1 stycznia 1970. Jeśli zostanie on podany, funkcja wyświetli czas, który był zapisany w tym parametrze. Jest on opcjonalny, tak więc:

date('r');

jest tym samym co:

date('r',time());

Przy następnych etapach będzie konieczne poznanie funkcji time, zwracającej czas liczony od tzw. "Ery UNIX-a" (01.01.1970 r.)

Teraz zastanówmy się - jak wyświetlić datę, która będzie za 1 dzień, tydzień, 21 dni, rok? Tutaj należy sobie przypomnieć jednostki i wykorzystać matematykę:

 1 minuta to 60 sekund
 60
 60 minut to 1 godzina
 60*60
 24 godziny to 1 doba
 60*60*24
 7 dni to 1 tydzień
 60*60*24*7
 365 dni to 1 rok (bez uwzględnienia przestępności)
 60*60*24*365

Teraz ładnie trzeba to przełożyć na PHP. Sprawa załatwiona:

<?php
// Aby nie liczyć kilka razy tego samego, użyjemy już wcześniej poznanych stałych
define('MINUTA',60);
define('GODZINA',60*60);
define('DOBA',60*60*24);
define('TYDZIEN',60*60*24*7);
define('ROK',60*60*24*365);

// Zwracamy dane
echo date('d-m-Y H:i:s',time()+MINUTA); // Za minutę
echo "<br>";
echo date('d-m-Y H:i:s',time()+GODZINA); // Za godzinę
echo "<br>";
echo date('d-m-Y H:i:s',time()+3*ROK+17*DOBA+6*GODZINA+39*MINUTA); // Za 3 lata, 17 dni, 6 godzin i 39 minut
?>

Jednak przed nami staje jeszcze problem optymalizacji, oraz dobra naszej klawiatury - pisanie np. 17*ROK+4*TYDZIEN+17*DOBA+4*GODZINA+7*MINUTA+42 jest bardzo męczące. Tutaj znów przychodzi z pomocą PHP, dzięki funkcji strtotime(). Funkcja ta zamienia większość angielskich tekstowych opisów daty i czasu na znacznik czasu:

<?php
echo date('d-m-Y H:i:s',strtotime("now"));
echo date('d-m-Y H:i:s',strtotime("+1 day"));
echo date('d-m-Y H:i:s',strtotime("+1 week 3 days 11 hours"));
echo date('d-m-Y H:i:s',strtotime("next Monday"));
echo date('d-m-Y H:i:s',strtotime("24 January 2003"));
?>

Dzięki temu nie jest wymagane użycie żadnych skomplikowanych operacji matematycznych - PHP zrobi wszystko za ciebie.

Sprawdzanie daty[edytuj]

Czasem w formularzu wymagane jest sprawdzenie, czy podana data jest prawdziwa. Tutaj bardzo dobrze sprawdzi się funkcja checkdate(). Przyjmuje ona za argumenty miesiąc, dzień i na końcu rok daty do sprawdzenia.

var_dump(checkdate(7, 16, 2006));
var_dump(checkdate(2, 30, 2003));

Różne formaty daty[edytuj]

Zauważ, że checkdate() nie przyjmuje tekstu jako parametrów. Czy to oznacza, że gdy mamy datę np. "9.21.2004", nie można jej sprawdzić? Tutaj pasuje idealnie wcześniej poznana funkcja explode().

$_Dane = explode(".","9.21.2004");
var_dump(checkdate($_Dane[0], $_Dane[1], $_Dane[2]));

Zakończenie[edytuj]

Poznałeś już większość funkcji związanych z czasem. Naprawdę jest ich więcej, ale aby ich używać należy wejść w głębia programowania obiektowego, którego podstaw będziesz się uczył już w następnym rozdziale.