【问题标题】:Why do I get error when try to convert Carbon to DateTime?为什么我在尝试将 Carbon 转换为 DateTime 时会出错?
【发布时间】:2021-12-24 00:08:36
【问题描述】:

我正在开发一个 Laravel 项目。我尝试使用 Carbon 创建一个 DateTime 对象。这是我尝试过的:

Carbon::createFromFormat('Y-m-d H:i:s', '2021-10-01T00:01:00')->toDateTime();

但我的 phpstan 抱怨:Cannot call method toDateTime() on Carbon\Carbon|false.

为什么会出现这个错误?将Carbon 转换为DateTime 对象的正确方法是什么?

【问题讨论】:

  • 您提供的时间不是您告诉 Carbon 期望的格式。所以createFromFormat() 失败,可能返回 false。
  • @Don'tPanic 但这是 PHPStan 无法检测到的东西
  • Y-m-d H:i:s2021-10-01T00:01:00。您的格式有空格;你的字符串有一个 T 代替。您的日期字符串与您的预期格式不符。
  • @ceejayoz 这是 PHPStan 通过静态分析无法检测到的东西
  • @NicoHaase 好吧,OP 编写的代码会引发异常。如果不出意外,他们应该先解决这个问题。

标签: php laravel php-carbon phpstan


【解决方案1】:

如果 PHPStan 抱怨,那是因为静态分析(不执行代码)无法正确确定类型。随着 Carbon 扩展 DateTimePHP documentation 可以帮助这个方法调用:

返回一个新的 DateTime 实例,失败时返回 false。

因此,为了确保代码在静态分析方面是正确的,您需要将其拆分:

$object = Carbon::createFromFormat('Y-m-d H:i:s', '2021-10-01T00:01:00');

if (!$object instanceof Carbon) {
  throw new RuntimeException('could not parse date');
}

$object->toDateTime();

区别:现在,当调用toDateTime() 时,PHPStan 可以安全地假定$object 的类型为Carbon


正如其他人指出的那样:运行该代码也会产生错误,因为您尝试解析的日期格式与输入日期不匹配。但这超出了 PHPStan 的范围,它执行代码

【讨论】:

    【解决方案2】:

    Carbon 对象是已经 DateTime 对象。

    class Carbon extends \DateTime
    

    你可能想要toDateTimeString,但如果你真的想要一个 DateTime 对象,你已经有了,只是在上面撒了一点 Carbon 语法糖。

    如果你真的需要一个 DateTime 对象,->toDate() 函数就是你要找的。​​p>

    https://carbon.nesbot.com/docs/

    返回与当前实例匹配的原生 DateTime PHP 对象。

    【讨论】:

    • 是的,我知道它是 DateTime 的包装,但我尝试了我发布的内容,它产生了错误。也试过->toDate(),仍然得到phpstan错误:无法在Carbon\Carbon|false上调用方法toDate()。你试过代码吗?它真的适合你吗?
    • @user842225 好吧,你已经告诉它期待Y-m-d H:i:s,但你已经提供了Y-m-d\TH:i:s 格式化数据。您提供给 Carbon 的文本与您所说的格式不符。
    【解决方案3】:

    您的格式不正确,因此 Carbon 无法创建时间。您错过了需要转义的 T。

    Carbon::createFromFormat('Y-m-d\TH:i:s', '2021-10-01T00:01:00')->toDateTime();
    

    【讨论】:

    • 请分享更多细节。如果 PHPStan 抛出了最初的错误,是什么让您认为您的代码工作方式不同?
    • 试过了,没用。
    • 没有用怎么办?这个对我有用。尽管正如 ceejayoz 在他的回答中所说,Carbon 已经是一个 DateTime 对象,并且可以这样使用。查看 documentation 了解 DateTime 的所有额外功能。
    • @NicoHaase 因为我已经测试过了。当我在 Tinker 中使用 Carbon\Carbon::createFromFormat('Y-m-d\TH:i:s', '2021-10-01T00:01:00')->toDateTime(); 时,我得到了一个带有 date: 2021-10-01 00:01:00.0 America/New_York (-04:00), 的 DateTime 对象。但是,我对 PHPStan 并不熟悉。
    • 我没有使用PHPStan,所以对它不熟悉。这只修复了格式错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多