Разработчику. Сборник рецептов PHP
Задавайте вопросы

Дата и время

Вернуться назад

Введение

На первый взгляд, отображение и обработка дат и времени кажется простой задачей, но иногда она усложняется в зависимости от многочисленности ваших пользователей и сложности их требований. Рассеяны ли пользователи по более чем одной временной зоне? Вероятно, да, только если вы не строите интранет или сайт с очень специфической географией аудитории. Смутит ли вашу аудиторию метка даты/времени вида «2002-07-20 14:56:34 EDT» или она предпочтет знакомое представление, например «20 июля 2002 года, 14:56». Определить количество часов в промежутке между 10 часами сегодняшнего дня и 19 часами завтрашнего довольно легко. А между 3-мя часами сегодняшнего утра и полуднем первого дня следующего месяца?

Определение разности между датами рассмотрено в рецептах описанных ниже.

Эти вычисления и обработка становятся еще более раздражающими из-за перехода на летнее время (Daylight Saving Time, DST). При этом появляется время, которое никогда не наступает (в большинстве американских штатов это время с 2 до 3 часов ночи в первое воскресенье апреля), и время, которое наступает дважды (в большинстве американских штатов это время с 1 до 2 часов ночи в последнее воскресенье октября). Некоторые из ваших пользователей живут в регионах, в которых соблюдается DST, а некоторые нет. Способы работы с часовыми поясами и DST рассмотрены в рецептах ниже.

Два соглашения делают программную обработку времени значительно более простой. Во-первых, в качестве внутреннего представления времени следует использовать согласованное универсальное время (UTC,Coordinated Universal Time), известное еще как GMT, Greenwich MeanTime – среднее время по Гринвичу) – патриарх семейства часовых поясов, не учитывающий DST (переход на летнее время). Это часовой пояс нулевого градуса долготы, а все остальные часовые пояса определяются как смещение (положительное или отрицательное) относительно него.

Во-вторых, время надо рассматривать не как массив различных значений для месяца, дня, минуты, секунды и т. д., а как количество секунд, истекшее с начала эпохи UNIX: полночи 1 января 1970 года (конечно, UTC). Это значительно упрощает вычисление интервалов времени, и PHP предоставляет множество функций, помогающих легко переходить от меток времени UNIX к понятным человеку представлениям времени и обратно.

Функция mktime() вырабатывает метку времени UNIX из данного набора компонентов времени, тогда как функция date() принимает метку времени, а возвращает форматированную строку даты и времени. Посредством этих функций можно, например, определить, на какой день недели пришелся новогодний праздник в 1986 году:

$stamp = mktime(0,0,0,1,1,1986);
print date('l',$stamp);

Wednesday

В данном случае функция mktime() возвращает метку времени UNIX в полночь 1 января 1986 года. Символ форматирования l в функции date() означает, что она вернет полное название дня недели, соответствующее данной метке времени. Многие символы форматирования, доступные в функции date(), подробно описаны ддалее...

В этой книге фраза метка времени UNIX относится к количеству секунд, истекших с начала эпохи UNIX. Части времени (или части да" ты или части времени и даты) означают массив или группу компонентов времени и даты, таких как день, месяц, год, час, минута и секунда. Форматированная строка времени (или форматированная строка даты и т. д.) означает строку, содержащую некоторым образом сгруппированные части времени и даты, например «2002-03-12», «Wednesday, 11:23 A.M.», или «February 25».

Если вы использовали метку времени UNIX в качестве внутреннего представления времени, то смогли избежать любых последствий, связанных с проблемой 2000 года, поскольку разность между 946702799 (1999-12-31 23:59:59 UTC) и 946702800 (2000-01-01 00:00:00 UTC) трактуется точно так же, как и разность между любыми двумя метками даты/времени. Однако можно столкнуться с проблемой 2038 года. 19 января 2038 года в 3:14:07 A.M. (UTC) – это 2147483647 секунд после полуночи 1 января 1970 года. Что особенного в 2147483647? Это 231 – 1, максимально возможное целое число со знаком в 32-битном представлении (32-й бит представляет знак.)

Решение? Выберите время до 19 января 2038 года для покупки оборудования, которое, скажем, использует 64 бита для хранения значений времени. Таким образом, вы купите еще примерно 292 триллиона лет. (Всего 39 бит позволили бы вам протянуть примерно до 10680 года и удачно пережить потрясения, вызванные ошибкой десятитысячного года, которая сравняла с землей фабрики погоды и станции сверхсветовых путешествий.)

2038 год может показаться сейчас слишком далеким, но таким же далеким казался и 2000-й год программистам на КОБОЛе в 1950-х и 1960-х годах. Не повторяйте этой ошибки!

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования


Рейтинг Сайтов ДОСКИ.РУ