为什么 Carbon::createFromFormat() 在给定英国格式和美国日期时不抛出异常?

问题描述 投票:0回答:1

我有这个代码:

try {
    Carbon::createFromFormat('dmY', $rawDate)->format('Ymd');
} catch (InvalidFormatException $e) {
    echo 'Oops, bad date format.';
}

如果我输入

31012024
作为我的
$rawDate
值,我会得到
20240131
作为输出。这是正确的。 Carbon 已正确读取日期,然后按照我的预期格式化日期。

如果我输入

01312024
(一年中第 31 个月的第一天),我会得到
20260701
作为输出。这不是我所期望的,因为第 31 个月不存在,我会假设 Carbon 会抛出
InvalidFormatException
异常,因为该月根本不存在。

我可以通过脚本运行该字符串来验证前两个字符是否小于 31,第三和第四个字符是否小于 12,但我不想考虑不同的月份长度和闰年。

我的问题是,我可以在

createFromFormat
之前调用不同的 Carbon 方法来首先验证日期格式是否正确吗?

我无法使用

parse
,因为这会成功解析美国日期格式,但我不希望脚本这样做;它必须接受并验证英国日期格式。

ddmmyyyy
外不得接受其他格式。

仅供参考,我使用的是 Carbon 2.72.5,并且不在 Laravel 环境中,因此无法使用 Laravel 验证工具。

php date datetime validation php-carbon
1个回答
0
投票

createFromFormat
函数在很大程度上与同名的基本 PHP 函数完全相同,并且会“溢出”任何不适合日期正常范围的值。因此,在您的示例中,2026 年 7 月是 2024 年开始后 31 个月。它只是假设您的意思是“2024 年开始后 31 个月”,并算出那是哪个日期。

为了克服这个问题,您可以使用 Carbon 的

hasFormatWithModifiers
函数更精确地检查日期格式,然后再将其传递给
createFromFormat
。这将检查天和月的值是否在天和月的正常范围内。

警告:它仍然不处理不同长度的月份 - 例如它将允许诸如 9 月 31 日之类的事情发生。因此,您可能需要考虑为此添加您自己的额外验证。

示例:

if (Carbon::hasFormatWithModifiers($rawDate, 'dmY!')) {
  $dt = Carbon::createFromFormat('dmY', $rawDate)->format('Ymd');
  echo ($dt);
}
else echo "Invalid date";

文档参考:

© www.soinside.com 2019 - 2024. All rights reserved.