Открыть список
Как стать автором
Обновить

Комментарии 92

буквально вчера искал что-то подобное, а тут ваша библиотека. Спасибо :)
А как вы храните даты в базе данных?
Конвертируете или всё в unixtimestamp'e храните?
Я сторонник идеи сохранять и получать данные из базы в одом часовом поясе, так что timestamp для меня никаких особых преимуществ не даёт. Поэтому храню в datetime. timestamp использую только в MySQL(т.к. MySQL на выходе всё равно timestamp в datetime конвертирует) для полей, в которых нужно чтобы он автоматом проставлялся при ON CREATE & ON UPDATE.
НЛО прилетело и опубликовало эту надпись здесь
Да, я поэтому и стараюсь всегда хранить в UTC+0. чтобы не зависеть от настроек сервера или пхп.
Я вопрос задавал потому что, наличие serverDateTime() показалось немного странным
А что разве удобней вызывать date('Y-m-d H:i:s') каждый раз прописывая формат, чем просто serverDateTime()? Этот метод введён из соображений практичности, а не функциональности)
НЛО прилетело и опубликовало эту надпись здесь
Всё равно не понял. Вот код преобразования из Europe/Minsk в UTC и обратно. Ничего нигде не теряется.

$dater = new Dater(new Dater_Locale_Russian(), 'Europe/Moscow');
$utcDateTime = $dater->format('2012-08-12 12:00:00', 'server_datetime', 'UTC', 'Europe/Minsk');
echo $dater->format($utcDateTime, 'server_datetime', 'Europe/Minsk', 'UTC');

Можете привести пример кода в котором что-то куда-то потеряется?
Формат данных и часовой пояс — разные вещи) Тут спросили про формат данных, datetime или timestamp. То, что часовой пояс UTC наиболее универсален для сервера трудно поспорить :)

И хранить даты нужно с уканаием пояса. Иначе вы не сможете вернуться в нужный часовой пояс и реальное время, к примеру кода у нас прыгали пояса, или между летним и зимнем временем.

Не совсем понял. Почему мы не сможем вернуться в нужный часовой пояс? Есть datetime клиента по Europe/Minsk скажем в летний период, приводим её к UTC, потом обратно в Europe/Minsk… и что вы хотите сказать, что в разное время года оно будет отличаться от исходного?
НЛО прилетело и опубликовало эту надпись здесь
Так это всё благодаря идиотам-политикам(типа Медведева), которые внезапно летнее время то отменяют, то не отменяют. В реальности же такие изменения в базах часовых поясов крайне редко происходят. И что ради этих крайне маловероятных событий теперь париться datetime в строковом формате хранить или заводить дополнительное поле для timezone? Лично мне это кажется немножко избыточными жертвами.

Плюс ко всему изменения утверждённые в гос реестре ещё неизвестно когда будут синхронизированы с базами серверов во всём Мире. Т.е. с уверенность могу сказать, что для большинства PHP серверов Россия переход на лентнее время не отменяла :) Это случится только после того как они в принудительном порядке timezonedb у себя внезапно зачемто обновят.
Для актуального ванильного PHP «Note: This list is based upon the timezone database version 2013.2.» и в минорных релизах обновляется, если изменения были (а они не так уже редки — государств порядка двух сотен и в каждом свои политики — каждое государство раз в сто лет сменит время — раз в полгода обновления базы — не так уж маловероятно, а есть ещё регионы и т. п.). В некоторых дистрах идет привязка к системному timezonedb, обновления которому прилетают из репов дистра. В нормальных дистрах обновление прилетает заблаговременно, через несколько дней после принятия закона или постановления. Два года никто не обновлялся?

В общем хранить датувремя нужно или с указанием пояса, или приводить его к какому-то фиксированному для приложения (не для сервера!), обычно UTC, причем не захардкодив где-то в глубине кода строку «UTC», а вынести как константу или элемент конфига со зловещим комментарием «Не менять, если не хотите трудноуловимых глюков и/или конвертировать всю базу!!!», а если разрешить смену в админке, то конвертировать все даты в новый пояс.
И всё равно я не пойму: если мы приводим дату-время к UTC в момент получения этой даты, то даже если в timezonedb обратная конвертация изменится, то мы всё равно получим оригинальное время. Например:

