【问题标题】:Exception Failed to parse time string异常无法解析时间字符串
【发布时间】:2020-05-28 00:03:27
【问题描述】:

我看了几个标题相似的问题,但我的情况却完全不同。我正在尝试使用 laravel 任务将数据从一个表移动到另一个表。我要从中复制数据的表使用varchar 表示date,而我要复制到的表具有date 列类型。因此,在插入新表之前,我必须将字符串转换为有效的碳日期。不幸的是,旧表的日期以不同的格式混合,所以我必须在插入之前检查和转换,但是在处理特定的字符串格式时我不断收到这个错误

异常:DateTime::__construct():无法在位置 0 (2) 解析时间字符串 (26/02/1991):意外字符

这是我将字符串转换为日期格式的代码的样子

if ($user->profile->date_of_birth === null) {  
    $dob = null;
    Log::info([$user->profile->date_of_birth, $dob]);
} else if (Carbon::parse($user->profile->date_of_birth)->toDateString() == true) {

    $dob = Carbon::parse($user->profile->date_of_birth)->toDateString();
    Log::info([$user->profile->date_of_birth, $dob]);
} else if (Carbon::createFromFormat('d/m/Y',   $user->profile->date_of_birth)->format('Y-m-d') == true) {

    $formattedDate = Carbon::createFromFormat('d/m/Y', $user->profile->date_of_birth)->format('Y-m-d');
    $dob = Carbon::parse($formattedDate)->toDateString();
    Log::info([$user->profile->date_of_birth, $dob]);
}

使用 laravel 的 artisan tinker,我实际上可以将字符串转换为日期格式,如下所示

为什么我在运行任务并遇到特定字符串时不断收到错误消息?

【问题讨论】:

    标签: php laravel php-carbon


    【解决方案1】:

    在 Carbon 中,Carbon::parse('26/02/1991') 不支持这种格式。碳将其视为('m/d/Y')。这就是为什么当你想解析它并转换为toDateString 时会出错的原因。我认为您可以在解析之前更改$dob 格式,然后它应该可以工作。

    // Error
    Carbon::parse('26/02/1991')->toDateString() // Error: DateTime::__construct(): Failed to parse time string (20/02/1995) at position 0 (2): Unexpected character
    
    // Solve
    Carbon::parse('02/26/1991')->toDateString() // "1991-02-26"
    

    您需要更改Profile 模型中date_of_birth 列的格式。因此,只需在您的 Profile 模型上添加一个访问器,就像这样,

    public function getDateOfBirthAttribute()
    {
        [$day, $month, $year] = explode('/', $this->date_of_birth);
        return implode('/', [$month, $day, $year]);
    }
    

    现在,当您调用 $user->profile->date_of_birth 时,它会调用访问器并获取有助于在 Carbon 中解析的所需格式。

    【讨论】:

    • 更改格式正是我想要做的,但由于实际的实时日期是字符串格式26/02/1991,我尝试通过指定格式进行转换,但失败了。还有其他转换字符串格式的方法吗?
    • 最近我更新了我的代码,创建了一个访问器来重新格式化日期
    【解决方案2】:

    我认为失败的是你的

    else if (Carbon::parse($user->profile->date_of_birth)->toDateString() == true)
    

    我会将其包含在 try/catch 中。如果失败,请尝试下一个。

    【讨论】:

    • 从我的日志中我可以看到该块实际上可以正常工作,并且错误消息是特定于导致问题的字符串。
    • 那么不要直接使用Carbon::parse,只需指定不同的可能格式,看看哪一种有效。顺便说一句,插入数据库时​​,您不必指定 ->format('Y-m-d)。 ,您可以简单地传递 Carbon 对象
    • 指定不同的格式是什么意思?您是否建议我只是将日期的字符串表示形式传递给我的新表而不转换它,因为 dob 列是数据类型?或者你的意思是转换每种字符串格式?如果您打算根据各种字符串格式进行转换,那么这正是 if else 检查的原因。如果您能解释更多您建议的方法,我将不胜感激。谢谢。
    • 旧数据库中文本字段的日期格式有哪些不同?
    【解决方案3】:

    使用::createFromFormat('d/m/Y'...) 而不是::parse(),就像您在其他地方所做的那样。

    但听起来->profile 是一个DB 对象,所以我强烈建议不要将->date_of_birth 作为字符串处理,您应该通过将其添加到$dates 字段中来将其保留为Carbon 实例你的模型;然后仅在获得用户输入时使用createFromFormat

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      相关资源
      最近更新 更多