парсинг даты — php date_parse (& quot; февраль 2010 & quot;) дает день == 1

В date_parse есть то, что я бы назвал ошибкой, когда дня нет. $d = date_parse("Feb 2010") дам $d["day"] == 1,

Смотрите комментарий к этому на страница справочника date_parse.

Есть хороший обходной путь для этой проблемы? 🙂

ОБНОВИТЬ
Дата взята из опубликованных исследовательских отчетов. К сожалению, это означает, что они могут выглядеть по-разному. Я хочу преобразовать их в более стандартный формат ISO при отображении ссылок. Чтобы помочь читателям, я хочу всегда включать только указанные поля (годы, месяц, дата). Так что это должно быть в силе (и просто дать мне год):

2010

Это должно быть верно, но просто дайте мне 2010-02, так сказать:

Feb 2010

ОБНОВЛЕНИЕ 2
До сих пор я видел две ошибки здесь, в date_parse, Не может разобрать 2010, И это дает день, хотя в Feb 2010,

Я могу, конечно, написать исправление для этого, но наверняка кто-то уже сделал это, или ???

3

Решение

Вышеуказанная процедура исправления ошибок великолепна, Лео, спасибо. К сожалению, он все еще споткнется в январе, думая, что 2014-01 — это то же самое, что и 2014-01-01 — мы находимся на одиннадцатой двенадцатой позиции.

Форматы даты, которые может анализировать PHP, не содержат день месяца, кажется, (в php_src: Дата / Библиотека / parse_date.re):

gnudateshorter   = year4 "-" month;
datenoday        = monthtext ([ .\t-])* year4;
datenodayrev     = year4 ([ .\t-])* monthtext;

Очень мало, удобно. Мы можем запустить те же регулярные выражения в $ dateRaw, по сути, пересмотрев то, что решил анализатор.

(Боковые наблюдения: в приведенное выше исключены форматы, такие как 5/2016, который анализируется как «20 мая с некоторыми дополнительными символами в конце»; они также похожи на форматы дня года и недели), поэтому мы постараюсь не запутаться.)

function date_parse_bugfix($dateRaw) {
$dateRaw = trim($dateRaw);
// Check for just-the-year:
if (strlen($dateRaw) === 4 && preg_match("/\d{4}/", $dateRaw) === 1) {
$da = date_parse($dateRaw . "-01-01");
$da["month"] = false;
$da["day"] = false;
}
else {
$da = date_parse($dateRaw);
if ($da) {
// If we have a suspicious "day 1", check for the three formats above:
if ($da["day"] === 1) {
// Hat tip to http://regex101.com
// We're not actually matching to monthtext (which is looooong),
// just looking for alphabetic characters
if ((preg_match("/^\d{4}\-(0?[0-9]|1[0-2])$/", $dateRaw) === 1) ||
(preg_match("/^[a-zA-Z]+[ .\t-]*\d{4}$/", $dateRaw) === 1) ||
(preg_match("/^\d{4}[ .\t-]*[a-zA-Z]+$/", $dateRaw) === 1)) {
$da["day"] = false;
}
}
}
}
return $da;
}
2

Другие решения

Нет ответов, поэтому я отвечаю на свой вопрос. Вот решение проблем, которые я видел.

// Work around for some bugs in date_parse (tested in PHP 5.5.19)
//   http://php.net/manual/en/function.date-parse.php
//
// Date formats that are cannot be parsed correctly withoug this fix:
//   1) "2014" - Valid ISO 8061 date format but not recognized by date_parse.
//   2) "Feb 2010" - Parsed but gives ["day"] => 1.
function date_parse_5_5_bugfix($dateRaw) {
// Check "2014" bug:
$dateRaw = rtrim($dateRaw);
$dateRaw = ltrim($dateRaw);
if (strlen($dateRaw) === 4 && preg_match("/\d{4}/", $dateRaw) === 1) {
$da = date_parse($dateRaw . "-01-01");
$da["month"] = false;
$da["day"] = false;
} else {
$da = date_parse($dateRaw);
if ($da) {
if (array_key_exists("year", $da)
&& array_key_exists("month", $da)
&& array_key_exists("day", $da))
{
if ($da["day"] === 1) {
// Check "Feb 2010" bug:
// http://www.phpliveregex.com/
if (preg_match("/\b0?1(?:\b|T)/", $dateRaw) !== 1) {
$da["day"] = false;
}
}
}
}
}
return $da;
}

Некоторые тесты (визуальные ;-))

$a = date_parse_5_5_bugfix("2014"); print_r($a);
$b = date_parse_5_5_bugfix("feb 2010"); print_r($b);
$c = date_parse_5_5_bugfix("2014-01-01"); print_r($c);
$d = date_parse_5_5_bugfix("2014-11-01T06:43:08Z"); print_r($d);
$e = date_parse_5_5_bugfix("2014-11-01x06:43:08Z"); print_r($e);
1

Ты можешь попробовать:

$dateTime = strtotime('February, 2010');
echo date('Y-m', $dateTime);
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector