Урок 10. Даты в PHP
Теория
Для работы с датами в PHP применяются различные функции. Мы начнем изучение с функции time.
Функция time, формат timestamp
Функция time возвращает разницу в секундах между 1.1.1970 и текущим моментом времени. Такое представление даты называется форматом timestamp.
Зачем нужен timestamp?
Время в формате timestamp используется для того, чтобы найти разницу между датами в секундах.
К примеру, у меня есть timestamp за 1 января текущего года и timestamp за текущий момент времени. Отнимаем 1 от другого и получаем разницу между этими моментами в секундах. Делим эту разницу на 60 и получаем разницу в минутах (в 1 минуте 60 секунд). Делим еще на 60 и получаем разницу в часах. И т.д.
С помощью функции time можно получить только текущий момент времени. Чтобы получить timestamp за любую дату следует использовать функцию mktime:
Функция mktime
Функция mktime работает аналогично функции time, но в отличие от нее принимает параметры: mktime (час,минута,секунда,месяц,день,год) (внимание, месяц и день переставлены местами на американский манер). Примеры:
<?/*Функция вернет timestamp для 31.1.2028 12 часов 43 минуты 59 секунд:*/echo mktime(12,43,59,1,31,2028)?>
1832928239.
Параметры можно опускать с конца. Если мы не напишем год (последний параметр) - то автоматически возьмется текущий год, если не напишем еще и день (предпоследний параметр) - то возьмется текущий день и текущий год. И так далее:
<?/*Функция вернет timestamp для 31 января текущего года 12 часов 43 минуты 59 секунд:*/echo mktime(12,43,59,1,31)?>
1706697839.
<?/*Функция вернет timestamp для номер текущего дня января текущего года 12 часов 43 минуты 59 секунд:*/echo mktime(12,43,59,1)?>
1706093039.
<?/*Функция вернет timestamp текущего дня текущего месяца текущего года 12 часов 43 минуты 59 секунд:*/echo mktime(12,43,59)?>
1735037039.
Решим типичную задачу на time и mktime. Пусть нам нужно найти разницу в секундах между текущим моментом времени и полуднем (12 часов 0 минут 0 секунд) 1 февраля (февраль - это месяц номер 2) 2008:
<?/*Функция time() вернет текущий момент времени в формате timestamp, а mktime - за заданную дату. Отнимем результаты друг от друга и получим разницу в секундах:*/echo time()-mktime(12,0,0,2,1,2008)?>
Полученная разница в секундах будет выглядеть так: 533205071 (обновите страницу и это число поменяется).
Функция date
Функция date выводит текущие дату и время в заданном формате.
Формат задается управляющими командами (английскими буквами), при этом можно вставлять любые разделители между ними (дефис, двоеточие и т.д.).
Команды (заглавные буквы отличаются от обычных, обратите внимание!):
U - количество секунд, прошедших с 1.1.1970г. (т.е. timestamp).
z - номер дня от начала года.
Y - год, 4 цифры.
y - год, 2 цифры.
m - номер месяца (с 0 спереди).
n - номер месяца без 0 впереди.
d - номер дня в месяце, всегда 2 цифры (т.е. 1-я может быть 0).
j - номер дня в месяце без предваряющего 0.
w - день недели (0 - воскресенье, 1 - понедельник и т.д.).
h - часы в 12-часовом формате.
H - часы в 24-часовом формате.
i - минуты.
s - секунды.
L - 1, если високосный год, 0, если не високосный.
W - порядковый номер недели года.
t - количество дней в указанном месяце.
Примеры работы с date:
echo'<p>'.date('Y')//вернет год
2024.
echo'<p>'.date('y')//вернет 2 последних цифры года
24.
echo'<p>'.date('m')//вернет номер месяца
12.
echo'<p>'.date('d')//вернет номер дня в месяце
24.
echo'<p>'.date('j')//вернет номер дня в месяце (без 0 спереди)
24.
echo'<p>'.date('w')//вернет день недели (воскресенье - это 0)
2.
echo'<p>'.date('H')//вернет часы
20.
echo'<p>'.date('i')//вернет минуты
31.
echo'<p>'.date('s')//вернет секунды
11.
echo'<p>'.date('d-m-Y')//вернет формат '31-08-2018'
24-12-2024.
echo'<p>'.date('d.m.Y')//вернет формат '31.08.2018'
24.12.2024.
echo'<p>'.date('H:i:s d.m.Y')//вернет формат '12:28:58 31.06.2013'
20:31:11 24.12.2024.
2-й параметр функции date
Функция date имеет 2-й необязательный параметр, который принимает момент времени в формате timestamp. Если передать этот параметр, то функция date отформатирует не текущий момент времени, а тот, который передан 2-м параметром. Этот timestamp можно получить, к примеру, через mktime (но не обязательно):
<?echo date('d-m-Y',mktime(0,0,0,12,28,18))/*вернет '31-12-2018'*/?>
28-12-2018.
Этим можно воспользоваться, чтобы узнать номер дня недели за определенную дату. Просто передадим ее 2-м параметром с помощью функции mktime, а 1-м параметром поставим управляющий символ 'w':
<?/*Узнаем какой день недели был 31-12-2018:*/echo date('w',mktime(0,0,0,12,28,18))/*вернет '0' - воскресенье*/?>
5.
Функция strtotime
Функция strtotime - это аналог функции mktime (тоже возвращает timestamp), только в отличие от нее принимает дату в более свободном формате.
К примеру, я могу передать ей строку '2028-12-31' и функция сама разберет, где тут год, где месяц, а где день, и вернет эту дату в формате timestamp.
Что можно делать еще: можно написать так: strtotime('now'), и мы получим текущий момент времени, или так: strtotime('next Monday'), и мы получим следующий понедельник (Monday по-английски 'понедельник').
Все форматы можно посмотреть тут: gnu.org/software/tar/manual/html_chapter/tar_7.html#Date-input-formats
Примеры:
<echo'<p>'.strtotime("now")?>
1735065071.
<echo'<p>'.strtotime("10 September 2000")?>
968533200.
<echo'<p>'.strtotime("+1 day")?>
1735151471.
<echo'<p>'.strtotime("+1 week")?>
1735669871.
<echo'<p>'.strtotime("+1 week 2 days 4 hours 2 seconds")?>
1735857073.
<echo'<p>'.strtotime("next Thursday")?>
1735164000.
<echo'<p>'.strtotime("last Monday")?>
1734904800.
Следующий код вернет дату предыдущего понедельника:
<?echo date('d-m-Y',strtotime("last Monday"))?>
23-12-2024.
Как добавить или отнять дату
Чтобы отнять или прибавить к дате определенный промежуток времени, следует пользоваться комбинацией из 3 функций: date_create подготавливает дату к работе (дата должна быть в формате год-месяц-день), создавая так называемый объект date, с которым производятся дальнейшие манипуляции, date_modify прибавляет или отнимает, date_format выводит получившуюся дату в заданном формате.
Пример 1
Создать объект с датой за 2028 12 месяц 31 день, затем прибавить к ней 1 день и вывести в формате 'день.месяц.год':
<?$d=date_create('2028-12-31');date_modify($d,'1 day');echo date_format($d,'d.m.Y')?>
01.01.2029.
Пример 2
Создать объект с датой за 2028 12 месяц 31 день, затем прибавить к ней 3 дня и выведем в формате 'день.месяц.год':
<?$d=date_create('2028-12-31');date_modify($d,'3 days');echo date_format($d,'d.m.Y')?>
03.01.2029.
Пример 3
Создать объект с датой за 2028 12 месяц 31 день, затем прибавить к ней 3 дня и 1 месяц и выведем в формате 'день.месяц.год':
<?$d=date_create('2028-12-31');date_modify($d,'3 days 1 month');echo date_format($d,'d.m.Y')?>
03.02.2029.
Пример 4
Создать объект с датой за 2028 1 месяц 1 день, затем отнять от нее 1 день и вывести в формате 'день.месяц.год':
<?$d=date_create('2028-01-01');date_modify($d,'-1 day');echo date_format($d,'d.m.Y')?>
31.12.2027.
Практика
Примеры решения задач
Задача
Вывести 23.9.2031 12:58:59 в формате timestamp.
Решение: функция mktime (сентябрь - 9-й месяц):
<?echo mktime(12,58,59,9,23,2031)/*Месяц и день идут в американском порядке: поэтому '9,23,' а не '23,9'.*/?>
1947923939
Можно также воспользоваться функцией strtotime, если представить нужную дату в формате 2031-09-23 12:58:59:
<?echo strtotime('2031-09-23 12:58:59')?>
1947923939
Задача
Найти разницу между 1.9.2010 7:25:59 и текущим моментом времени в секундах.
Решение: текущий момент времени в формате timestamp получим с помощью функции time, а timestamp для заданной даты - с помощью функции mktime. Отнимем одно число от второго и получим искомую разницу:
<?echo time()-mktime(7,25,59,9,1,2010)?>
451749912
Задача. Функция date
Вывести текущую дату-время в формате '2025.12.31 12:59:59'.
Решение: воспользуемся функцией date, передав ей управляющие команды в таком порядке: год (команда Y), потом точку как символ, потом месяц (команда m), опять точку, день (команда d), час (команда H), двоеточие, минуту (команда i), секунду (команда s). Получится такая строка: 'Y.m.d H:i:s'. Подставим ее в функцию date:
<?echo date('Y.m.d H:i:s')?>
2024.12.24 20:31:11
Задача. Функция date
Вывести 1 сентября текущего года в формате '2020.09.01'.
Решение: для начала с помощью функции mktime преобразуем 1 сентября текущего года в формат timestamp. Мы это делаем для того, чтобы подставить найденное число вторым параметром в функцию date (а первым параметром для date мы укажем формат вывода).
Т.к. требуется текущий год, то последний параметр (год) для mktime мы не указываем, тогда возьмется текущий год:
<?/*Выведем timestamp 1 сентября текущего года:*/echo mktime(0,0,0,9,1)?>
1725138000
Теперь подставим найденный timestamp в функцию date:
<?echo date('Y.m.d',mktime(0,0,0,9,1))?>
2024.09.01
Задача. Функция date. Вывод дня недели текстом
Узнать, какой день недели (текстом) был 1.9.2010г.
Решение: решение аналогично предыдущей задаче, только формат вывода для функции date мы сделаем в виде 'v'. В этом случае date вернет нам число, соответствующее дню недели за заданную дату (0 - воскресенье, 1 - понедельник и так далее):
<?/*День недели числом за нужную дату:*/echo date('v',mktime(0,0,0,9,1,2010))?>
000
Кстати, если бы мы хотели узнать, какой день недели сегодня, мы бы просто не передавали 2-й параметр функции date (тогда бы взялся текущий момент времени и, соответственно, вывелась бы 'v' за текущий день).
Продолжим. Мы вывели номер дня недели, а по задаче его следует вывести текстом. Для этого составим массив дней недели $v и с его помощью выведем то, что нам нужно. Вот этот массив:
<?/*Массив дней недели:*/$v=['вс','пн','вт','ср','чт','пт','сб'];/*Выведем с его помощью, к примеру, понедельник:*/echo$v[1];/*А теперь вторник:*/echo$v[2]?>
пнвт
Совместим теперь то, что вернет нам date, с нашим массивом $v:
<?/*День недели цифрой за нужную дату:*/$d=date('v',mktime(0,0,0,9,1,2010));/*Массив дней недели:*/$v=['вс','пн','вт','ср','чт','пт','сб'];/*День недели словом:*/echo$v[$d]?>
Задача. Преобразование форматов
Дана дата в формате '31-12-2025'. С помощью функций mktime и explode перевести эту дату в формат timestamp.
Решение: разобьем строку '31-12-2025' функцией explode в массив $a:
<?$a=explode('-','31-12-2025');echo$a[0];echo', '.$a[1];echo', '.$a[2]//получим 31, 12, 2025?>
31, 12, 2025
В элементе $a[0] будет лежать день, в элементе $a[1] - месяц, в элементе $a[2] - год. Подставим эти данные в функцию mktime (напоминаю, что она принимает данные в формате 'месяц-день-год', не 'день-месяц-год'):
<?$a=explode('-','31-12-2025');echo mktime(0,0,0,$a[1],$a[0],$a[2])?>
1767132000
Задачи для решения
Timestamp: time и mktime
Для решения задач данного блока понадобятся функции time, mktime.
Вывести текущее время в формате timestamp.
Вывести 1.3.2028 в формате timestamp.
Вывести 31 декабря текущего года в формате timestamp. Скрипт должен работать независимо от года, в котором он запущен.
Найдите количество секунд, прошедших с 13:12:59 15.3.2008 до настоящего момента времени.
Найдите количество целых часов, прошедших с 7:23:48 текущего дня до настоящего момента времени.
Функция date
Для решения задач данного блока понадобится функция date.
Вывести на экран текущий год, месяц, день, час, минуту, секунду.
Вывести текущую дату-время в форматах '2025-12-31', '31.12.2025', '31.12.13', '12:59:59'.
С помощью функций mktime и date выведите 12.2.2025г. в формате '12.02.2025'.
Создать массив дней недели $v. Вывести на экран название текущего дня недели с помощью массива $v и функции date. Узнайте какой день недели был 6.6.2008, в ваш день рождения.
Создать массив месяцев $m. Вывести на экран название текущего месяца с помощью массива $m и функции date.
Найти количество дней в текущем месяце. Скрипт должен работать независимо от месяца, в котором он запущен.
Сделать поле ввода, в которое пользователь вводит год (4 цифры), а скрипт определяет високосный ли год.
Сделать форму, которая спрашивает дату в формате '31.12.2025'. С помощью функций mktime и explode перевести эту дату в формат timestamp. Узнать день недели (текстом) за введенную дату.
Сделать форму, которая спрашивает дату в формате '2025-12-31'. С помощью функций mktime и explode перевести эту дату в формат timestamp. Узнать месяц (текстом) за введенную дату.
Сравнение дат
Сделать форму, которая спрашивает 2 даты в формате '2025-12-31'. 1-ю дату записать в переменную $d, а 2-ю в $e. Сравнить, какая из введенных дат больше. Вывести ее на экран.
На strtotime
Для решения задач данного блока понадобится функция strtotime.
Дана дата в формате '2025-12-31'. С помощью функции strtotime и функции date преобразуйте ее в формат '31-12-2025'.
Сделать форму, которая спрашивает дату-время в формате '2025-12-31T12:13:59'. С помощью функции strtotime и функции date преобразовать ее в формат '12:13:59 31.12.2025'.
Прибавление и отнимание дат
Для решения задач данного блока понадобятся функции date_create, date_modify, date_format.
В переменной $date лежит дата в формате '2025-12-31'. Прибавьте к этой дате 2 дня, 1 месяц и 3 дня, 1 год. Отнимите от этой даты 3 дня.
Задачи
Узнать, сколько дней осталось до Нового Года. Скрипт должен работать в любом году.
Сделать форму с 1 полем ввода, в которое пользователь вводит год. Найти все пятницы 13-е в этом году. Результат вывести в виде массива дат.
Узнать, какой день недели был 100 дней назад.