Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с датами различных форматов, предлагаю решение 
:(
    Опции темы
Bikutoru
Дата 28.1.2006, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: 3
Всего: 22



Работая с PHP, нередко приходится приходится обрабатывать даты различного формата. PHP содержит встроенную функцию date, позволяющую отформатировать метку времени так, как вам хочется, а вот средств для осуществления обратной операции мною замечено не было.

Чтобы было более понятно приведу простой пример. Допустим, нам нужно сделать небольшую админку для регистрации клиентов, в которой нужно указать дату начала и дату окончания действия регистрации и записать всю информацию в базу данных. Вот тут-то мы и сталкиваемся с проблемой разных форматов дат. Не секрет, что для Европы наиболее привычный формат даты - ДД.ММ.ГГГГ, в то время, как для записи даты в MySQL требуется иной формат (например ГГГГ-ММ-ДД). Переформатировать дату - задача несложная. Это можно сделать, например, так:
Код

function reformatDateToMySQLFormat($date) 
{
    if (!preg_match('/^(\d\d)-(\d\d)-(\d{4})$/', $date, $match))
        return false;
    
    return date('Y-m-d', mktime(0, 0, 0, $match[2], $match[1], $match[3]));
}

print reformatDateToMySQLFormat("31-12-2005");

"Так в чем же проблема?" - спросите вы. Проблема в том, что форматы "входных" дат в одном проекте или в разных могут различаться и поэтому приходится писать несколько различных функций, осуществляющих переформатирование дат к единому формату, что, прямо скажем, задача довольно скучная и рутинная. Поэтому я предлагаю средство, которое позволяет переформатировать даты из
любого формата в любой.
Примечание: конечно же, дату можно получать извне по принципу "один компонент - одно поле ввода", но "склеивание" компонентов при таком варианте, на мой взгляд, тоже нельзя назвать творческой работой.

Итак класс DateFormatter.
Для создания его экземпляра следует воспользоваться конструктором, принимающим на вход один аргумент - формат даты. Каждый компонент даты именуется буквой латинского алфавита:
y для года;
m для месяца;
d для дня;
h для часа;
i для минуты;
s для секунды.
Как видите, изобретать велосипед я не стал и воспользовал мнемоники из стандартной функции date. Формат даты - это строка, представляющая собой шаблон даты. Например форматы "dd.mm.yyyy" и "yyyy-mm-dd" соответствуют двум форматам
приведенным ранее (ДД.ММ.ГГГГ и ГГГГ-ММ-ДД, соответственно).

После задания шаблона, экземпляр класса DateFormatter становится способным "понимать" даты указанного формата. Небольшой примерчик:
Код

require_once "DateFormatter.php";

$df =& new DateFormatter("dd.mm.yyyy hh:ii:ss");
$time = $df->getTimestamp("28.01.2006 12:35:00");
if ($time != -1) {
    print date("Y-m-d H:i:s", $time) . "<br>\n";
}

Основные методы класса DateFormatter? используемые для получения времени и его компонентов:
getTimestamp($dateString) - возвращает метку времени, соответствующую дате, заданной в $dateString;
getYear($dateString) - возвращает значение года даты, заданной в $dateString;
getMonth($dateString) - возвращает значение месяца даты, заданной в $dateString;
getDay($dateString) - возвращает значение дня даты, заданной в $dateString;
getHours($dateString) - возвращает значение часа даты, заданной в $dateString;
getMinutes($dateString) - возвращает значение минут даты, заданной в $dateString;
getSeconds($dateString) - возвращает значение секунд даты, заданной в $dateString.

В принципе, на этом можно и остановиться, но мне показалаось, что это решение можно улучшить. Посмотрите на пример кода, приведенный чуть ранее. Перевод даты из одного формата в другой требует от пользователя, чтобы он узнавал метку времени и передавал ее в функцию date. Мне показалось, что это не совсем правильно, именно поэтому я реализовал еще две функции:
format($time) - возвращает отформатированную в соответствии с заданным форматом дату, заданную меткой времени $time;reformatTo($dateString, $newFormatter) - возвращает отформатированную в соответствии с форматом, указанным в $newFormatter, дату, заданную строкой $dateString.

C учетом этих двух функций переформатирование даты из одного формата в другой будет иметь следующий вид:
Код

require_once "DateFormatter.php";

$df   =& new DateFormatter("dd.mm.yyyy hh:ii:ss");
$ndf =& new DateFormatter("dd/mm/yy hh:ii:ss");

print $df->reformatTo("31.12.2005 23:59:59", $ndf);

Не знаю как вам, но мне такое решение определенно нравится больше.

Ну вот и все, свое решение я описал, как мне кажется, довольно подробно. Если кому-то оно пригодится, буду только рад. Если есть какие-нибудь вопросы или предложения, высказывайте.

Это сообщение отредактировал(а) Bikutoru - 31.1.2006, 17:27

Присоединённый файл ( Кол-во скачиваний: 80 )
Присоединённый файл  DateFormatter.php 7,08 Kb


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
Mal Hack
Дата 28.1.2006, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 16
Всего: 261



Цитата
array strptime ( string timestamp, string format )


Универсального решения конечно нет, но все же..
Плюс, обычно в своих системах разрабочики используют 1-2 формата дат, для переформирования которых уже есть свои заготовки.

В догонку: http://vingrad.ru/PHP-SRC-002931


Это сообщение отредактировал(а) Mal Hack - 28.1.2006, 14:18
PM ICQ   Вверх
Bikutoru
Дата 28.1.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: 3
Всего: 22



strptime это хорошая функция, но у нее как минимум один недостаток
Цитата(http://ru.php.net/manual/en/function.strptime.php)

PHP 5 >= 5.1.0RC1

А ведь кое-кто еще работает с четверкой (я например).

Цитата(Mal Hack @ 28.1.2006, 15:15 Найти цитируемый пост)

в своих системах разрабочики используют 1-2 формата дат, для переформирования которых уже есть свои заготовки

Согласен, но у меня бывали случаи, когда клиенты говорят что-то вроде "А нельзя kb на этой странице сделать, чтобы время показывалось как ...". Переписывать имеющуюся функцию переформатирования нельзя, т.к. она может использоваться и в других местах, поэтому приходится писать новую методом "copy&paste". А с помощью моего класса мы просто исправляем с скрипте строку формата, использующуюся при создании экземпляра класса, и все готово smile



--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
IZ@TOP
Дата 28.1.2006, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 2
Всего: 73



Цитата(Bikutoru @ 28.1.2006, 18:44 Найти цитируемый пост)

strptime это хорошая функция, но у нее как минимум один недостаток

Хэй... а как же эта http://ru.php.net/manual/ru/function.strtotime.php ???


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Bikutoru
Дата 31.1.2006, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: 3
Всего: 22



IZ@TOP, позволь отвечу несколькими строчками кода:
Код

<?php

print date('Y-m-d', strtotime('31.01.2006'));
//Получаем warning

require_once 'DateFormatter.php';
$df =& new DateFormatter("dd.mm.yyyy");
print date('Y-m-d', $df->getTimestamp('31.01.2006'));
// Получаем 2006-01-31

?>

Добавлено @ 17:29
Кстати, если кому-нибудь интересно, я заменил файл на чуть-чуть исправленную версию.


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
Ciber SLasH
Дата 31.1.2006, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



strtotime принимает строку с GNU Date Input Formats форматом даты.
Т.е. нуно так: strtotime('31/01/2006')

Это сообщение отредактировал(а) Ciber SLasH - 31.1.2006, 21:07
PM   Вверх
Bikutoru
Дата 1.2.2006, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: 3
Всего: 22



Ciber SLasH, а ты первый пост читал? Мой класс для того и нужен, чтобы разный формат дат можно было обрабатывать...
Добавлено @ 11:10
...что и демонстрируется тем фрагментом кода.


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
Alone
Дата 2.3.2006, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

Репутация: нет
Всего: 6



Мои 5 копеек:

Для хранения даты в ЛЮБОЙ БД используем поле Integer и храним там дату в виде unix timestamp.
Из таймстампа в пхп можно привести К ЛЮБОМУ НУЖНОМУ ВАМ ВИДУ с помощью date("<format string>", $tstamp).

А вот для реверса из строки в исходный интегер - этот класс как раз и может быть полезен.


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
CyClon
Дата 3.3.2006, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: 1
Всего: 4



Alone, Про unix timestamp по подробнее можно? Помоему это дана формата:

Цитата
01.01.2005 00:00:00


Или я не прав?


--------------------
user posted image
PM   Вверх
AztEK
Дата 3.3.2006, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 723
Регистрация: 4.1.2005

Репутация: нет
Всего: 18



Нет, не прав.
Это формат вида 1336172882


--------------------
Linux is like wigwam -- no windows, no gates, apache inside.
PM MAIL Jabber   Вверх
CyClon
Дата 3.3.2006, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: 1
Всего: 4



AztEK, И что это обохначает? Может подкинешь ссылку, где можно почитать? У меня вечный вопрос с хранением даны, сейчас как ламер храню в varchar(20) такого типа dd.mm.yy | hh:ii


--------------------
user posted image
PM   Вверх
AztEK
Дата 4.3.2006, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 723
Регистрация: 4.1.2005

Репутация: нет
Всего: 18



CyClon это количество секунд, прошедших с начала эпохи UNIX (1 января 1970 года 05:00:00)


--------------------
Linux is like wigwam -- no windows, no gates, apache inside.
PM MAIL Jabber   Вверх
CyClon
Дата 4.3.2006, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: 1
Всего: 4



AztEK, В MySQL есть такое поле timestamp, но читал в статье, тчо лучше хранить в varchar... Как объясните?


--------------------
user posted image
PM   Вверх
Ciber SLasH
Дата 5.3.2006, 04:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



2CyClon:
Скачай мануал на русском на php.net и поиск по функции time.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.1056 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.