до 2008
Europe/Moscow: +4 летом

после 2008
Europe/Moscow: +3 летом

И вот к примеру летом 2007-го мы получаем datetime по UTC +4, к примеру 14:00, при водим к UTC получаем 10:00.
Потом в 2009 году обновляем timezonedb и приводим обратно эту дату-время к Europe/Moscow. И получаем уже не 14:00, а 13:00. И вы считаете это ошибкой?

На мой взгляд это очень даже правильно. Т.к. хоть для одной страны мы и получили разницу в смещении(хотя не факт что не оправданную, раз они в timezonedb изменения внесли), но для всех других стран эта метка времени осталась актуальной. А если придерживаться вашей идеии хранить название оригинальногого timezone, то потом приводя эту дату к другим часовым вы будете получать искажённое значение. К примеру будете 14:00 приводить к UTC после 2008-го и получите не 10:00, а 11:00, и так для всех других часовых поясов.

В итоге дилемма такая: или вы ломаете дату для одного пояса, или ломаете её для всех остальных поясов. Логика подсказывает, что большую погрешность в актуальности даты даёт как раз ваш, последний случай.

Кстати, в пользу хранения даты-времени у универсальном часовом поясе даже специальный тип данных ввели — timestamp называется.
timezonedb хранит не только текущие значения для разных часовых поясов, но и всю историю. 1 августа 2007 14:00 MSK мы приводим 1 августа 2007 10:00 UTC по любой базе после 2007, а обратное преобразование по другой любой базе после 2007, хоть за 2025, даст нам то же время. При этом, на любой базе после 2009 1 августа 2009 10:00 UTC приведется к 1 августа 2009 13:00 MSK. Внешняя нелогичность может быть, если мы к дате 1 августа 2007 14:00 MSK прибавим 2 года и получим 1 августа 2007 13:00 MSK. Но по UTC/unixtime это будет именно плюс 60*60*24*(365*2 + 1) секунд (с учетом, что 2008-й — високосный). Дилеммы нет. Ошибок нет. Правда при условии, что мы считаем время физическими единицами, а не юридическими — со всеми этими свистоплясками на timezonedb полагаться нельзя если меняется дата при преобразованиях. Грубо говоря, если нас интересует датавремя 1 августа 2007 00:00 MSK + 2 года, то по российским законам 2 года истекут 2 августа 2009 00:00 MSK в общем случае, а если положимся на timezonedb, то 1 августа 2009 23:00 MSK. Это следует иметь в виду при проектировании приложений в которых сроки имеют юридическую значимость (или при даче показаний или ответов на запросы, типа пришел запрос из прокуратуры или СК «предоставьте логи заходов с такого-то IP за последние три года»). Юридические сроки нужно считать не в физических единицах через timezonedb, а в юридических согласно законодательству конкретной страны, зачастую учитывающих не только законы, но и график работы конкретных учреждений. Особенно если любишь оттягивать дедлайн до последнего :) Или наезжать, если дедлайн хоть на секунду задержали :(
> timezonedb хранит не только текущие значения для разных часовых поясов, но и всю историю

Я вот тоже первым делом на это понадеился, но перепроверив понял, что это не так:

echo $dater->format('2001-07-07 12:00:00', 'time', 'UTC', 'Europe/Moscow') . PHP_EOL;
echo $dater->format('2012-07-07 12:00:00', 'time', 'UTC', 'Europe/Moscow') . PHP_EOL;


Всегда выводит 11:00. При том, что timezone_version_get() возвращает 2011.8, т.е. вполне актуальная.
Можете привести пример подтверждающий ваши слова?
$date = new DateTime('2000-01-01', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2000-01-01 00:00:00+03:00
$date->setTimeZone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 1999-12-31 21:00:00+00:00
$date->modify('+ 13 year'); 
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2012-12-31 21:00:00+00:00
$date->setTimeZone(new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2013-01-01 01:00:00+04:00

Как видите, «ниоткуда» час появился, а PHP «знает», что зимой 2000-го у нас было +3, а это зимой — +4.
Отлично, timezonedb хранит историю изменений — это здорово. И это в очередной раз доказывает, что нет необходимости хранить даты в оригинальном timezone с timezone меткой — это ничего не даёт.

$date = new DateTime('2000-01-01 12:00:00', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:s P') . PHP_EOL; // 2000-01-01 12:00:00 +03:00
$date->setTimeZone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:s P') . PHP_EOL; // 2000-01-01 09:00:00 +00:00
$date->setTimeZone(new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:s P') . PHP_EOL; // 2000-01-01 12:00:00 +03:00


Как видите при конвертации Msk-UTC-Msk ничего не теряется. У вас время теряется только после того как вы 13 лет прибавляете. Не понятно только зачем вы это делаете и почему думаете, что время в 2000-ом должно быть эквивалентно времени в 2013, в то время как правила его исчисления изменились?
Делаю это чтобы исчислять сроки. Скажем, для задач типа GTD — поставили начальную датувремя проекта как now(), поставили «срок — неделя». В зависимости от формата хранения могут быть три варианта: аларм выскочит ровно через неделю (60*60*24*7 секунд), может на час раньше, а может на час позже. Последние два варианта по местному времени, если переход летнее/зимнее произошел. Получаем, что результат работы программы зависит от формата хранения данных и нужно определиться какой формат хранения нам нужен. И это мы только с UTC и MSK разбирались. А если нам нужно между EET (Europa/Kiev) и, скажем, бывшим PETT (Asia/Kamchatka, MSK+9), ныне объединенным с MAGT (Asia/Magadan, MSK+8), разбираться, то вообще не уверен, что timezone функции справятся. А для меня, по идее, это область практических интересов, и там, и там родные живут.
А не проще ли было для одного такого случая модификации даты-времени с сохранением попраки на оригинальный часовой пояс просто реализовать метод модификации, который бы автоматически корректировал время на разницу в timezonedb нужного часового пояса?

Там ведь делов то на несколько строчек :) И не пришлось бы с заморачиваться с хранением timezone каждой даты.
На моем основном проекте (MMO игра) сейчас люди из разных стран (минимум три — Россия, причем не только московское время, Украина и Германия), им постоянно нужно показывать время событий (в том числе и будущих) друг друга в их местном времени. Сейчас там костыль на костыле, саппорт советует для Москвы выставлять часовой пояс, кажется, Стамбула, чтобы более-менее нормально работало. Я вот хочу успеть к последнему воскресению марта сделать безкостыльную систему :)
Смещения даты-времени без учёта часового пояса — это уже костыль :) А вот реализация смещения без учёта поправки на часовой пояс — это вполне себе простенькое и прозрачное решение, которое вы по коду, по идее, лишь в нескольких местах будете использовать.
Заинтересовал ваш пример, поигрался, и вообще вот что получил:
$date = new DateTime('2000-01-01', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2000-01-01 00:00:00+03:00
$date->setTimeZone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 1999-12-31 21:00:00+00:00
$date->setTimeZone(new DateTimeZone('Europe/Moscow'));
$date->modify('+ 13 year');
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2013-01-01 00:00:00+04:00
$date->setTimeZone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2012-12-31 20:00:00+00:00


То есть модификаторы типа '+ 13 year' и, видимо, DateInterval с DateTime работают с учетом текущего часового пояса. Приводим к UTC — работаем с физическим временем 9аналогично timestamp), приводим к «политическому» поясу — работаем с работаем с местным временем. Как-то я эту фишку не просек, когда экспериментировал. Потому вывод: хранить исключительно в формате с часовым поясом, причем не в формате «Y-m-d H:i:s P», а в формате «Y-m-d H:i:s T» или «Y-m-d H:i:s e». С мускулом, правда, нужны отдельные эксперименты, насчет того, как он воспринимает таймзоны для полей типа DATETIME. Беглое чтение доков показало, что адекватного восприятия им строк нужно регулярно конвертитровать timezonedb в таблицу в базе mysql. Но хранит ли он таймзону в самом поле или конвертирует её к какой-то нужно разбираться.
Это всё имеет смысл только при том, что у вас частенько возникают конвертации типа +13 years и вы хотите в таких конвертациях сохранять неизменность времени. И мало того, что это спорный вопрос насколько правильно сохранять время при конвертации в другие timezenedb правила, так ещё и сам кейс крайне крайне редкий.

Лично я не готов был бы пойти на заморочки с отдельным хранение timezone для каждой даты-времени лишь ради такого сомнительного выигрыша как сохранении времени в таких крайне редких случаях как +13 years.
Простой кейс — поиск записей за последний год/месяц/неделю/день на ресурсе типа форума или блога с хотя бы российской аудиторией. Имхо, просто непрофессионально сдавать заказчику (пускай и внутреннему типа начальника отдела или менеджера проекта), если не можешь описать её поведение (а оно зависит от формата хранения) в экстремальных условиях типа Путина/Медведева. Когда я вижу в ТЗ записи типа «за последнюю неделю» я сразу задаю уточняющие вопросы типа «что считать неделей, если у пользователя часовой пояс изменился, причем не просто +3 или +4 к MSK, а с MSK+4 к MSK на UTC-7:30 DST».
См. habrahabr.ru/post/173693/#comment_6036635 Можно просто реализовать метод, который будет возвращать дату-время с игнорированием timezonedb изменений.
Что значит «с игнорированием измененияй»? Что принимаем за основу, после которой игнорируем? И почему имеено эта основа?
Ваша проблема с потерей времени при конвертации msk-utc-msk в этом примере habrahabr.ru/post/173693/#comment_6036409 заключается в том, что вы делаете modify +13 years над utc, а не над msk. Т.е. в вашем случае правильней было бы реализовать modify, который работал бы перед вызовом modify приводил время к нужному поясу. Например:

$date = new DateTime('2000-01-01', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2000-01-01 00:00:00+03:00
$date->setTimeZone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 1999-12-31 21:00:00+00:00
$date->setTimeZone(new DateTimeZone('Europe/Moscow'));
$date->modify('+ 13 year');
echo $date->format('Y-m-d H:i:sP') . PHP_EOL; // 2013-01-01 00:00:00+04:00


И используйте его на здоровье там, где вам нужно модифицировать дату с сохранением времени. Всё ведь просто, и не нужно timezone для каждой даты хранить.
Да собственно это не проблема. Просто нужно знать нюансы.
Из пожеланий — composer, ну и уже namespace, пора уже…
Всё будет!
ИМХО — Сейчас публиковать библиотеки для PHP без пакета композера и PSR-0 уже плохой тон.

Но, в любом случае, спасибо за библиотеку, как минимум попробую поюзать :)
Composer есть ведь. Устанавливайте «dater/dater» => «dev-master» А psr-o будет как только на неймспейсы зарефакторю.
Храню время в unix timestamp, в начале скрипта выставляю часовой пояс по умолчанию (каждый пользователь может иметь свой).
Форматы дат хранятся в языковых файлах, для каждой локали свой набор форматов краткой, полной даты и т.д…
Просто, прозрачно, применяется ко всем операциям с датами в любом месте скрипта.
Для себя решил, что такой подход наиболее удобен.
Работа с несколькими локалями и часовыми поясами — для очень узкой ниши специализированных проектов.
Использую такой же подход. Никаких проблем не наблюдается.
А вы не рассматривали возможности определять время клиента по заголовкам HTTP без этого шаманства с JS?
А что существуют такие заголовки?) Расскажите? Очень интересно)
=) Если бы я знал, я бы так и написал. А я как раз и спрашивал, исследовали ли вы этот вопрос, может, есть что-то.
Нет такого :)
Я ж без наездов, правда, интересно было, а искать — лень =) Сейчас вот тоже поискал, таки нет ничего похожего.
Таки в одной России 9 часовых поясов :D С вероятностью 1 к 9 часовой пояс определять?))
Ну да. Тут я промазал.Однако
Ну да. Тут я промазал.
Однако можно определить географическое положение пользователя по его IP-адресу. В сумме, все эти «догадки» (geoip, accept-language, etc) могут дать вполне достоверную информацию о таймзоне. Не ручаюсь за степень достоверности.
Спасибо, интересно.

А зачем классы Dater_Locale_*? Не лучше ли стандартными строками типа ru_UA или en_US (и в идеале ещё и кодировку корректно обрабатывать типа ru_RU.UTF-8) инициализировать конструктор Dater_Locale сделав его не абстрактным, а локали хранить или в статическом массиве этого класса, или в «конфигах», или заполнять динамически с помощью setlocale/strftime, ну или уж если так нравится, то сделать фабричный статический метод в Dater_Locale, который будет внутри нужный конструктор вызывать?

Главная фишка в чем со строками — для локалей задаваемых пользователем или детектируемых не нужно будет лепить большой switch или костыли типа new 'Dater_Locale_'.$locale;
Добавил статический метод Dater::getLocaleByCode('ru');
Лучше Dater_Locale::getByCode('ru'); по-моему. И маленький пулл-реквест ещё отправил. Было интересно функциональность гитхаба редактирования онлайн проверить :)
> Лучше Dater_Locale::getByCode('ru');

Не могу согласиться. Всё-таки Dater_Locale это класс сущности локали, а не агрегатор какой-то функциональности. А то так будет странно выглядеть Dater_Localer_English::getByCode('ru'). Ну и возможность переопределить список локалей в под-классе сущности выглядит странно. Pull реквест получил, спасибо :) но вынужден отклонить.
Ну, Dater_Locale_English::getByCode('ru') это будет нецелевое использование классов-наследников Dater_Locale :) Для исключения переопределения можно (и нужно) final использовать. В принципе можно и исключение бросать если getByCode вызывается из Dater_Locale_English, сравнивая self и static (LSB). А в идеале отдельный класс Dater_Locale_Fabric сделать, пускай и с одним (пока) методом. А так вы нарушаете принцип единственной ответственности и усиливаете связанность — класс Dater у вас теперь отвечает за то, какой из подклассов Dater_Locale создавать и статически с ними связан, причем так, что поиск по имени класса эту связь не покажет, IDE вряд ли её обнаружит при попытке переименования классов Dater_Locale_* и т. п. Не лучше ли такую связь вынести в более очевидное место?

Может реализация у меня костыльная, но над предложением чтобы фабричный метод принимал не только «ru», но и «ru_RU», и «ru_UA» и переадресовывал на «ru» раз точных описаний найти не может, советую подумать — это общепринятая техника работы с локалями, даже MS её перетащила из никсов в Висте :). А заодно переименовать классы типа Dater_Localer_English в Dater_Localer_En.
Я ведь не про переопределение говорил, а про вызов Dater_Locale_English::getByCode('ru'). Лично мне не нравится идея выносить в класс сущности фабричный метод её инициализации. Заводить отдельный класс-фабрику для мапинга кодов локалей на классы я специально не стал, хочется оставить библиотеку в лаконичном виде. Dater::$localeCodes поэтому публичным оставил, кому надо — добавят своих классов локалей и впишут их в Dater::$localeCodes.

По поводу предложения ru_RU я комментом к пул реквесту ответил: форматов может быть сотни, преобразуются они элементарно, не вижу смысла заграмождать Dater этимим преобразованиями, кому надо сами преобразуют перед вызовом getLocaleByCode.

Тем не менее спасибо, что проявили участие! :) Для меня это очень важно.
Пожалуйста :)
кому надо сами преобразуют перед вызовом getLocaleByCode.

У многих строка локали уже есть в формате BTC 47, хотя бы потому что это общепринятый стандарт, не нужно думать о том как закодировать американский и британский английские. Зачем ограничивать совместимость со стандартом, тем более что даже строчки не добавляется? Или не хотите, чтобы сейчас кто-то ввел «russian» или «english», оно у него работало, а потом отвалилось из-за того что перешли на формат \.._..\ с \...*\?
Вот вам нравится этот стандарт, кому-то другому нравится трёхбуквенный стандарт RUS, ENG. Таки я не хочу вступать в полемику какой стандарт лучше. Каждый из прочих других стандартов элементарным образом приводится к двух-буквенному.
Мне этот стандарт не нравится, но он общепринят на уровне самых распространенных ОС, хоть на десктопах (Windows, MacOS, Linux), хоть на серверах (Linux, *BSD, Windows). И он описывает именно локали, а не языки. Он может описать различия между русским российским («на Украину») и украинским («в Украину), английским американским (»I will") и британским («I shall»).
А вот этого я не учёл. Спасибо вам. Скоро зарефакторю на новый стандарт.
На самом деле под разными ОС локаль прописывается в разном формате: ru_RU, RUS_RUS, Russian_Russia — 3 разных варианта. В общем я зарефакторил всё на работу в двухсимпольном формате, без привязки к регистру, и без подчёркивания. Теперь работает как-то так $dater->getLocaleByCode('en', 'uk'); второй аргумент опционален.
Это я знаю, но все классы перечислять не хочу, а под psr-0 пока не зарефакторил. Так или иначе __autoload.php нужен т.к. из общего числа пользователей Composer процентов 3-5 используют.
А так? :)
    "autoload": {
        "psr-0" : {
            "Dater_" : "Dater/"
        }
    }


PS Лучше «Dater/» => «src/Dater/».
У меня вот жёсткая дилемма по этому поводу: если переходить на неймспейсы, то придётся переименовывать Dater в \Dater\Dater. Вы считаете нормальным такие именования?
Liaren\Dater — вполне обычная практика :)
Это то понятно)) Но неймспейс у библиотеки должен быть не Liaren, а Dater. Отсюда возникает вопрос: как назвать основной класс? А то ведь new \Dater\Dater правда странно смотреться будет. А вот переименовать его в какой-нить Formatter и т.п. рука не поднимается
Dater\Dater вполне подходит. Не нужно писать new \Dater\Dater;
Вместо этого используйте use. К тому же ide сама добавляет нехватающие use в начало файла (напримерв PhpStorm напишите new Dater; нажмите Alt + Enter)
Имел в виду нэймспэйс Liaren\Dater, полное имя класса \Liaren\Dater\Dater Опять же обычная практика.
Честно говоря ниразу не видел код, в которым бы в качестве базового namespace имя автора использовалось. Искал на гитхабе примеры организации именований неймспейсов в более ли менее солидных библиотеках, так вот нашёл единственный случай именования по аналогии с Dater/Dater — github.com/ircmaxell/PHP-PasswordLib/blob/master/lib/PasswordLib/PasswordLib.php больше такого нигде не видел.
Первая (значащая) строка PSR-0
\<Vendor Name>\(<Namespace>\)*<Class Name>
. Вы же вендор :)
Под Vendor name в данном случае понимается название библиотеки, а не класса :) fabpot ведь не пихал свой фреймворк Silex в namespace /Fabpot/Silex github.com/fabpot/Silex, да и вообще так никто не делает. Всегда используют название библиотеки как корневой namespace.
Не всегда. Zend так точно делает :) Фабиен тоже месяц назад писал SensioLabs\Connect\Security\Authentication\Provider;
У Зенда название продукта совпадает с названием бренда, тут без вариантов)) А SensioLabs просто нормального названия продукту не придумали, вот и решили вставить себя в корень, заодно и попиариться. Вы посмотрите сотни прочих более ли менее современных библиотек, так больше никто особо не делает.

