PHP从格式方法创建日期不能按预期工作

时间:2017-07-19 12:39:23

标签: php datetime

以下内容返回false

DateTime::createFromFormat("Ymd-Gi", '20170629-902')

我已经查看了http://php.net/manual/en/function.date.php中的格式,这一切似乎都是正确的。

知道为什么吗?

2 个答案:

答案 0 :(得分:0)

我认为G应该是前导零。然后0902代替902

答案 1 :(得分:0)

我冒昧地看一下php源代码,发现负责解析format字符串的函数:timelib_get_nr_ex。它看起来像这样,

static timelib_sll timelib_get_nr_ex(char **ptr, int max_length, int *scanned_length)
{
    char *begin, *end, *str;
    timelib_sll tmp_nr = TIMELIB_UNSET;
    int len = 0;

    while ((**ptr < '0') || (**ptr > '9')) {
        if (**ptr == '\0') {
            return TIMELIB_UNSET;
        }
        ++*ptr;
    }
    begin = *ptr;
    while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
        ++*ptr;
        ++len;
    }
    end = *ptr;
    if (scanned_length) {
        *scanned_length = end - begin;
    }
    str = timelib_calloc(1, end - begin + 1);
    memcpy(str, begin, end - begin);
    tmp_nr = strtoll(str, NULL, 10);
    timelib_free(str);
    return tmp_nr;
}

当格​​式字符串中找到'G'或'H'时,它被调用{/ 3}。

// ...
case 'G': /* two digit hour, with leading zero */
case 'H': /* two digit hour, without leading zero */
        TIMELIB_CHECK_NUMBER;
        if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
                add_pbf_error(s, "A two digit hour could not be found", string, begin);
        }
        break;
// ...

如您所见,timelib_get_nr_ex函数不会检查前导零。但是,它仍然消耗两位数。所以在你的情况下,小时部分变为90。然后只有一个数字剩余的分钟部分。但根据格式i,它应该是一个两位数值(包括前导零)。所以这会引发错误:“无法找到两位数分钟”

要检查是否有任何错误/警告,您可以使用此

DateTime::getLastErrors()

对于12小时格式,他们也有这样的验证。

if (s->time->h > 12) {
    add_pbf_error(s, "Hour can not be higher than 12", string, begin);
}

如果您使用'G'或'H',则没有任何相似之处。因此,当它错误地将其解析为90时,它不会记录错误。

无论您使用何种格式值,看起来只需一个数字就必须使用零。