Pers.narod.ru. PHP. Статьи. Хранить ли дату как дату :) |
Казалось бы, самый естественный путь для работы с датой и временем на PHP/MySQL - сохранять в базе данных MySQL
значение типа "дата и время" - для этого есть тип столбца datetime
:
CREATE DATABASE IF NOT EXISTS datetime; USE datetime; DROP TABLE IF EXISTS datetime; CREATE TABLE datetime ( date datetime ); INSERT INTO datetime (date) VALUES ( '2011-06-02 18:00:00' ); INSERT INTO datetime (date) VALUES ( '2011-05-03 17:00:00' );
По умолчанию даты хранятся в MySQL в формате год-месяц-день, за это отвечают установки
date_format %Y-%m-%d datetime_format %Y-%m-%d %H:%i:%s
В типовой ситуации мы хотим выбрать некие записи и вывести их по убыванию (реже возрастанию) даты:
<?php $d=mysql_connect('localhost', 'root', 'root') or die ("Соединение не установлено!"); mysql_select_db('datetime',$d); $r=mysql_query('select * from datetime order by date desc') or die ("Ошибка запроса!"); while ($date = mysql_fetch_array($r)) { echo '<p>'.$date['date'].'</p>'; } ?>
Здесь напечатается:
2011-06-02 18:00:00 2011-05-03 17:00:00
То есть, всё верно, но отображение даты неудобно. Можно его преобразовывать функциями PHP date
и
strtotime
перед выводом:
<?php $d=mysql_connect('localhost', 'root', 'root') or die ("Соединение не установлено!"); mysql_select_db('datetime',$d); $r=mysql_query('select * from datetime order by date desc') or die ("Ошибка запроса!"); while ($date = mysql_fetch_array($r)) { echo '<p>'.date("d.m.Y, H:s",strtotime($date['date'])).'</p>'; } ?>
Получилось вот что:
02.06.2011, 18:00 03.05.2011, 17:00
- формат даты/времени привычный и сортировка правильная.
Ещё один путь - использовать встроенную прямо в MySQL функцию date_format
:
<?php $d=mysql_connect('localhost', 'root', 'root') or die ("Соединение не установлено!"); mysql_select_db('datetime',$d); $r=mysql_query('select *,date_format(date,"%Y.%m.%d, %H:%S") as date1 from datetime order by date1 desc') or die ("Ошибка запроса!"); while ($date = mysql_fetch_array($r)) { echo '<p>'.$date['date1'].'</p>'; } ?>
Этот тест вывел
2011-06-02 18:00:00 2011-05-03 17:00:00
то есть, опять мы получили "день-месяц-год", а замена формата на
date_format(date,"%d.%m.%Y, %H:%S")
, очевидно, приведёт к неправильной сортировке -
3 мая окажется позже (выше в списке), чем 2 июня!
Чтобы не решать все эти проблемы с форматами, я просто всегда храню дату как длинное целое:
CREATE DATABASE IF NOT EXISTS datetime; USE datetime; DROP TABLE IF EXISTS datetime; CREATE TABLE datetime ( date bigint default '0' ); INSERT INTO datetime (date) VALUES ( UNIX_TIMESTAMP('2011-06-02 18:00:00') ); INSERT INTO datetime (date) VALUES ( UNIX_TIMESTAMP('2011-05-03 17:00:00') );
А при выводе форматирую метку времени так, как в данный момент удобно:
<?php $d=mysql_connect('localhost', 'root', 'root') or die ("Соединение не установлено!"); mysql_select_db('datetime',$d); $r=mysql_query('select * from datetime order by date desc') or die ("Ошибка запроса!"); while ($date = mysql_fetch_array($r)) { echo '<p>'.date("d.m.Y, H:s",$date['date']).'</p>'; } ?>
Все даты на месте, вывод примера правильный:
02.06.2011, 18:00 03.05.2011, 17:00
Метка времени Unix или timestamp - это число секунд, прошедших от начала так называемой
"эпохи Unix" (The Unix Epoch, началась 1 января 1970, 00:00:00 GMT) до текущего времени.
Наиболее полезные стандартные функции PHP для работы с датой и временем - date
, time
, strftime
, mktime
,
естественным образом работают как раз с метками времени Unix.
Сообщение об ошибке date.timezone в PHP последних версий |
И ещё одно замечание насчёт вывода дат. PHP последних версий довольно строг в отношении вывода сообщений об ошибках и предупреждений, скорее всего, в Вашем файле настроек стоит
error_reporting = E_ALL & ~E_DEPRECATED
Это, в частности, означает, что вывод предупреждений (Warnings, директива E_WARNING
) не подавлен, поэтому при ненастроенном "часовом поясе по умолчанию" каждый вызов функции date(...)
, в котором не подавлен вывод ошибок (@date(...)
), да и другие собщения об ошибках
будут сопровождаться предупреждением вида
Warning: Unknown: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'UTC' for '6.0/no DST' instead in [ИМЯ_ФАЙЛА] on line [НОМЕР_СТРОКИ]
Просто поставьте в активном файле php.ini
настройку date.timezone
в секции [DATE]
,
например:
[Date] date.timezone = "Europe/Moscow"
или просто
[Date]
date.timezone = 6
для часового пояса GMT+6 - если лень искать в списках свой город. - не надо так делать, всё-таки значение зоны из спецификации; а вот без кавычек можно:
[Date] date.timezone = Europe/Moscow
Список допустимых временных зон PHP
Узнать, откуда подключён файл настроек php.ini, можно, выполнив это:
<?php phpinfo(); ?>
Ответ содержится в первой таблице в строке Loaded Configuration File
Начиная с PHP 5.1.0 можно установить временную зону по умолчанию для всех функций скрипта и без правки файла php.ini
- для этого достаточно вызвать метод date_default_timezone_set
с параметром-идентификатором временной зоны (см. ссылку выше).
Например, для Новосибирска делаем так:
date_default_timezone_set ('Asia/Novosibirsk');
Ещё лучше предусмотреть в скрипте соответствующую настройку.
Ещё я делаю так где-нибудь в начале скрипта (лучше всего в коде, выполняющемся 1 раз):
@date_default_timezone_set (date_default_timezone_get()); //Чтоб дальше не ругался предупреждениями на date()
гостевая; E-mail |