Боремся с 77 февраля
Если зайти по вот такому адресу — http://ilyabirman.ru/meanwhile/2008/02/77/ — то вместо ожидаемой страницы 404 мы увидим страницу, говорящую о том, что 77 февраля заметок нет. Это, конечно, не беда, но если это можно решить по-простому, то хочется взять, да и решить, правда?
Я это уже исправил в v1793, но на сайте пока крутится v1792 (последняя доступная всем остальным версия — v1746). Сначала я в функции, отвечающей за выдачу страницы архива, написал:
if (!e2_date_possible ($year, $month, $day)) return e2_error404_mode ();
А потом написал функцию e2_date_possible (), которая получилась не намного длиннее.
Задача: придумайте функцию e2_date_possible () лучше моей (не видя мою).
Update:
Дмитрий Смирнов: Ты изобрел функцию checkdate, поздравляю!
Принимаю поздравления. Это, кстати, подтверждает правоту Болка. Тем не менее, задачка остаётся, просто к ней добавляется (в реальной жизни ненужное) условие неиспользования функциии checkdate ().
if ($day>76) return false;
return ($day<77);
:)
ты бы писал, что подразумеваешь под «лучше» и заодно, чего можно использовать, а то для меня самый простой вариант в некритичной для скорости секции (с поправкой на язык)
result := TtyEncodeDate(Year, Month, Date, tDate);
а вот если нужна чистая арихметика, то становится интереснее
вот как-то так:
function e2_date_possible($year, $month, $day){
return date(’n’, mktime(0, 0, 0, $month, $day, $year)) == $month
}
Можно написать еще более «ручное» вычисление даты с учетом количеств дней в месяце, високосных лет, смены календаря в россии...
Но checkdate() по-любому будет работать быстрее.
Подход похожий, но не стопроцентно надёжно у вас. Вы сможете «попасть» в месяц, если введёте 377-е февраля :-)
возможно, вот этот вариант будет пошустрее капельку (не уверен):
return mktime(0, 0, 0, $month, $day, $year) <= mktime(0, 0, 0, ($month+1), 0, $year)
О, наконец-то я врубился в то, как это работает!
Функция не должна проверять верность даты. Вдруг, приспичит написать секретный пост за 31 июля, вспомнив Пристли.
Ну очень уже хочется новый e2 пощупать. Когда у нас появится такая возможность?
Этого никто не знает ;-)
%%function e2_date_possible ($year, $month, $day) {
$year = (int)$year;
$month = (int)$month;
$day = (int)$day;
if == $year) || ($day < 1 {
return FALSE;
}
switch ($month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return $day <= 31;
case 4: case 6: case 9: case 11:
return $day <= 30;
case 2:
if ($day <= 28) {
return TRUE;
} elseif (29 == $day) {
return ($year % 4 == 0) && % 100 != 0) || ($year % 400 == 0;
}
default:
return FALSE;
}
}%%
Ох и не лень же вам было!
вот такой вариант не попадает в 377 февраля:
return date(’Y.n’, mktime(0, 0, 0, $month, $day, $year)) == $year.’.’.$month
а вариант с двумя mktime() изначально лишен этого недостатка.
Играем дальше? Или я выполнил условия задачи?
Всё правильно, даже на капельку умнее, чем у меня ;-)
Ну, я решил, что условие можно расширить запретом использовать любые встроенные функции для работы с календарём или временем. А то неинтересно как-то: ведь чем использование checkdate принципиально отличается от использования mktime?
Ничем, просто я не знал про чекдейт. Как только узнал, перешёл на него :-)
Ваше решение хорошо как упражнение, но ещё вчера для меня это было не упражнением, а реальной задачей. Поэтому не было никакого резона в том, чтобы накладывать ограничения.
Спасибо в любом случае :-)