А что если библиотеку форкать будут, всем потом название корневого неймспейса вручную менять?) А так есть базовая версия Dater, она же на packagist.org под dater/dater опубликована. Кто будет форкать — пусть публикует под myname/dater, но имхо конечные пользователи не должны париться каждый раз namespace у себя перепрописывать только из-за того, что переключились на использование Dater, который был форкнут и доработан другим автором.
Это что по вашему Yaml — это чей-то ник?)
Это отдельный компонент Symfony, который не имеет зависимостей от самого фреймоворка, поэтому может выступать как отдельный пакет для чего угодно.

Symfony — это имя вендора. Можете не использовать свой ник. Можете взять любое название, под которым будете выпускать свои пакеты.
Вы путаете название компонента и название вендора. Vendor — поставщик, т.е. название автора. В случае с Symfony название вендора должно было быть SensioLabs т.к. по сути это их продукт, однако где вы видели в исходниках Symfony namespace SensioLabs? В нормальной практике никто так не делает, это крайне неудобно.
В нормальной практике никто так не делает, это крайне неудобно.

Смотря как посмотреть. Уникальный Vendor_name сильно уменьшает вероятность конфликта имен. И позаботиться о глобальной уникальности только один раз нужно, а дальше только о внутренней.
Мне кажется лучше пусть разработчик компонента 1 раз позаботиться об уникальности названия своего детища(гугл в помощь), чем пользователи этого компонента потом будут каждый раз в неймспесах его ник прописывать, а потом ещё париться с автозаменой неймспейса, если решат переключиться на альтернативный форк от другого разработчика.
Да, вы правы… Но суть в том, что у вашего корневого класса должно быть как минимум два неймспейса: ). Можно и так Dater\Dater\Dater :^ )
А чем обусловлено это ваше «должно»?)
Про PSR-0 Вам уже выше сказали. Только это.
В таком случае в жопу PSR-0 :)
А чем Вы руководствуетесь?
Тем, что в этом нет абсолютно никакой практической составляющей. Кстати, вы что-то напутали с PSR-0, там не обязательно namespace Dater\Dater использовать, можно просто Dater. См. habrahabr.ru/post/173693/?reply_to=6047733#comment_6044785 там (<Namespace>\)* как бы намекатает, что под-неймспейсов должно быть от 0 и более, а не от 1 и более.

Так что всё ок с PSR-0, это вы меня напутали)
Действительно, напутал… Сам вот недавно пакет делал и там vendor не vendor, и корневой namespace один.
Это что по вашему Yaml — чей-то ник?)
Liaren\Dater\Dater :^ )
Очень интересная библиотека. У самого есть что-то похожее, но значительно беднее. Теперь вот думаю: стоит ли свое развивать, раз уже готовое есть? )

Есть предложение: ввести еще функцию, которая будет возвращать шаблон даты на основе текущей локали. Например так:

$dater->setLocale(new Dater\Locale\En()); echo $dater->getDatePattern(); // 'mm/dd/yyyy' $dater->setLocale(Dater\Dater::getLocaleByCode('ru')); echo $dater->getDatePattern(); // 'dd.mm.yyyy'

Очень удобно для инициализации яваскриптовых библиотек, чтобы уж везде на страницах сайта дата единообразно фомировалась
Отлично!

А метод с js-кодом, наверное, вряд ли так уж необходим. Нормальные библиотеки для манипуляции с календарями, например, позволяют задавать формат вывода даты при инициализации, и добавленных функций достаточно. А на все случаи жизни все равно методов не напасешься.
А как быть с этим js, ведь сначало исполняется php, а потом уже клиент, соответственно когда человек заходит на сайт первый раз, то php ещё не знает о часовом поясе. Как это можно обойти?
А, понял, сразу не заметил. Просто у меня периодически выскакивает ошибка в логах.

date_default_timezone_set(): Timezone ID '' is invalid in /public_html/library/Controllers/ControllerBase.php on line 19


Не знаю как это исправить
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.