Боремся с 77 февраля: мой вариант
В общем, вчерашняя моя задачка во многом потеряла смысл, когда Дима Смирнов указал мне на наличие функции checkdate (). Просто когда проблема возникла я не пошёл читать мануал в поисках готовой функции, так как был уверен, что после того, как я намучился с проблемой часовых поясов и летнего времени (и стал мировым экспертом в этой области), я уже по-любому знаю все функции, связанные с датой временем. Оказалось, что я ошибся.
Впрочем, придумывать сложной математики мне не пришлось. Моё решение было однострочным и работало так:
return (
gmdate ('Y/n/d', gmmktime (0, 0, 0, $m, $d, $y))
== $y .'/'. $m .'/'. $d
);
Функция mktime умеет делать нормальный «тайм-штамп» из любых входных параметров. Например, если дать ей 25 часов 99 минут 32 декабря 2008 когда, то она вернёт штамп для 2 часов 39 минут 2 января 2009 не поперхнувшись.
Это свойство функции mktime () страшно удобно, потому, что если нужно посчитать, какими будут дата и время через 55 часов, то можно тупо прибавить 55 к часам и забыть про суточные, месячные и годовые переходы, забыть про учёт високосности — функция всё сделает сама.
Короче, критерий правильности даты — то, что функции не пришлось ничего «исправлять». (На самом деле, я уверен, что функция ничего и не исправляет, просто формулы в ней написаны так, чтобы всё работало независимо от корректности входных параметров.) А GMT-версии функций я использую «для надёжности», чтобы нигде часовые пояса не могли что-нибудь испортить.
Сергей Коваленко в комментариях к прошлой заметке предложил это же решение, причём совершенно справедливо не стал проверять день.
мне кажется, использование gm-функций здесь не оправдано. Они дают штамп времени по Гринвичу, в отличие от простых функций, показывающих штамп поясного серверного времени; и соответственно, они должны работать незметно медленнее. А поскольку в нашей функции мы ищем различия в штапме по одному и тому же поясу, то и приведение ко Гринвичу ничего не изменяет в данном случае. Т. е. gmdate(gmmktime()) будет эквивалентно date(mktime()).
http://php.net/strtotime
Из описания функции не следует, что она вернёт -1 для несуществующей даты. Там сказано просто, что она вернёт -1 «в случае ошибки». Но может оказаться, что речь идёт просто об ошибке парсинга.
Парсинга чего, пхп? :)
Если ты имел в виду дату, то — да. Дату надо писать в любом буржуазном формате. А в функцию mktime() писать параметры в правильной последовательности. Ох уж этот пхп.
Парсинга той херни, которую ты передаёшь шаманской функции strtotime ().
Ну ты и ленивый. А попробовать функцию?
(gmdate (’Y/n/d’, gmmktime (0, 0, 0, $m, $d, $y)) == $y .’/’. $m .’/’. $d);
Тоже самое:
strtotime($y .’/’. $m .’/’. $d) > 0;
Или (более читаемый без подсветки):
strtotime(sprintf(’%s/%s/%s’, $y, $m, $d)) > 0;
В функции нет ничего шаманского. Она просто много делает, что для PHP нехарактерно. Но у неё много плюшек и если с strrotime() поближе познакомиться, то можно упростить и жизнь и код. :)
Если я мгновенно придумал решение, в котором не сомневаюсь, зачем мне придумывать какое-то ещё решение, которое, тем более, нужно ещё и проверять? :-)
«Цайтштемпель» (http://de.wikipedia.org/wiki/Zeitstempel)
Нужно помнить только два формата даты: ’Y-m-d’ и ’d.m.Y’. При этом первый формат универсален, понимается всеми парсерами и правильно пишется в БД, а второй более привычен на письме для русского глаза.