|
Навигация
|
Главная » Sql Работа с датами и временем в PHP и MySQLИсточник: webmasters webmasters При работе с любым языком программирования, задачи, касающиеся даты и времени, часто является тривиальными и простыми. И PHP, к счастью, имеет один из самых мощных инструментов по работе с датой/временем, который поможет вам легко справиться со всеми видами задач связанных с временем: работа с Unix timestamp, форматирование дат для лучшего восприятия их человеком, работа с часовыми поясами, подсчет количества дней между сегодняшним днем и, например, вторым вторником в следующем месяце, и т.д. В этой статье вы ознакомитесь с основными временными функциями PHP (time(), mktime() и date()) и их объектно-ориентированными "коллегами", а затем познакомитесь с MySQL-датами, и мы покажем вам, как подружить их с PHP.PHP-функции даты и времени Большая часть этой статьи будет посвящена работе с Unix-временем или POSIX. Время здесь представлено в виде количества секунд, прошедших с полуночи 1 января 1970 года, UTC. Если вы заинтересованы в полной истории времени Unix, то ознакомьтесь со статьей Unix time в Википедии.UTC, известное также под именем Coordinated Universal Time, также известное как GMT, а иногда и Zulu time, это время нулевого градуса долготы. Все остальные часовые пояса в мире являются положительным или отрицательным смещением относительно этого времени. UTC и Unix время сделает вашу жизнь проще, когда вам придется иметь дело с часовыми поясами. Я расскажу об этом чуть позже, а пока рассмотрим некоторые функции для работы со временем. Получение текущего времени Unix Функция time() без аргументов возвращает количество секунд, прошедших с начала эпохи Unix. Чтобы проиллюстрировать это я буду использовать интерактивную консоль PHP. sean@beerhaus:~$ php -a Если вам нужен массив для работы с Unix-временем, используйте функцию getdate(). Она принимает необязательный аргумент Unix timestamp, если его нет, то по умолчанию это значение функции time().php > print time(); 1324402770 php > $unixTime = time(); php > print_r(getdate($unixTime)); Array ( [seconds] => 48 [minutes] => 54 [hours] => 12 [mday] => 20 [wday] => 2 [mon] => 12 [year] => 2011 [yday] => 353 [weekday] => Tuesday [month] => December [0] => 1324403688 ) Форматирование времени Unix Unix-время может быть легко отформатировано в почти любую строку, чтобы человек мог его прочитать. Функция date() используется для форматирования Unix timestamp в понятную для человека строку и принимает аргументы форматирования и необязательный аргумент "время". Если необязательный аргумент "время" не указан, используется значение функции time(), т.е. текущее время.php > print date("r", $unixTime); Аргумент "r" при форматировании строки возвращает время в формате RFC 2822. Конечно, Вы можете использовать другие спецификаторы, чтобы определить свои собственные форматы.Tue, 20 Dec 2011 12:54:48 -0500 php > print date("m/d/y h:i:s a", $unixTime); Полный список допустимых значений для форматирования, смотрите на странице функции date() в документации по PHP. Функция становится еще более полезной, когда используется в сочетании с функциями mktime() и strtotime(), это вы увидите в дальнейших примерах.12/20/11 12:54:48 pm php > print date("m/d/y h:i:s a"); 12/20/11 01:12:11 pm php > print date("jS \of F Y", $unixTime); 20th of December 2011 Создание Unix-времени от заданного времениФункция mktime() используется, чтобы создать метку времени на основе списка значений, которые соответствуют каждой части даты (секунды, минуты, часы, год и т.д.). Она принимает ряд целочисленных аргументов для установки каждой части даты в следующем порядке:mktime(часы, минуты, секунды, месяц, день, год, isDST) Вы можете установить isDST равный 1, если используется летнее время, в противном случае 0, или -1, если это неизвестно (значение по умолчанию).php > print date("r", mktime(12, 0, 0, 1, 20, 1987)); Вы можете видеть, что mktime() может быть очень полезна при работе с запросами к базе данных, которые используют диапазоны дат определенные пользователем. Например, если вы храните timestamp в виде целых чисел (Unix время) в MySQL, очень легко настроить общий временной диапазон для запроса.Tue, 20 Jan 1987 12:00:00 -0500 php > print date("r", mktime(0, 0, 0, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 00:00:00 -0500 php > print date("r", mktime(23, 59, 59, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 23:59:59 -0500 $startTime = mktime(0, 0, 0, 1, 1, date("y")); $endTime = mktime(0, 0, 0, date("m"), date("d"), date("y")); ?> Преобразование английских дат в Unix времяПочти магическая функция strtotime() принимает строку даты/времени в качестве первого аргумента, и Unix timestamp, чтобы использовать в качестве основы для преобразования. Смотрите документацию для получения информации о допустимых форматах даты.php > print strtotime("now"); 1324407707 php > print date("r", strtotime("now")); Tue, 20 Dec 2011 14:01:51 -0500 php > print strtotime("+1 week"); 1325012569 php > print date("r", strtotime("+1 week")); Tue, 27 Dec 2011 14:03:03 -0500 php > print date("r", strtotime("next month")); Fri, 20 Jan 2012 14:04:20 -0500 php > print date("r", strtotime("next month", mktime(0, 0, 0))); Fri, 20 Jan 2012 00:00:00 -0500 php > print date("r", strtotime("next month", mktime(0, 0, 0, 1, 31))); Thu, 03 Mar 2011 00:00:00 -0500 Объекты DateTime и DateTimeZone Объект PHP DateTime является объектно-ориентированным подходом к работе с датами и часовыми поясами. Конструктор принимает строковое представление времени, очень похоже на функцию strtotime() , о которой говорилось выше. Значение по умолчанию, если аргумент не указан, " now " (сейчас).php > $dt = new DateTime("now"); Метод format() объекта DateTime работает так же, как функция date(), и принимает все те же символы форматирования. Объект DateTime также имеет несколько полезных констант, которые могут быть переданы в метод format().php > print $dt->format("r"); Tue, 20 Dec 2011 16:28:32 -0500 php > $dt = new DateTime("December 31 1999 12:12:12 EST"); php > print $dt->format("r"); Fri, 31 Dec 1999 12:12:12 -0500 php > print $dt->format(DATE_ATOM); Полный список констант можно найти на странице документации DateTime.2011-12-20T15:57:45-05:00 php > print $dt->format(DATE_ISO8601); 2011-12-20T15:57:45-0500 php > print $dt->format(DATE_RFC822); Tue, 20 Dec 11 15:57:45 -0500 php > print $dt->format(DATE_RSS); Tue, 20 Dec 2011 15:57:45 -0500 Поскольку мы будем работать с часовыми поясами, давайте установим часовой пояс по умолчанию. В файле конфигурации php.ini (у меня есть один для CLI и один для Apache) найдите раздел, который выглядит следующим образом: [Date] Если значение не указано для date.timezone, PHP будет пытаться сделать все возможное, чтобы определить часовой пояс системы которая установлена на вашем сервере. Вы можете проверить, какое значения использует PHP при помощи функции date_default_timezone_get().; Defines the default timezone used by the date functions ; http://php.net/date.timezone ; date.timezone = php > print date_default_timezone_get(); Давайте установим временную зону сервера на время UTC (date.timezone = UTC) и сохраним файл конфигурации. Вы должны перезагрузить Apache или CLI, чтобы увидеть изменения.America/New_York Объект DateTime включает в себя внутренний экземпляр класса DateTimeZone для отслеживания часовых поясов. Когда вы создаете новый экземпляр DateTime, DateTimeZone должен быть установлен по умолчанию как указано в php.ini. php > $dt = new DateTime(); Полный список допустимых имен часовых поясов можете найти на соответствующей странице документации.php > print $dt->getTimeZone()->getName(); UTC Теперь вы можете увидеть разницу во времени, между двумя объектами DateTime, созданных для разных часовых поясов. Например, вот пример, который преобразует время из UTC в America/New_York(EST). php > $dt = new DateTime(); Обратите внимание на смещение -0500 в декабре месяце. Если вы измените значение времени на летний день, например, 1 июля, то увидите, что он "знает" летнее время (EDT).php > print $dt->format("r"); Tue, 20 Dec 2011 20:57:45 +0000 php > $tz = new DateTimeZone("America/New_York"); php > $dt->setTimezone($tz); php > print $dt->gt;format("r"); Tue, 20 Dec 2011 15:57:45 -0500 php > $tz = new DateTimeZone("America/New_York"); php > $july = new DateTime("7/1/2011"); php > $july->setTimezone($tz); php > print $july->>format("r"); Thu, 30 Jun 2011 20:00:00 -0400 Использование даты в MySQL и PHP Если вы использовали MySQL на любом уровне, вы, вероятно, обратили внимание на тип данных DATETIME. Он выглядит как дата, и если бы вы сказали, что это дата, то вы были бы правы. Но поскольку вы выбираете его из MySQL, в PHP эта дата уже представляет собой строку, которая выглядит как дата.* Да, я знаю, что MySQL имеет множество функций форматирования даты. Почему же мы хотим отформатировать дату прямо из базы данных в таком случае? У нас может быть несколько различных преобразований и форматов, которые мы хотим применить. И лучше всего форматировать дату только тогда, когда человек собирается её увидеть. $db = new PDO("mysql:host=localhost;dbname=testdb", "dbuser", "dbpassword"); $result = $db->query("SELECT dt_date FROM some_table"); Выполнив этот простой скрипт, вы можете видеть, что все данные с поля DATETIME отформатированны в строку без информации о часовом поясе.while ($row = $result->fetch(PDO::FETCH_ASSOC)) { print_r($row); var_dump($row["dt_date"]); } $result->closeCursor(); Array Значение DATETIME - это время локального сервера MySQL в любом часовом поясе. Если все, что вы делаете, касается только одного сервера в одном часовом поясе, DATETIME, вероятно, подходит для большинства ваших потребностей, и я очень завидую вам.( [dt_date] => 2012-01-16 13:03:49 ) string(19) "2012-01-16 13:03:49" Итак, как вам справляться с датами и часовыми поясами в PHP и MySQL? Сохранять даты как Unix timestamps. Вы уже знаете, что время Unix - это количество секунд, прошедших с 1 января 1970 года в UTC, так что это дает вам постоянный часовой пояс для работы, и, надеюсь, вы заметили, что многие PHP функции даты/времени основываются на Unix timestamps. При работе с MySQL, я обычно создаю столбец таблицы, который будет хранить даты как INTEGER UNSIGNED. При вставке даты можно использовать функции time() из PHP или UNIX_TIMESTAMP() из MySQL. mysql> SELECT UNIX_TIMESTAMP(); Если вы хотите использовать MySQL для форматирования даты, то вы можете. Но время будет соответствовать часовому поясу сервера и я советую вам воздержаться от любого типа форматирования, то тех пока вы не находитесь в шаблоне/на уровне представления в вашем веб-приложении и готовы, чтобы человеческий глаз увидел это.+------------------+ / UNIX_TIMESTAMP() / +------------------+ / 1326738918 / +------------------+ mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP()); В любом приложении, как правило, есть таблица, которая отслеживает пользователей, пользовательские настройки часового пояса, которые затем будут считаны в значение $_SESSION. Если у вас есть запись в сессии, вроде этой:+---------------------------------+ / FROM_UNIXTIME(UNIX_TIMESTAMP()) / +---------------------------------+ / 2012-01-16 13:37:16 / +---------------------------------+ $_SESSION["userTZ"] => "America/Chicago" Вы можете легко конвертировать сохраненный Unix timestamp (UTC) в любую дату в часовом поясе конкретного пользователя.$result = $db->query("SELECT int_date FROM some_table"); Это вернет дату "Mon, 16 Jan 2012 12:03:49 -0600". Где -0600 говорит нам, что это 6 часов от временной зоны UTC, которая имеет смещение 0.while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $dt = new DateTime(); $tz = new DateTimeZone($_SESSION["userTZ"]); $dt->setTimestamp($row["int_date"]); $dt->setTimezone($tz); print $dt->format("r"); } Если бы мы изменили часовой пояс на America/Los_Angeles, то в результате дата выглядела бы так: Mon, 16 Jan 2012 10:03:49 -0800 А America/New_York вернет:Mon, 16 Jan 2012 13:03:49 -0500 Заключение Работа с датами и временными зонами является частью задач многих программистов, но вам не о чем беспокоиться, если у вас есть PHP, надежный и простой в использовании инструмент для работы с датами.Вы видели, как легко получить метку времени, как отформатировать дату в любой формат, как преобразовать английское представление даты в метку времени (timestamp) и как преобразовывать время между часовыми поясами. Если выделить две основных темы из статьи, то это: 1) Unix время и 2) UTC, как основная временная зона для всех дат при работе с PHP и MySQL. Идея отсчитывать всё время по UTC относится не только к PHP и MySQL, это считается хорошей практикой в любом языке. Перевод статьи с phpmaster.com Новое решение по интеграции с базами данных для SQLBase. Сертификат MySQL 5.0 Developer (CMDEV). IBM Rational ClearQuest (FAQ). Выполнение триггеров в определенном порядке (исходники). Магия бизнес-аналитики. Главная » Sql |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |