Skip to content

Instantly share code, notes, and snippets.

@codedokode
Last active June 22, 2018 19:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codedokode/10539805 to your computer and use it in GitHub Desktop.
Save codedokode/10539805 to your computer and use it in GitHub Desktop.
Дата и время в PHP

Этот урок переехал по адресу https://github.com/codedokode/pasta/blob/master/php/datetime.md. Ниже старая, неподдерживаемая версия.


##Календари и время

В этом уроке мы поговорим о том, как работать с датой и временем в PHP. Часто в задачах нужно производить какие-то вычисления, связанные со временем, например «определить, какой день недели был 12 февраля 1956 года» или «найти дату на 3 дня позже, чем 26 февраля 2012 года». Не стоит спешить открывать редактор и писать очередной велосипед для работы с датами, давай лучше посмотрим, какие возможности уже встроены в PHP.

###Unix timestamp

В PHP функции работы со временем используют формат unix timestamp (unix time, POSIX time, таймстамп, временная метка). Таймстамп — это число секунд, которое прошло с 00:00 1 января 1970 года UTC. Поскольку секунд с той поры прошло много, таймстампы получаются довольно большие. Например, времени «12:00:00 5 января 2012 года» соответствует число 1380413489. Для дат до 1970-го года используют отрицательные числа.

Получить время в виде timestamp можно несколькими способами:

  • Функция time возвращает текущее время в виде timestamp с точностью до секунды
  • Функция mktime возвращет таймстамп для указанных значений часа, минут, секунд, дня, месяца и года. Например echo mktime(12, 0, 0, 5, 1, 2012); выведет метку времени для 12:00:00 5 января 2012
  • Функция strtotime парсит время из строки в формате вроде '2012-01-05 12:00:00' и возвращает timestamp. Она умеет разбирать дату в большом количестве форматов, подробный список которых можно найти в мануале по этой функции.

Иногда точности функции time() недостаточно. Например, для подсчета времени выполнения функции, которая выполнялась меньше одной секунды. В таких случаях можно использовать функцию microtime , которая возвращает время с высокой точностью, в виде дробного числа секунд. Обрати внимание, ее надо писать, указывая true в скобках: microtime(true) (почему? читай мануал). Вот пример измерения, сколько времени выполнялся цикл:

$start = microtime(true);
$a = 0;
for ($i = 0; $i < 1000000; $i++) {
    $a = $a + 2;
}
$end = microtime(true);
// находим разницу и переводим из секунд в миллисекунды
$timeMilliseconds = ($end - $start) * 1000; 
echo "Время выполнения: $timeMilliseconds мс\n";

Преобразовать дату из timestamp обратно в понятный человеку вид можно функцией date . Она выводит ее в указанном формате (что обозначают буковки в описании формата, написано в мануале):

$time = strtotime('2012-03-12 15:00:00');
echo "Timestamp: $time\n";
echo "Дата: " . date('Y.m.d H:i:s', $time)."\n";
echo "Еще дата: " . date('r', $time) . "\n";

Посмотреть в действии: http://ideone.com/SvvG0f. Еще с помощью функции date легко получить, какому дню недели соответствует дата: echo date('N', $time);.

Также, в PHP есть функция для проверки правильности даты. Допустим, пользователь ввел дату рождения и мы хотим проверить, а не ввел ли он случайно 31 февраля или 37 октября? Для этого можно воспользоваться функцией checkdate , которая проверяет, существуют ли указанные день, месяц и год.

Сложение и вычитание дат

Теперь разберемся, как найти дату, например, «на 3 дня позже заданной». Если пытаться вручную складывать дни, учитывать сколько дней в разных месяцах, это может затянуться надолго, а вот с timestamp все становится проще. 3 суток содержат 3 * 24 = 72 часа, каждый час 3600 секунд. Если мы теперь к исходной timestamp прибавим 3 * 24 * 3600, то мы получим timestamp даты на 3 дня позже. Осталось только вывести эту дату:

$time = strtotime('2012-02-26'); // Исходная дата
$interval = 3 * 24 * 3600; // число секунд в 3 сутках
$time += $interval;
echo "Через 3 дня будет " .date('Y-m-d', $time) ."\n";

Посмотреть в действии: http://ideone.com/ObaCYI

ООП-версия

Работать с датами можно и с помощью объектов — для этого в PHP есть класс DateTime. Все подробности о нем ты можешь прочесть в мануале. Преимущества объекта DateTime:

  • с помощью этого класса можно преобразовывать даты между разными часовыми поясами (метод setTimezone()).
  • он позволяет работать с огромными датами, которые не помещаются в обычный timestamp (на 32-битных машинах числа типа int могут быть только от -2 млрд. до +2 млрд., и они позволяет без потерь точности поддерживать даты только от 1900 до 2038 года, если нужно больше, используй DateTime).
  • Ну и наконец, любителям ООП он понравится больше

Недостатки: для простых случаев кода получается больше, чем с mkdate/strtotime.

Задачи

Ну что, с таким багажом ценных знаний для тебя совсем не составит труда решить эти задачи:

1 . Сделай программу, определяющую по дате рождения день недели и знак Зодиака. Например, указываешь дату «1999-06-25», она пишет «Ты родился 25 июня 1999 в пятницу, значит ты Рак». Соответствие между датой и знаком Зодиака легко найти в википедии: http://ru.wikipedia.org/wiki/Знаки_зодиака.

Слишком просто? Держи задачу посложнее.

2 . Дана дата из 2012 года, например, «2012-04-15». Посчитай дату, которая наступает через 5 рабочих дней после нее. «5 рабочих дней» значит, что в этот интервал не включаются выходные и праздники. Выходные — это субботы и воскресенья (кроме тех, что были превращены в рабочие дни), а список праздников легко найти в интернете: http://www.legalcalc.ru/date-calculator/nerabochie-dni-2012.htm.

В общем, решай задачки, полезно для мозгов.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment