Работа с датой и временем: Введение
Примечание: эта статья является почти полностью теоретической и адресована тем, кто только начинает разбираться в том, как работать с датами и временем в PHP. Здесь вы не найдете примеров кода - они будут в других статьях этого цикла.
Работа с датой и временем - достаточно распространенная задача, а потому часто возникает ошибочное впечатление, что "Там всё просто...".
Обычно это впечатление сохраняется ровно до тех пор, пока перед нами не встанут реальные практические задачи.
Здесь в ход идет целый ряд факторов:
- Ваши пользователи наверняка живут в разных часовых поясах;
- Ваши пользователи не очень любят даты вида "2015-07-20"; скорее всего, они предпочли бы видеть что-то вроде: "Суббота, 20 июля 2015";
- Вычислить количество часов между 10:00 и 19:00 сегодняшнего дня несложно. А как насчет интервала между 15:00 сегодняшнего дня и полуднем первого дня следующего месяца?
- Различные манипуляции с датами не упрощает и то, что во многих странах есть так называемое "летнее" и "зимнее" время. Это приводит к "временным парадоксам", вроде того, что возникают "несуществующие" моменты времени (при переводе стрелок вперед) и, наоборот, отрезки времени, которые "существуют дважды" (при переводе стрелок назад).
И со всем этим безобразием (и многими другими) приходится иметь дело бедным PHP-программистам:)
Однако не все так плохо, потому что работа со временем в программах заметно упрощается двумя конвенциями, т.е. условными соглашениями.
1. Первое соглашение заключается в том, что во внутреннем представлении программы работают с так называемым "Всемирным Скоординированным Временем (UTC, Coordinated Universal Time — также используется сокращение GMT от «Greenwich Mean Time») — своего рода «патриархом» семейства часовых поясов без летнего времени.
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
Суть в том, что этот часовой пояс находится на долготе 0 градусов (которая, как было условлено, проходит через Лондон) а все остальные часовые пояса выражаются в смещениях от него (положительных или отрицательных).
К востоку мы имеем смещение в плюс, к западу - в минус.
2. Второй принципиальный момент заключается в том, что время рассматривается не как совокупность привычных нам понятий, вроде года, месяца, дня недели, минут и секунд.
Для удобства манипулирования временем оно рассматривается как количество секунд, прошедших от начала так называемой "эпохи Unix" - полуночи 1 января 1970 года. Знаю, если вы новичок и впервые об этом слышите, то все это может показаться безумием:
- время в секундах?
- какая еще "эпоха Unix"?
- зачем все так усложнять?
- и т.д., и т.п.
У меня у самого было много вопросов, когда я впервые об этом узнал.
Однако все это было сделано не случайно и является не таким уж плохим решением - во всяком случае, к этому можно быстро привыкнуть.
Итак, такое представление течения времени существенно упрощает вычисление интервалов, и в PHP существует много функций, помогающих легко переходить между количеством секунд от начала эпохи (так называемым timestamp - "временной меткой") и представлением, понятным для человека.
Так, существуют две противоположные по своей сути функции. Одна из них - mktime(), - создает временные метки из заданного набора привычных нам компонентов (а-ля год, месяц, день, час и т.д.).
Другая же - date(), наоборот, для известной временной метки возвращает отформатированную строку, т.е. дату и время, записанные в удобном для человека виде.
В коде ниже эти функции используются для определения дня недели, на который пришелся Новый год в 1986 году.
$stamp = mktime(0,0,0,1,1,1986); print date('l',$stamp);
Результат выполнения будет следующим:
Wednesday
В коде выше функция mktime() возвращает временную метку для полуночи 1 января 1986 года. Форматный же символ "l", передаваемый функции date, сообщает ей что нужно вернуть полное название дня недели, соответствующего заданной временной метке.
Другие форматные символы, поддерживаемые date(), мы как-нибудь разберем отдельно.
Следующий важный момент, который позволит нам упростить обработку даты и времени в коде - это присвоение конфигурационной переменной date.timezone соответствующего часового пояса (как вариант можно вызывать функцию date_default_timezone_set() перед выполнением каких-либо операций с временем или датой).
— Разгрузит мастера, специалиста или компанию;
— Позволит гибко управлять расписанием и загрузкой;
— Разошлет оповещения о новых услугах или акциях;
— Позволит принять оплату на карту/кошелек/счет;
— Позволит записываться на групповые и персональные посещения;
— Поможет получить от клиента отзывы о визите к вам;
— Включает в себя сервис чаевых.
Для новых пользователей первый месяц бесплатно. Зарегистрироваться в сервисе
Наконец, чтобы в вычислениях с датой всегда использовалось время UTC, нужно присвоить date.timezone значение UTC. Далее уже можно будет организовать вывод времени и даты в формате, соответствующем часовому поясу и местонахождению пользователя.
Еще одним интересным моментом является то, что использование временных меток позволило в свое время избежать "проблемы 200 года" (можете погуглить вопрос, если вы совсем юны и не знаете, о чем речь), ведь разность между 946702799 (31 декабря 1999 г., 23:59:59 UTC) и 946702800 (1 января 2000 г., 00:00:00 UTC) интерпретируется так же, как разность между любыми другими временными метками.
Впрочем, пока приходится учитывать потенциальную «проблему 2038 года». Момент времени 3:14:07 19 января 2038 года (UTC) наступит через 2147483647 секунд от полуночи 1 января 1970 года. Чем же так примечательно число 2147483647? Это 2 в 31 степени минус единица, т.е. наибольшее целое значение при использовании 32-разрядного представления знаковых целых (32-й разряд используется для знака).
Функции PHP, использующие встроенную библиотеку работы с временем (такие, как date(), mktime() и методы класса DateTime), хранят временные метки в виде 64-разрядных целых чисел. Диапазон представимых дат в этом случае расширяется до 600 миллиардов лет (поэтому нам с вами точно хватит, верно?)
По этой причине (а также для простоты) в других материалах, посвященных этой теме, для работы со временем и датой мы будем использовать для обеспечения необходимой функциональности не strftime() и gmstrftime(), а PHP-функции date(), mktime() и ряд других.
На этом я заканчиваю данное мини-введение в тему чисел и дат. Если вы были совсем новичком, то, полагаю, смогли найти для себя пару полезных моментов и получить общее понимание вопроса.
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также: