Funkcje daty i czasu
Szybki quiz – przypomnienie poprzedniej lekcji
1. Co zostanie wyświetlone?
function podwoj($x) {
echo $x * 2;
}
$w = podwoj(4);
var_dump($w);
2. Co wyświetli poniższy kod?
function test() {
return 1;
echo "A";
}
echo test();
3. Dlaczego ten kod nie wyświetla liczby 250? Jak go poprawić bez użycia global?
$xp = 250;
function pokazXp() {
echo $xp;
}
pokazXp();
4. Co jest nie tak w definicji tej funkcji?
function powitanie($imie = "Gość", $wiek) {
return "$imie ma $wiek lat";
}
5. Co zostanie wyświetlone?
function licznik() {
static $c = 0;
$c++;
return $c;
}
echo licznik();
echo licznik();
echo licznik();
6. Co wyświetli kod w wersji A, a co w wersji B?
// Wersja A
function dodajXp($xp) {
$xp += 50;
}
// Wersja B
function dodajXp(&$xp) {
$xp += 50;
}
$xp = 100;
dodajXp($xp);
echo $xp;
7. Uzupełnij nagłówek funkcji tak, aby było jasne, że funkcja przyjmuje liczbę całkowitą i zwraca liczbę całkowitą.
function obliczPoziom(____ $xp) ____ {
// ...
}
8. TaskQuest: XP_NA_POZIOM wynosi 100. Co zwróci obliczPoziom(550), a co ileBrakujeXp(250, 3)?
Odpowiedzi
- Wyświetli
8, a potemNULL. Funkcja wyświetla wynik przezecho, ale nic nie zwraca, więc$wma wartośćNULL. 1.returnkończy działanie funkcji –echo "A"nigdy się nie wykona.- Zmienna
$xpjest globalna, a wewnątrz funkcji widoczne są tylko zmienne lokalne. PHP zgłosi ostrzeżenieUndefined variable $xpi nic nie wyświetli. Poprawka: przekazać wartość jako argument –function pokazXp($xp) { echo $xp; }i wywołaniepokazXp($xp);. - Parametr z wartością domyślną stoi przed parametrem bez wartości domyślnej. Argumenty domyślne muszą być na końcu listy:
function powitanie($wiek, $imie = "Gość"). W PHP 8 taki zapis daje komunikatDeprecated, a wartość domyślna"Gość"i tak nie działa – oba argumenty stają się wymagane. 123. Zmiennastaticzachowuje wartość między wywołaniami funkcji.- Wersja A:
100(przekazanie przez wartość – funkcja zmienia kopię). Wersja B:150(przekazanie przez referencję&– funkcja zmienia oryginalną zmienną). function obliczPoziom(int $xp): intobliczPoziom(550)zwraca6.ileBrakujeXp(250, 3)zwraca50(próg następnego poziomu:3 * 100 = 300,300 - 250 = 50).
PHP oferuje dwa główne sposoby pracy z datą i czasem:
- Funkcje proceduralne (starsze, np. `date()`, `time()`, `strtotime()`)
- Klasy DateTime (nowoczesne, obiektowe, zalecane od PHP 5.2+)
Era Uniksa (Unix Timestamp)
Aktualny czas, podawany jako liczba sekund, które upłynęły od nastania Ery Unixu: 1 stycznia 1970, 0:00:00 GMT.
Uniwersalny sposób reprezentacji czasu w systemach komputerowych – jedna liczba zamiast wielu składowych (rok, miesiąc, dzień, itd.).
Przykład:
- `0` = 1 stycznia 1970, 00:00:00 GMT
- `1000000000` = 9 września 2001, 01:46:40 GMT
- `1700000000` = 14 listopada 2023, 22:13:20 GMT
time()
Zwraca aktualny uniksowy znacznik czasu
$teraz = time();
echo $teraz; // np. 1714481247
// Za tydzień (7 dni * 24 godziny * 60 minut * 60 sekund)
$zaTydzien = time() + (7 * 24 * 60 * 60);
echo $zaTydzien;
date()
Formatuje lokalny czas/datę na czytelny format.
string date ( string $format [, int $timestamp = time() ] )
Jako $format podajemy odpowiedni schemat zapisu z tabeli poniżej, a $timestamp to znacznik czasowy – nie musimy go podawać, jest ustawiany automatycznie (jest to ilość sekund od nastania Ery Unixu: 1 stycznia 1970, 0:00:00 GMT).
Przykład:
echo date("l"); // wyświetli Monday
echo date("m.d.y"); // wyświetli 03.10.01
echo date("j, n, Y"); // wyświetli 10, 3, 2001
echo date('l jS \of F Y h:i:s A'); // wyświetli Monday 8th of August 2005 03:12:46 PM
echo date('Y-m-d', time()+(7*24*60*60)); //wyświetli datę za tydzień (7*24*60*60=604800 tyle sekund ma tydzień)
date() zwraca datę sformatowaną zgodnie z szablonem przedstawionym w poniższej tabeli.
Poniższych znaków używa się jako tekstu w parametrze format
| Zawartość parametru format | Opis | Przykład zwróconej wartości |
|---|---|---|
| Dzień | — | — |
| d | Dzień miesiąca, 2 cyfry z wiodącymi zerami | 01 do 31 |
| D | Tekstowy opis angielskiej nazwy dnia, trzy litery | Mon kończąc na Sun |
| j | Dzień miesiąca bez zer wiodących | 1 do 31 |
| l (mała litera 'L’) | Pełen angielski opis dnia tygodnia | Sunday aż do Saturday |
| N | Liczbowa forma dnia tygodnia, zgodna z normą ISO-8601 (dodana w PHP 5.1.0) | 1 (dla Poniedziałku) aż do 7 (dla Niedzieli) |
| S | Angielski przyrostek porządkowy dla dnia miesiąca, 2 litery | st, nd, rd lub th. Dobrze wygląda w połączeniu z j |
| w | Liczbowa forma dnia tygodnia | 0 (dla Niedzieli) aż do 6 (dla Soboty) |
| z | Dzień roku (Zaczynając od 0) | 0 aż do 365 |
| Tydzień | — | — |
| W | Numer tygodnia w roku, zgodny z normą ISO-8601, Tygodnie rozpoczynają Poniedziałki (dostępne od PHP 4.1.0) | Przykład: 42 (42. tydzień roku) |
| Miesiąc | — | — |
| F | Pełen angielski opis, dnia miesiąca, taki jak January czy March | January aż do December |
| m | Liczbowa forma miesiąca, z zerami wiodącymi | 01 aż do 12 |
| M | Krótki, angielski opis miesiąca, trzy litery | Jan a do Dec |
| n | Liczbowa forma miesiąca, bez zer wiodących | 1 aż do 12 |
| t | Ilość dni w danym miesiącu | 28 do 31 |
| Rok | — | — |
| L | Informacja o tym, czy rok jest przestępnym | 1 jeśli rok jest przestępny, 0 w przeciwnym wypadku. |
| 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) | Przykłady: 1999 lub 2003 |
| Y | Pełna liczbowa forma roku, 4 cyfry | Przykłady: 1999 lub 2003 |
| y | Dwie cyfry reprezentujące rok | Przykłady: 99 or 03 |
| Czas | — | — |
| a | Pora dnia – dwie małe litery (przed/po południu) (ang. Ante/Post meridiem) | am lub pm |
| A | Pora dnia – dwie duże litery (przed/po południu) (ang. Ante/Post meridiem) | AM lub PM |
| B | Swatch Internet Time | 000 aż do 999 |
| g | Godzina, w formacie 12-godzinnym, bez zer wiodących | 1 aż do 12 |
| G | Godzina, w formacie 24-godzinnym, bez zer wiodących | 0 aż do 23 |
| h | Godzina, w formacie 12-godzinnym, z zerami wiodącymi | 01 aż do 12 |
| H | Godzina, w formacie 24-godzinnym, z zerami wiodącymi | 00 through 23 |
| i | Minuty z zerami wiodącymi | 00 do 59 |
| s | Sekundy, z zerami wiodącymi | 00 aż do 59 |
| u | Mikrosekundy (dodano w PHP 5.2.2) | Przykład: 54321 |
| v | Milisekundy (dodano w PHP 7.0.0). | Przykład: 654 |
| Strefa czasowa | — | — |
| e | Identyfikator strefy czasowej (dodano w PHP 5.1.0) | Przykłady: UTC, GMT, Europe/Zagreb |
| I (duże i) | Informacja o tym, czy czas jest letni | 1 jeśli czas jest letni, 0 w przeciwnym razie. |
| O | Różnica z czasem Greenwich (GMT) w godzinach | Przykład: +0200 |
| P | Różnica z czasem Greenwich (GMT) z dwukropkiem pomiędzy godzinami i minutami (dodano w PHP 5.1.3) | Przykład: +02:00 |
| T | Skrót dla strefy czasowej | Przykłady: EST, MDT … |
| 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ódod niego. | -43200 aż do 50400 |
| Pełna Data/Czas | — | — |
| c | Data w standardzie ISO 8601 (dodana w PHP 5) | 2004-02-12T15:19:21+00:00 |
| r | Data sformatowana zgodnie z » RFC 2822 | Przykład: Thu, 21 Dec 2000 16:01:07 +0200 |
| U | Sekundy liczone od ery UNIX-a (1 stycznia 1970 00:00:00 czasu Greenwich – GMT) | Zobacz także time() |
getdate()
Zwraca tablicę asocjacyjną z informacjami o dacie
array getdate ([ int $timestamp = time() ] )
Funkcja zwraca tablicę asocjacyjną, a $timestamp to znacznik czasowy – nie musimy go podawać, jest ustawiany automatycznie (jest to ilość sekund od nastania Ery Unixu: 1 stycznia 1970, 0:00:00 GMT).
Przykład:
$info= getdate();
print_r($info);
echo "Dzisiaj jest {$info['mday']} {$info['month']} {$info['year']}";
// Dzisiaj jest 1 May 2024
Zostanie wyświetlone:
Array
(
[seconds] => 45 // sekundy
[minutes] => 30 // minuty
[hours] => 14 // godziny (24h)
[mday] => 1 // dzień miesiąca (1-31)
[wday] => 1 // dzień tygodnia (0=niedziela, 6=sobota)
[mon] => 5 // miesiąc (1-12)
[year] => 2024 // rok
[yday] => 121 // dzień roku (0-365)
[weekday] => Monday // nazwa dnia (ang.)
[month] => May // nazwa miesiąca (ang.)
[0] => 1714481445 // timestamp
)
microtime()
Zwraca aktualny uniksowy znacznik czasu z mikrosekundami
mixed microtime([bool $asFloat = false])
Przykład
// Jako string (domyślnie)
echo microtime(); // "0.25163900 1714481247"
// Jako float (zalecane)
echo microtime(true); // 1714481247.2516
// Mierzenie czasu wykonania
$start = microtime(true);
// Kod do zmierzenia
for ($i = 0; $i < 1000000; $i++) {
// jakieś operacje
}
$end = microtime(true);
$czas = $end - $start;
echo "Wykonanie trwało: " . round($czas, 4) . " sekund";
mktime()
Zwraca uniksowy znacznik czasu dla konkretnej daty
int mktime(
int $hour = date("H"),
int $minute = date("i"),
int $second = date("s"),
int $month = date("n"),
int $day = date("j"),
int $year = date("Y")
)
Zwraca liczbę sekund, które upłynęły od nastania Ery Unixu: 1 stycznia 1970, 0:00:00 GMT do podanej daty. Należy zwrócić uwagę na kolejność podawanych parametrów!
Poprawna kolejność parametrów to: godziny, minuty, sekundy, miesiąc, dzień, rok.
Aby wyświetlić np dzień tygodnia, w którym się urodziliście wystarczy dostosować poniższy kod
// Sprawdź dzień tygodnia swoich urodzin
$urodziny = mktime(0, 0, 0, 7, 15, 2000); // 15 lipca 2000
echo "Urodziłem się w " . date("l", $urodziny); // Saturday
// Konkretna data i czas
$sylwester = mktime(23, 59, 59, 12, 31, 2024);
echo date("Y-m-d H:i:s", $sylwester); // 2024-12-31 23:59:59
// mktime automatycznie koryguje nieprawidłowe daty
$nastepnyMiesiac = mktime(0, 0, 0, 13, 1, 2024); // miesiąc 13 -> styczeń 2025
echo date("Y-m-d", $nastepnyMiesiac); // 2025-01-01
strtotime()
Parsuje większość angielskich tekstowych opisów daty i czasu do uniksowego znacznika czasu
int strtotime ( string $czas [, int $teraz ] )
Funkcja przyjmuje tekst zawierający datę w formacie angielskim i stara się przeliczyć ją na uniksowy znacznik czasu, zachowuje się zgodnie ze składnią daty wg GNU. W przypadku fiaska, zwracane jest -1.
// Podstawowe użycie
echo strtotime("now"); // aktualny timestamp
echo strtotime("2024-05-01"); // konkretna data
echo strtotime("01 May 2024"); // angielski format
echo strtotime("2024-05-01 14:30:00"); // data i czas
// Relatywne daty
echo strtotime("+1 day"); // jutro
echo strtotime("-1 week"); // tydzień temu
echo strtotime("+2 months"); // za 2 miesiące
echo strtotime("+1 week 2 days"); // za tydzień i 2 dni
echo strtotime("+1 week 2 days 4 hours 2 seconds");
// Słowa kluczowe
echo strtotime("next Monday"); // następny poniedziałek
echo strtotime("last Friday"); // ostatni piątek
echo strtotime("tomorrow"); // jutro
echo strtotime("yesterday"); // wczoraj
echo strtotime("midnight"); // północ dzisiaj
echo strtotime("noon"); // południe dzisiaj
// Kombinacja
$base = strtotime("2024-01-01");
echo strtotime("+3 months", $base); // 3 miesiące od 1 stycznia 2024
// Formatowanie wyniku
echo date("Y-m-d", strtotime("+7 days")); // data za tydzień
Lista formatów dostępna tutaj.
Klasy DateTime (nowoczesne podejście)
Zalety obiektowego podejścia:
- Łatwiejsze manipulowanie datami
- Obsługa stref czasowych
- Immutable warianty (DateTimeImmutable)
- Lepsze porównywanie dat
- Bezpieczniejsze dla dat przed 1970 i po 2038
- Czytelniejszy kod
Klasa DateTime
Tworzenie obiektu:
// Aktualna data i czas
$teraz = new DateTime();
echo $teraz->format('Y-m-d H:i:s');
// Z konkretną datą
$data = new DateTime('2024-05-01');
$data = new DateTime('2024-05-01 14:30:00');
$data = new DateTime('now');
$data = new DateTime('tomorrow');
$data = new DateTime('+1 week');
// Ze strefą czasową
$data = new DateTime('now', new DateTimeZone('Europe/Warsaw'));
$data = new DateTime('2024-05-01', new DateTimeZone('America/New_York'));
Formatowanie (format)
$data = new DateTime('2024-05-01 14:30:45');
echo $data->format('Y-m-d'); // 2024-05-01
echo $data->format('d.m.Y'); // 01.05.2024
echo $data->format('l, j F Y'); // Wednesday, 1 May 2024
echo $data->format('H:i:s'); // 14:30:45
echo $data->format('c'); // 2024-05-01T14:30:45+02:00 (ISO 8601)
echo $data->format('r'); // Wed, 01 May 2024 14:30:45 +0200 (RFC 2822)
echo $data->format('U'); // 1714481445 (timestamp)
Modyfikowanie dat (modify, add, sub)
$data = new DateTime('2024-05-01');
// modify() - używa składni strtotime
$data->modify('+1 day');
$data->modify('-2 weeks');
$data->modify('+3 months');
$data->modify('next Monday');
// add() - używa DateInterval
$data->add(new DateInterval('P1D')); // +1 dzień
$data->add(new DateInterval('P7D')); // +7 dni
$data->add(new DateInterval('P1M')); // +1 miesiąc
$data->add(new DateInterval('PT2H')); // +2 godziny
$data->add(new DateInterval('P1DT2H')); // +1 dzień 2 godziny
// sub() - odejmowanie
$data->sub(new DateInterval('P1D')); // -1 dzień
Format DateInterval:
P– prefix (period)Y– lata (years)M– miesiące (months) lub minuty (po T)D– dni (days)T– separator czasuH– godziny (hours)M– minuty (minutes)S– sekundy (seconds)
'P1Y' // 1 rok
'P3M' // 3 miesiące
'P2W' // 2 tygodnie
'P10D' // 10 dni
'PT5H' // 5 godzin
'PT30M' // 30 minut
'PT45S' // 45 sekund
'P1DT12H' // 1 dzień i 12 godzin
'P1Y2M3DT4H5M6S' // 1 rok, 2 miesiące, 3 dni, 4 godziny, 5 minut, 6 sekund
Różnica między datami (diff)
$data1 = new DateTime('2024-01-01');
$data2 = new DateTime('2024-12-31');
$roznica = $data1->diff($data2);
echo $roznica->days; // 365 (całkowita liczba dni)
echo $roznica->y; // 0 (lata)
echo $roznica->m; // 11 (miesiące)
echo $roznica->d; // 30 (dni)
echo $roznica->h; // 0 (godziny)
echo $roznica->i; // 0 (minuty)
echo $roznica->s; // 0 (sekundy)
echo $roznica->invert; // 0 (dodatnia) lub 1 (ujemna)
// Formatowanie różnicy
echo $roznica->format('%y lat, %m miesięcy, %d dni');
// 0 lat, 11 miesięcy, 30 dni
Porównywanie dat
$data1 = new DateTime('2024-05-01');
$data2 = new DateTime('2024-06-01');
// Operatory porównania
if ($data1 < $data2) {
echo "Data1 jest wcześniejsza";
}
if ($data1 == $data2) {
echo "Daty są równe";
}
if ($data1 > $data2) {
echo "Data1 jest późniejsza";
}
// Różnica w sekundach
$roznica = $data2->getTimestamp() - $data1->getTimestamp();
echo "Różnica: $roznica sekund";
DateTimeImmutable
Niemodyfikowalna wersja DateTime – każda operacja zwraca NOWY obiekt.
Zapobiega przypadkowym zmianom daty, bezpieczniejsze w kodzie współdzielonym.
// DateTime - modyfikuje oryginalny obiekt
$data = new DateTime('2024-05-01');
$nowData = $data->modify('+1 day');
echo $data->format('Y-m-d'); // 2024-05-02 (zmieniona!)
echo $nowData->format('Y-m-d'); // 2024-05-02 (ta sama!)
// DateTimeImmutable - tworzy nowy obiekt
$data = new DateTimeImmutable('2024-05-01');
$nowData = $data->modify('+1 day');
echo $data->format('Y-m-d'); // 2024-05-01 (NIEzmieniona!)
echo $nowData->format('Y-m-d'); // 2024-05-02 (nowy obiekt!)
Strefy czasowe (DateTimeZone)
// Tworzenie z konkretną strefą
$warszawa = new DateTime('now', new DateTimeZone('Europe/Warsaw'));
$newYork = new DateTime('now', new DateTimeZone('America/New_York'));
echo $warszawa->format('Y-m-d H:i:s T'); // 2024-05-01 14:30:00 CEST
echo $newYork->format('Y-m-d H:i:s T'); // 2024-05-01 08:30:00 EDT
// Zmiana strefy czasowej
$data = new DateTime('2024-05-01 14:30:00', new DateTimeZone('UTC'));
echo $data->format('Y-m-d H:i:s T'); // 2024-05-01 14:30:00 UTC
$data->setTimezone(new DateTimeZone('Europe/Warsaw'));
echo $data->format('Y-m-d H:i:s T'); // 2024-05-01 16:30:00 CEST
// Lista wszystkich stref czasowych
$zones = DateTimeZone::listIdentifiers();
print_r($zones);
// ['Africa/Abidjan', 'Africa/Accra', ..., 'Europe/Warsaw', ...]
Tworzenie DateTime z timestamp
$timestamp = 1714481247;
// Sposób 1
$data = new DateTime();
$data->setTimestamp($timestamp);
// Sposób 2 (lepszy)
$data = (new DateTime())->setTimestamp($timestamp);
// Sposób 3 (najlepszy w PHP 5.3+)
$data = DateTime::createFromFormat('U', $timestamp);
echo $data->format('Y-m-d H:i:s');
Tworzenie DateTime z formatu niestandardowego
// Parsowanie niestandardowego formatu
$data = DateTime::createFromFormat('d/m/Y', '01/05/2024');
echo $data->format('Y-m-d'); // 2024-05-01
$data = DateTime::createFromFormat('d.m.Y H:i', '01.05.2024 14:30');
echo $data->format('Y-m-d H:i:s'); // 2024-05-01 14:30:00
// Z wykrywaniem błędów
$data = DateTime::createFromFormat('Y-m-d', 'nieprawidłowa-data');
if ($data === false) {
$errors = DateTime::getLastErrors();
print_r($errors);
}
Przykłady:
Liczenie czasu generowania strony
$start = microtime(true);
// Kod do zmierzenia
for ($i = 0; $i < 10000; $i++) {
$str = 'test';
}
$end = microtime(true);
echo 'Strona wygenerowana w ' . round($end - $start, 4) . ' sekund';
//Nowoczesny sposób
$start = new DateTimeImmutable();
// Kod do zmierzenia
for ($i = 0; $i < 10000; $i++) {
$str = 'test';
}
$end = new DateTimeImmutable();
$roznica = $start->diff($end);
echo 'Strona wygenerowana w ' . $roznica->format('%s.%f sekund');
Tworzenie daty o godzinę w przód
$czas_akt = time();
$za_godz = $czas_akt + 3600;
echo date("r", $za_godz); // Wyświetli datę 'za godzinę'
Data „za miesiąc”
$day = date('d');
$month = date('m');
$year = date('Y');
$month++;
if ($month == 13) {
$month = 1;
$year++;
}
echo "$day.$month.$year";
//Nowoczesny sposób
$data = new DateTime();
$data->modify('+1 month');
echo $data->format('d.m.Y');
// Lub z add()
$data = new DateTime();
$data->add(new DateInterval('P1M'));
echo $data->format('d.m.Y');
Odliczanie czasu do konkretnego wydarzenia:
function CountDown($hour, $minute, $second, $month, $day, $year) {
$eventDate = mktime($hour, $minute, $second, $month, $day, $year);
$today = time();
$secondsTo = $eventDate - $today;
$minutesTo = round($secondsTo / 60);
$hoursTo = round($minutesTo / 60);
$daysTo = round($hoursTo / 24);
$weeksTo = round($daysTo / 7);
$monthsTo = round($weeksTo / 4);
$yearsTo = round($monthsTo / 12);
return [
'seconds' => $secondsTo,
'minutes' => $minutesTo,
'hours' => $hoursTo,
'days' => $daysTo,
'weeks' => $weeksTo,
'months' => $monthsTo,
'years' => $yearsTo
];
}
$countdown = CountDown(12, 0, 0, 12, 31, 2024);
print_r($countdown);
//Nowoczesny sposób
function countDown(string $targetDate): array {
$teraz = new DateTimeImmutable();
$cel = new DateTimeImmutable($targetDate);
$roznica = $teraz->diff($cel);
return [
'days' => $roznica->days,
'hours' => $roznica->h,
'minutes' => $roznica->i,
'seconds' => $roznica->s,
'formatted' => $roznica->format('%a dni, %h godz, %i min, %s sek')
];
}
$countdown = countDown('2024-12-31 23:59:59');
echo "Do sylwestra zostało: {$countdown['formatted']}";
Baner zależny od pory dnia
function getBannerName() {
$hour = date("G");
if ($hour > 22 || $hour < 4) {
return "banner_noc.gif";
} elseif ($hour >= 4 && $hour < 12) {
return "banner_rano.gif";
} elseif ($hour >= 12 && $hour < 18) {
return "banner_dzien.gif";
} else {
return "banner_wieczor.gif";
}
}
echo '<img src="' . getBannerName() . '">';
//Nowoczesny sposób
function getBannerName(): string {
$teraz = new DateTime();
$godzina = (int)$teraz->format('G');
return match(true) {
$godzina >= 22 || $godzina < 4 => 'banner_noc.gif',
$godzina >= 4 && $godzina < 12 => 'banner_rano.gif',
$godzina >= 12 && $godzina < 18 => 'banner_dzien.gif',
default => 'banner_wieczor.gif'
};
}
echo '<img src="' . getBannerName() . '" alt="Banner">';
Sprawdzanie czy daty są z tego samego dnia
function sameDay($ts1, $ts2) {
return date("Y-m-d", $ts1) === date("Y-m-d", $ts2);
}
$date1 = mktime(19, 30, 0, 12, 10, 2024);
$date2 = mktime(10, 12, 0, 12, 10, 2024);
if (sameDay($date1, $date2)) {
echo "Daty są z tego samego dnia";
}
//Nowoczesny sposób
function sameDay(DateTime $date1, DateTime $date2): bool {
return $date1->format('Y-m-d') === $date2->format('Y-m-d');
}
$date1 = new DateTime('2024-12-10 19:30:00');
$date2 = new DateTime('2024-12-10 10:12:00');
$date3 = new DateTime('2024-12-11 19:30:00');
if (sameDay($date1, $date2)) {
echo "Daty 1 i 2 są z tego samego dnia\n";
}
if (!sameDay($date1, $date3)) {
echo "Daty 1 i 3 NIE są z tego samego dnia\n";
}
Wiek osoby
function obliczWiek(string $dataUrodzenia): int {
$urodziny = new DateTime($dataUrodzenia);
$teraz = new DateTime();
$roznica = $urodziny->diff($teraz);
return $roznica->y;
}
echo "Masz " . obliczWiek('2000-07-15') . " lat";
// Z dodatkowymi informacjami
function szczegolyWieku(string $dataUrodzenia): array {
$urodziny = new DateTime($dataUrodzenia);
$teraz = new DateTime();
$roznica = $urodziny->diff($teraz);
return [
'lata' => $roznica->y,
'miesiace' => $roznica->m,
'dni' => $roznica->d,
'calkowite_dni' => $roznica->days,
'formatted' => $roznica->format('%y lat, %m miesięcy, %d dni')
];
}
$wiek = szczegolyWieku('2000-07-15');
echo "Żyjesz już: {$wiek['formatted']} ({$wiek['calkowite_dni']} dni)";
Dni robocze między datami
function dniRoboczeMiedzy(DateTime $start, DateTime $end): int {
$dni = 0;
$current = clone $start;
while ($current <= $end) {
$dzienTygodnia = (int)$current->format('N'); // 1-7 (Pn-Nd)
if ($dzienTygodnia < 6) { // Pn-Pt
$dni++;
}
$current->modify('+1 day');
}
return $dni;
}
$poczatek = new DateTime('2024-05-01');
$koniec = new DateTime('2024-05-31');
echo "Dni robocze w maju 2024: " . dniRoboczeMiedzy($poczatek, $koniec);
Pierwszy i ostatni dzień miesiąca
function pierwszyDzienMiesiaca(int $miesiac, int $rok): DateTime {
return new DateTime("$rok-$miesiac-01");
}
function ostatniDzienMiesiaca(int $miesiac, int $rok): DateTime {
$data = new DateTime("$rok-$miesiac-01");
$data->modify('last day of this month');
return $data;
}
$pierwszy = pierwszyDzienMiesiaca(5, 2024);
$ostatni = ostatniDzienMiesiaca(5, 2024);
echo "Maj 2024: " . $pierwszy->format('Y-m-d') . " - " . $ostatni->format('Y-m-d');
// Maj 2024: 2024-05-01 - 2024-05-31
Czy data jest w przeszłości/przyszłości
function czyPrzeszlosc(DateTime $data): bool {
return $data < new DateTime();
}
function czyPrzyszlosc(DateTime $data): bool {
return $data > new DateTime();
}
$wczoraj = new DateTime('yesterday');
$jutro = new DateTime('tomorrow');
var_dump(czyPrzeszlosc($wczoraj)); // true
var_dump(czyPrzyszlosc($jutro)); // true
Zadania do wykonania:
Zadanie 1: Napisz skrypt, który będzie pokazywał aktualna datę i czas w postaci: Dzisiaj jest 30.10.2018 godzina 16:50:47
Zadanie 2: Napisz skrypt sprawdzający w jaki dzień tygodnia się urodziłeś/łaś oraz sprawdź ile czasu zostało do twoich urodzin.
Zadanie 6: Napisz funkcję, która sprawdzi, czy podana data jest weekendem.
Zadanie 7: Napisz funkcję, która zwróci liczbę pełnych tygodni między dwiema datami.
TaskQuest — Karta pracy
KARTA PRACY
TaskQuest 0.7 — terminy i prawdziwy streak
Mamy już użytkownika, XP oraz poziomy.
Ale jedna rzecz wciąż jest sztuczna:
$wykonalDzisiajZadanie = true;
Skąd program ma wiedzieć, czy użytkownik naprawdę wykonał zadanie dzisiaj?
Do tego potrzebujemy daty i czasu.
Cel lekcji
Wykorzystać daty do stworzenia dwóch elementów TaskQuest:
- terminu wykonania zadania,
- pierwszego prawdziwego mechanizmu streak.
1. Problem
Dotychczas informację o aktywności ustawialiśmy ręcznie:
$wykonalDzisiajZadanie = true;To nie jest prawdziwy mechanizm.
TaskQuest powinien znać:
dzisiejszą datę
datę ostatniej aktywności
termin zadania2. Jedno zadanie
Nie znamy jeszcze tablic. Dlatego pracujemy tylko na jednym przykładowym zadaniu.
$tytulZadania = "Nauczyć się obsługi daty w PHP";
$terminZadania = "2026-09-20";
$zadanieWykonane = false;Na razie:
$zadanieWykonane = false;oznacza:
zadanie nie zostało wykonane.
Później zmienimy tę wartość na true, aby zasymulować wykonanie zadania.
3. SAMODZIELNIE — ile dni zostało?
Utwórz:
$dzisiaj = new DateTime('today');
$termin = new DateTime($terminZadania);Następnie oblicz różnicę:
$roznica = $dzisiaj->diff($termin);Możesz zobaczyć co zostało zwrócone i co zawiera zmienna $roznica:
print_r($roznica);Spróbuj wyświetlić liczbę dni.
HINT
Obiekt zwrócony przez diff() posiada między innymi:
$roznica->days
4. Zadanie jest przed terminem czy po terminie?
Sprawdź:
if ($termin < $dzisiaj) {
// termin minął
}
Jeżeli termin jest w przyszłości:
Do terminu pozostało: 5 dni.
Jeżeli minął:
Termin minął 2 dni temu.
A może jest dzisiaj?
Termin jest dzisiaj.5. Funkcja zwracająca komunikat
Utwórz funkcję:
function komunikatTerminu(string $terminZadania): string
Ma ona zwrócić odpowiedni komunikat, wykorzystując:
$dzisiaj
$termin
$roznica
oraz stworzone warunki if.
Nie używaj wewnątrz funkcji:
echo
Funkcja ma zwrócić tekst przez:
return
Wyświetl odpowiednio zadanie i termin zadania oraz odpowiedni komunikat.
6. Streak — czy passa wciąż trwa
Zanim zaczniemy pisać kod streaka, uporządkujmy jedną rzecz.
W poprzedniej wersji pojawiały się dwie zmienne:
$zadanieWykonaneoraz:
$wykonalDzisiajZadanieNie będziemy używać obu.
KROK 1 — ZMIANA $wykonalDzisiajZadanie
W całym kodzie znajdź:
$wykonalDzisiajZadanie
i zmień jej nazwę na:
$zadanieWykonane
Dotyczy to wszystkich miejsc:
- przykładu,
- danych używanych przy streaku,
- warunku
if, - parametru funkcji
aktualizujStreak(), - warunku wewnątrz funkcji,
- wywołania funkcji.
Uwaga
W sekcji z zadaniem mamy już:
$zadanieWykonane = false;
Nie tworzymy drugi raz:
$zadanieWykonane = true;
Jeżeli chcemy zasymulować wykonanie zadania dzisiaj, zmieniamy wartość istniejącej zmiennej:
$zadanieWykonane = true;
Od tej pory w całym TaskQuest używamy tylko jednej zmiennej:
$zadanieWykonane
Oznacza ona:
Czy użytkownik wykonał zadanie?
7. Jak działa streak?
Mamy trzy informacje:
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-14";
$zadanieWykonane = true;
Interesuje nas:
Co powinno stać się ze streakiem, jeśli użytkownik wykona dziś zadanie?
Rozpatrujemy trzy sytuacje.
Sytuacja 1 — ostatnia aktywność była dzisiaj
Przykład:
dzisiaj: 2026-09-17
ostatnia aktywność: 2026-09-17
Użytkownik już dzisiaj wykonał zadanie.
Nie zwiększamy streaka.
streak pozostaje bez zmian
Sytuacja 2 — ostatnia aktywność była wczoraj
Przykład:
dzisiaj: 2026-09-17
ostatnia aktywność: 2026-09-16
Użytkownik zachował ciągłość.
Zwiększamy streak:
$streak++;
Jeżeli było:
5
będzie:
6
Sytuacja 3 — ostatnia aktywność była wcześniej
Przykład:
dzisiaj: 2026-09-17
ostatnia aktywność: 2026-09-14
Między aktywnościami była przerwa.
Jeżeli użytkownik wykona dziś zadanie, rozpoczyna nową serię:
$streak = 1;
8. SAMODZIELNIE — przygotuj daty
Utwórz:
$dzisiaj = new DateTime('today');
$ostatniaAktywnosc =
new DateTime($dataOstatniejAktywnosci);
$wczoraj = new DateTime('yesterday');
Mamy teraz trzy daty:
dzisiaj
wczoraj
ostatnia aktywność
Porównaj je.
HINT
Możesz porównać daty po sformatowaniu:
$ostatniaAktywnosc->format('Y-m-d')
oraz:
$dzisiaj->format('Y-m-d')
9. POMOC — układ warunków
Najpierw sprawdzamy, czy zadanie zostało wykonane.
if ($zadanieWykonane) {
// tutaj sprawdzamy datę
}
Dlaczego?
Bo jeśli zadanie nie zostało wykonane:
$zadanieWykonane = false;
to nie powinniśmy zmieniać streaka.
Następnie sprawdzamy, czy ostatnia aktywność była dzisiaj:
if (
$ostatniaAktywnosc->format('Y-m-d')
===
$dzisiaj->format('Y-m-d')
) {
// nic nie zmieniamy
}
Jeżeli nie, sprawdzamy wczoraj:
elseif (
$ostatniaAktywnosc->format('Y-m-d')
===
$wczoraj->format('Y-m-d')
) {
$streak++;
}
Jeżeli nie było ani dzisiaj, ani wczoraj:
else {
$streak = 1;
}
10. SAMODZIELNIE — napisz logikę streaka
Spróbuj teraz połączyć wszystko samodzielnie.
Masz:
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-14";
$zadanieWykonane = true;
Utwórz:
$dzisiaj = new DateTime('today');
$wczoraj = new DateTime('yesterday');
$ostatniaAktywnosc =
new DateTime($dataOstatniejAktywnosci);
Następnie napisz warunki.
11. ROZWIĄZANIE — logika streaka
if ($zadanieWykonane) {
if (
$ostatniaAktywnosc->format('Y-m-d')
===
$dzisiaj->format('Y-m-d')
) {
// nic nie zmieniamy
} elseif (
$ostatniaAktywnosc->format('Y-m-d')
===
$wczoraj->format('Y-m-d')
) {
$streak++;
} else {
$streak = 1;
}
}
Na tym etapie nie tworzymy jeszcze funkcji.
Najpierw ważne jest, żeby zrozumieć samą logikę.
12. Przenosimy streak do funkcji
Kiedy logika działa, zamykamy ją w funkcji.
Utwórz:
function aktualizujStreak(
int $streak,
string $dataOstatniejAktywnosci,
bool $zadanieWykonane
): int
Funkcja otrzymuje trzy informacje:
$streak
$dataOstatniejAktywnosci
$zadanieWykonane
i zwraca nową wartość streaka.
KROK 1
Jeżeli zadanie nie zostało wykonane:
if (!$zadanieWykonane) {
return $streak;
}
Streak pozostaje bez zmian.
KROK 2
Utwórz daty wewnątrz funkcji:
$dzisiaj = new DateTime('today');
$wczoraj = new DateTime('yesterday');
$ostatniaAktywnosc =
new DateTime($dataOstatniejAktywnosci);
KROK 3
Sprawdź, czy aktywność była dzisiaj.
Jeżeli tak:
return $streak;
KROK 4
Sprawdź, czy aktywność była wczoraj.
Jeżeli tak:
return $streak + 1;
KROK 5
Jeżeli aktywność była wcześniej:
return 1;
13. ROZWIĄZANIE — funkcja streaka
function aktualizujStreak(int $streak,string $dataOstatniejAktywnosci,bool $zadanieWykonane): int {
if (!$zadanieWykonane) return $streak;
$dzisiaj = new DateTime('today');
$wczoraj = new DateTime('yesterday');
$ostatniaAktywnosc = new DateTime($dataOstatniejAktywnosci);
if ($ostatniaAktywnosc->format('Y-m-d') === $dzisiaj->format('Y-m-d')) return $streak;
if ($ostatniaAktywnosc->format('Y-m-d') === $wczoraj->format('Y-m-d')) return $streak + 1;
return 1;
}
Zwróć uwagę:
nie ma już **$wykonalDzisiajZadanie**.
Mamy tylko:
$zadanieWykonane
14. Wywołanie funkcji
Przygotuj dane:
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-14";
$zadanieWykonane = true;
Następnie:
$streak = aktualizujStreak(
$streak,
$dataOstatniejAktywnosci,
$zadanieWykonane
);
Funkcja oblicza nowy streak i zapisujemy wynik ponownie do:
$streak
15. Ważne — co oznacza data ostatniej aktywności?
W tej lekcji:
$dataOstatniejAktywnosci
oznacza datę poprzedniej zapisanej aktywności, którą przekazujemy do funkcji.
Przykład:
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-16";
$zadanieWykonane = true;
Jeżeli dzisiaj jest:
2026-09-17
wynik będzie:
6
Jeżeli:
$dataOstatniejAktywnosci = "2026-09-17";
wynik pozostanie:
5
bo aktywność z dzisiaj została już uwzględniona.
Jeżeli:
$dataOstatniejAktywnosci = "2026-09-14";
wynik będzie:
1
bo seria została przerwana.
16. Funkcja komunikatu terminu
Pozostawiamy funkcję z wcześniejszej części:
function komunikatTerminu(string $terminZadania): string{
$dzisiaj = new DateTime('today');
$termin = new DateTime($terminZadania);
$roznica = $dzisiaj->diff($termin);
// print_r($roznica);
if ($termin < $dzisiaj) {
return "Termin minął {$roznica->days} dni temu.!";
} elseif ($termin == $dzisiaj) {
return "Termin jest dzisiaj.";
} else{
return "Do terminu pozostało: {$roznica->days} dni.";
}
}
17. ROZWIĄZANIE — wersja referencyjna
<?php
function komunikatTerminu(string $terminZadania): string
{
$dzisiaj = new DateTime('today');
$termin = new DateTime($terminZadania);
$roznica = $dzisiaj->diff($termin);
if ($termin < $dzisiaj) return "Termin minął {$roznica->days} dni temu.";
if ($termin == $dzisiaj) return "Termin jest dzisiaj!";
return "Do terminu pozostało: {$roznica->days} dni.";
}
function aktualizujStreak(int $streak,string $dataOstatniejAktywnosci,bool $zadanieWykonane): int {
if (!$zadanieWykonane) return $streak;
$dzisiaj = new DateTime('today');
$wczoraj = new DateTime('yesterday');
$ostatniaAktywnosc = new DateTime($dataOstatniejAktywnosci);
if ($ostatniaAktywnosc->format('Y-m-d') === $dzisiaj->format('Y-m-d')) return $streak;
if ($ostatniaAktywnosc->format('Y-m-d') === $wczoraj->format('Y-m-d')) return $streak + 1;
return 1;
}
$tytulZadania = "Nauczyć się obsługi daty w PHP";
$terminZadania = "2026-09-20";
$zadanieWykonane = true;
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-14";
$streak = aktualizujStreak($streak,$dataOstatniejAktywnosci,$zadanieWykonane);
echo "<h1>TaskQuest</h1>";
echo "<h2>$tytulZadania</h2>";
echo "<p>"
. komunikatTerminu($terminZadania)
. "</p>";
echo "<p>Streak: $streak dni</p>";
echo "<p>Stan: <strong>"
. ($zadanieWykonane ? "Wykonane" : "W trakcie")
. "</strong></p>";
18. Co usunęliśmy?
W całym kodzie nie ma już:
$wykonalDzisiajZadanie
Nie tworzymy tej zmiennej.
Nie przekazujemy jej do funkcji.
Nie sprawdzamy jej w if.
19. Co zostało?
Mamy jedną zmienną:
$zadanieWykonane
Ona określa stan zadania.
$zadanieWykonane = false;
oznacza:
zadanie niewykonane
a:
$zadanieWykonane = true;
oznacza:
zadanie wykonane
W tej lekcji true oznacza, że symulujemy wykonanie zadania dzisiaj.
Datę ostatniej wcześniejszej aktywności przechowujemy osobno:
$dataOstatniejAktywnosci
Dzięki temu każda zmienna ma jedno zadanie.
20. Testy streaka
Testuj tylko zmianę:
$dataOstatniejAktywnosci
oraz:
$zadanieWykonane
Test 1 — zadanie niewykonane
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-16";
$zadanieWykonane = false;
Wynik:
Streak: 5
Test 2 — aktywność była dzisiaj
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-17";
$zadanieWykonane = true;
Wynik:
Streak: 5
Test 3 — aktywność była wczoraj
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-16";
$zadanieWykonane = true;
Wynik:
Streak: 6
Test 4 — aktywność była 5 dni temu
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-12";
$zadanieWykonane = true;
Wynik:
Streak: 1
21. Testy terminów
Przetestuj:
wczoraj
dzisiaj
jutro
za 10 dni
Zmieniając:
$terminZadania
Sprawdź, czy komunikat jest prawidłowy.
22. Mini-eksperyment
Sprawdź różnicę między:
new DateTime('now')
i:
new DateTime('today')
Wyświetl oba obiekty przez:
format('Y-m-d H:i:s')
Zwróć uwagę na godzinę.
23. Ważna uwaga dotycząca prawdziwego TaskQuest
Na razie dane są zapisane ręcznie w kodzie:
$streak = 5;
$dataOstatniejAktywnosci = "2026-09-14";
Dlatego jest to symulacja działania streaka.
W prawdziwej aplikacji po wykonaniu zadania trzeba będzie zapisać nową datę aktywności, np.:
dzisiaj → 2026-09-17
i przy kolejnym wejściu na stronę odczytać ją ponownie.
Do tego wykorzystamy później bazę danych.
Na tej lekcji skupiamy się na tym, jak PHP rozpoznaje:
dzisiaj
wczoraj
wcześniej
na podstawie dat.
Do samodzielnego sprawdzenia
- Potrafię utworzyć obiekt
DateTime. - Potrafię sformatować datę.
- Potrafię porównać dwie daty.
- Użyłem
diff(). - Zadanie informuje o terminie.
- Streak reaguje na datę ostatniej aktywności.
- Używam jednej zmiennej
$zadanieWykonane. - Nie używam
$wykonalDzisiajZadanie. - Rozumiem, kiedy streak się zwiększa.
- Rozumiem, kiedy streak pozostaje bez zmian.
- Rozumiem, kiedy streak zostaje ustawiony na
1. - Nadal nie używam tablic.
Pytania kontrolne
- Czym różni się data zapisana jako string od obiektu
DateTime? - Do czego służy
format()? - Co zwraca
diff()? - Co powinno stać się ze streakiem po trzydniowej przerwie?
- Dlaczego nie możemy zwiększać streaka za każdym odświeżeniem strony?
- Dlaczego użyliśmy
today, a nie zawszenow? - Do czego służy
$zadanieWykonane? - Do czego służy
$dataOstatniejAktywnosci? - Dlaczego nie potrzebujemy osobnej zmiennej
$wykonalDzisiajZadanie? - Co stanie się ze streakiem, jeżeli zadanie nie zostało wykonane?
- Co stanie się ze streakiem, jeżeli ostatnia aktywność była wczoraj?
- Co stanie się ze streakiem, jeżeli ostatnia aktywność była dzisiaj?
- Co stanie się ze streakiem, jeżeli ostatnia aktywność była 5 dni temu?
PODSUMOWANIE LEKCJI
W skrócie
- Timestamp to jedna liczba całkowita: sekundy od 1 stycznia 1970, 00:00:00 GMT.
time()zwraca timestamp „teraz”. Na timestampach można wykonywać zwykłe działania arytmetyczne (np.time() + 3600= za godzinę). date()nie liczy, tylko formatuje. Zamienia timestamp na tekst według podanego wzoru. Bez drugiego argumentu formatuje aktualny czas.- Litery formatu rozróżniają wielkość znaków.
mto miesiąc,ito minuty.Hto godzina 0–23,hto 1–12.Yto rok 4-cyfrowy,y2-cyfrowy.dma zero wiodące,jnie ma.l(małe L) to nazwa dnia,Lto informacja o roku przestępnym. mktime()ma nietypową kolejność argumentów: godzina, minuta, sekunda, miesiąc, dzień, rok. Błędne wartości nie powodują błędu – PHP je „przelicza” (miesiąc 13 = styczeń następnego roku), więc pomyłka w kolejności daje po cichu inną datę.strtotime()rozumie tekst po angielsku ("+1 day","next Monday","2026-09-20") i zwraca timestamp. Drugi argument to punkt odniesienia.- Obiekt
DateTimeto nie tekst. Nie wyświetlisz go przezecho $data– zawsze używasz->format('...'). Litery formatu są takie same jak wdate(). DateTimezmienia sam siebie (modify(),add(),sub()), aDateTimeImmutablezostawia oryginał i zwraca nowy obiekt.diff()zwraca obiektDateInterval.->daysto całkowita liczba dni między datami.->y,->m,->dto składowe (lata, miesiące, dni) –->dto nie jest liczba wszystkich dni.->daysjest zawsze dodatnie. Kierunek różnicy mówi->invertalbo zwykłe porównanie dat</>. Dlatego w TaskQuest osobno sprawdzamy, czy termin minął.- Obiekty
DateTimeporównuje się operatorami<,>,==– porównywana jest data razem z godziną. 'now'ma aktualną godzinę,'today'ma godzinę 00:00:00. Jeśli porównujesz tylko dni, używaj'today'albo porównuj tekstyformat('Y-m-d').- DateInterval: zaczyna się od
P, część czasowa poT.MprzedTto miesiące, poT– minuty. - Streak w TaskQuest zależy od daty ostatniej aktywności: dzisiaj → bez zmian, wczoraj →
+1, wcześniej →1. Gdy zadanie nie jest wykonane, streak się nie zmienia.
Co trzeba umieć na INF.03?
- uczeń powinien umieć wyświetlić aktualną datę i godzinę w wymaganym formacie, np.
17.09.2026 16:50, - dobrać litery formatu na podstawie opisu (np. z dokumentacji lub tabeli) i rozpoznać pomyłkę typu
mzamiasti, - odczytać działanie nieznanej funkcji wbudowanej z jej opisu (kolejność argumentów, typ zwracanej wartości) – na egzaminie funkcje PHP są podawane w tabeli,
- przetestować skrypt dla kilku wartości wejściowych i sprawdzić wynik.
Minimum, które powinno wejść w pamięć
date("d.m.Y H:i:s")– aktualna data i godzina.m= miesiąc,i= minuty.time()– teraz w sekundach.time() + 24*60*60– ta sama godzina jutro.mktime(godz, min, sek, MIESIĄC, DZIEŃ, rok)– najpierw miesiąc, potem dzień.new DateTime('2026-09-20')tworzy datę,->format('d.m.Y')ją wyświetla.echo $obiektnie działa.$a->diff($b)->days– ile dni między datami (zawsze liczba dodatnia).$termin < $dzisiaj– porównanie dat obiektówDateTime.'today'= dzisiaj o północy,'now'= teraz z godziną.DateTimemodyfikuje oryginał,DateTimeImmutablezwraca nowy obiekt.
Ściągawka – najważniejsze polecenia i składnia
Funkcje proceduralne
| Funkcja | Co robi | Przykład |
|---|---|---|
time() | aktualny timestamp | time() + 3600 |
date(format, [timestamp]) | timestamp → tekst | date("Y-m-d") |
mktime(h, i, s, m, d, Y) | konkretna data → timestamp | mktime(0, 0, 0, 7, 15, 2000) |
strtotime(tekst, [baza]) | tekst ang. → timestamp | strtotime("+7 days") |
getdate([timestamp]) | tablica z częściami daty | getdate()['year'] |
microtime(true) | timestamp z ułamkiem sekundy | pomiar czasu wykonania |
Najczęstsze litery formatu
| Litera | Znaczenie | Przykład |
|---|---|---|
d / j | dzień z zerem / bez zera | 05 / 5 |
m / n | miesiąc z zerem / bez zera | 09 / 9 |
Y / y | rok 4 / 2 cyfry | 2026 / 26 |
H / G | godzina 24h z zerem / bez zera | 08 / 8 |
i | minuty | 07 |
s | sekundy | 09 |
l | nazwa dnia (ang.) | Thursday |
N | dzień tygodnia 1 (pn) – 7 (nd) | 4 |
t | liczba dni w miesiącu | 30 |
L | rok przestępny (1/0) | 0 |
Obiektowo – DateTime
$d = new DateTime('today'); // dziś 00:00
$d = new DateTime('2026-09-20'); // konkretna data
echo $d->format('d.m.Y'); // wyświetlenie
$d->modify('+1 day'); // zmiana (składnia jak w strtotime)
$d->add(new DateInterval('P1M')); // +1 miesiąc
$d->sub(new DateInterval('PT2H')); // -2 godziny
$r = $a->diff($b); // różnica
$r->days; // wszystkie dni
$r->invert; // 1, gdy $b jest wcześniej niż $a
if ($a < $b) { } // porównanie
if ($a->format('Y-m-d') === $b->format('Y-m-d')) { } // ten sam dzień
DateInterval
P1D 1 dzień PT1H 1 godzina
P2W 2 tygodnie PT30M 30 minut
P3M 3 miesiące PT45S 45 sekund
P1Y 1 rok P1DT12H 1 dzień i 12 godzin
Schemat z TaskQuest – czy termin minął
$dzisiaj = new DateTime('today');
$termin = new DateTime($terminZadania);
$roznica = $dzisiaj->diff($termin);
if ($termin < $dzisiaj) // termin minął $roznica->days dni temu
elseif ($termin == $dzisiaj) // termin jest dzisiaj
else // zostało $roznica->days dni
Quiz – sprawdź się
1. Co oznacza liczba 0 jako uniksowy znacznik czasu? Co zwraca time()?
2. Co zostanie wyświetlone?
echo date("j.n.y G:i", mktime(14, 7, 9, 3, 5, 2026));
3. Uczeń chciał wyświetlić godzinę w formacie 16:05. Znajdź błąd.
echo date("H:m");
4. Uczeń chciał zapisać datę 15 lipca 2000 r. Jaką datę faktycznie otrzyma? Dlaczego PHP nie zgłosi błędu?
$urodziny = mktime(0, 0, 0, 15, 7, 2000);
echo date("Y-m-d", $urodziny);
5. Co zostanie wyświetlone?
$sylwester = mktime(0, 0, 0, 12, 31, 2025);
echo date("Y-m-d", strtotime("+1 day", $sylwester));
6. Dlaczego ten kod kończy się błędem? Popraw go.
$data = new DateTime('2026-09-17');
echo $data;
7. Co zostanie wyświetlone w wersji A, a co w wersji B?
// Wersja A
$a = new DateTime('2026-09-17');
// Wersja B
$a = new DateTimeImmutable('2026-09-17');
$b = $a->modify('+1 day');
echo $a->format('d.m') . ' ' . $b->format('d.m');
8. Co zostanie wyświetlone?
$od = new DateTime('2026-01-01');
$do = new DateTime('2026-03-15');
$r = $od->diff($do);
echo $r->days . ' / ' . $r->m . ' / ' . $r->d;
9. Co zostanie wyświetlone? Co z tego wynika dla funkcji komunikatTerminu()?
$r = (new DateTime('2026-09-20'))->diff(new DateTime('2026-09-17'));
echo $r->days . ' ' . $r->invert;
10. Który zapis oznacza „2 godziny i 30 minut”?
- a)
'P2H30M' - b)
'PT2H30M' - c)
'P2HT30M' - d)
'PT2H30'
11. O ile przesunie datę add(new DateInterval('P3M')), a o ile add(new DateInterval('PT3M'))?
12. Co zostanie wyświetlone?
$a = new DateTime('2026-09-17 08:00');
$b = new DateTime('2026-09-17 20:30');
var_dump($a == $b);
var_dump($a->format('Y-m-d') === $b->format('Y-m-d'));
13. W funkcji komunikatTerminu() ktoś zamienił 'today' na 'now'. Termin zadania to dzisiejsza data. Jaki komunikat się wyświetli i dlaczego?
$dzisiaj = new DateTime('now');
$termin = new DateTime($terminZadania); // dzisiejsza data
$roznica = $dzisiaj->diff($termin);
if ($termin < $dzisiaj) return "Termin minął {$roznica->days} dni temu.";
if ($termin == $dzisiaj) return "Termin jest dzisiaj!";
return "Do terminu pozostało: {$roznica->days} dni.";
14. TaskQuest. Załóż, że dzisiaj jest 2026-09-17. Co zwróci aktualizujStreak() w każdym przypadku?
$streak | $dataOstatniejAktywnosci | $zadanieWykonane | |
|---|---|---|---|
| a) | 3 | "2026-09-16" | true |
| b) | 3 | "2026-09-17" | true |
| c) | 3 | "2026-09-10" | false |
| d) | 3 | "2026-09-10" | true |
15. Uzupełnij kod tak, aby wyświetlił angielską nazwę dnia tygodnia, w którym wypada 1 maja 2026 r.
echo date("___", mktime(0, 0, 0, ___, ___, 2026));
16. Zadanie praktyczne. Napisz funkcję czyPoTerminie(string $terminZadania): bool, która zwraca true, jeżeli termin był przed dzisiejszym dniem, a false w pozostałych przypadkach (także gdy termin jest dzisiaj). Użyj DateTime. Przetestuj ją dla daty wczorajszej, dzisiejszej i jutrzejszej.
Odpowiedzi
0to 1 stycznia 1970, 00:00:00 GMT (początek ery Uniksa).time()zwraca liczbę sekund, które upłynęły od tego momentu do teraz.5.3.26 14:07–jinbez zer wiodących,ydwucyfrowo,Ggodzina bez zera,iminuty.moznacza miesiąc, a nie minuty. Wyświetli się np.16:09(wrzesień). Poprawnie:date("H:i").2001-03-07. Argumentymktime()to godzina, minuta, sekunda, miesiąc, dzień, rok – uczeń zamienił miesiąc z dniem. PHP traktuje „miesiąc 15” jako marzec kolejnego roku i przelicza datę zamiast zgłaszać błąd. Poprawnie:mktime(0, 0, 0, 7, 15, 2000).2026-01-01.strtotime()liczy „+1 dzień” względem 31 grudnia 2025 i przechodzi na nowy rok.- Obiektu
DateTimenie można zamienić na tekst (Error: Object of class DateTime could not be converted to string). Poprawnie:echo $data->format('Y-m-d');. - Wersja A:
18.09 18.09–modify()zmienia oryginalny obiekt, a$bwskazuje ten sam obiekt. Wersja B:17.09 18.09–DateTimeImmutablezostawia oryginał bez zmian i zwraca nowy obiekt. 73 / 2 / 14.daysto wszystkie dni (31 + 28 + 14), amidto składowe: 2 miesiące i 14 dni.3 1.daysjest zawsze dodatnie, ainvert= 1 oznacza, że druga data jest wcześniejsza. Dlatego wkomunikatTerminu()sama liczba dni nie wystarczy – trzeba osobno porównać$termin < $dzisiaj, żeby wiedzieć, czy termin minął.- b)
'PT2H30M'. Godziny i minuty muszą stać poT. Zapis a) powoduje błąd (wyjątek) przy tworzeniuDateInterval. P3M– o 3 miesiące (np. z 2026-09-17 na 2026-12-17).PT3M– o 3 minuty (z 00:00 na 00:03).MprzedTto miesiące, poT– minuty.bool(false)ibool(true).==porównuje datę razem z godziną, a porównanie tekstówY-m-dsprawdza tylko dzień.Termin minął 0 dni temu.new DateTime($terminZadania)ma godzinę 00:00, a'now'– aktualną godzinę. Termin jest więc „wcześniej” niż teraz, a warunek==nigdy nie będzie spełniony. Dlatego w TaskQuest używamy'today'.- a)
4– ostatnia aktywność wczoraj, seria trwa. b)3– aktywność z dzisiaj już była uwzględniona. c)3– zadanie niewykonane, streak bez zmian. d)1– była przerwa, zaczyna się nowa seria. echo date("l", mktime(0, 0, 0, 5, 1, 2026));– wyświetliFriday.- Przykładowe rozwiązanie:
function czyPoTerminie(string $terminZadania): bool {
$dzisiaj = new DateTime('today');
$termin = new DateTime($terminZadania);
return $termin < $dzisiaj;
}
Oczekiwane wyniki: wczoraj → true, dzisiaj → false, jutro → false. Typowy błąd: użycie 'now' zamiast 'today' – wtedy dzisiejsza data da true.