【问题标题】:Carbon in Laravel 4 InvalidArgumentException - Unexpected data found. Trailing dataLaravel 4 InvalidArgumentException 中的 Carbon - 发现意外数据。尾随数据
【发布时间】:2014-08-01 20:06:45
【问题描述】:

我正在尝试获取 DB::raw("DATE_FORMAT(created_at, '%m-%d-%Y %r') AS created_at") 的 Eloquent 查询结果,但每次我从 Carbon 收到此异常:

InvalidArgumentException
Unexpected data found. Trailing data

如果我将其更改为 created_at 而不是使用 MySQL 的 DATE_FORMAT() 函数,那么它可以毫无问题地获取数据。

我不仅以前没有问题地完成过这种日期格式,而且我检查了数据库表中的每个字段(这个种子只有 10 个)并且每个都是标准的有效日期,所以我想知道为什么Carbon 正在迎头赶上。

在 Laravel 4.1 中运行。

【问题讨论】:

    标签: php mysql laravel-4 php-carbon


    【解决方案1】:

    Eloquent 查询结果(模型)中,每个date 字段都是carbon object,这意味着,如果您查询包含任何timestamp 字段的模型,例如created_atupdated_at(基本上创建在迁移过程中使用timestamps())和deleted_atLaravel 将它们转换为Carbon 对象,您可以使用Carbon 的任何公共方法,例如:

    $user = User::find(1);
    
    // '2014-04-20 19:02:09' will become 'Apr 20, 2014'
    $user->created_at->toFormattedDateString();
    

    因此,您可以在模型中可用的timestamp 字段上直接使用Carbon 的任何公共方法。如果你试试这个:

    dd($user->created_at);
    

    那么输出将是:

    object(Carbon\Carbon)[456]
      public 'date' => string '2014-04-20 19:02:09' (length=19)
      public 'timezone_type' => int 3
      public 'timezone' => string 'UTC' (length=3)
    

    所以,如果你想format 一个日期,你可以使用:

    // outputs like: 'Sunday 20th of April 2014 07:02:09 PM'
    $user->created_at->format('l jS \\of F Y h:i:s A')
    

    更新:

    如果你想改变这种行为,意味着如果你想告诉Laravel,哪些字段应该自动转换为Carbon对象,那么你可以通过在你的模型中创建一个方法来覆盖它:

    public function getDates()
    {
        // only this field will be converted to Carbon
        return array('updated_at');
    }
    

    要完全禁用日期突变,只需从 getDates 方法返回一个空数组。更多详情,请查看Laravel 网站上的Date Mutators

    【讨论】:

    • 如何在原始查询中执行此操作?我需要获取相当多的行和几个不同的列,这就是我寻求提前格式化日期的原因。
    • 在您的模型中,您可以通过添加 public function getDates()` 作为日期变更器来覆盖它。 `
    【解决方案2】:

    我意识到最初的问题是指 MySQL,但我在使用 MSSQL 时遇到了同样的错误。问题原来是 MSSQL 的 datetime 列类型的精度为 0.001 秒,但我将模型的格式设置为无精度:

    protected function getDateFormat()
    {
        return 'Y-m-d G:i:s';
    }
    

    通过使用较新的 DateTime2 列类型并关闭精度,我修复了错误。即

    datetime2(0)
    

    当然,您也可以更改 getDateFormat 中的格式。

    【讨论】:

      【解决方案3】:

      如果它对其他人有帮助,我在尝试复制日期时遇到了同样的错误。

      $user->last_login = Carbon::now();
      
      if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
          // This is the users first login
          $user->first_login = $user->last_login; // FAILS!
      }
      

      原来 Laravel 将 $user-&gt;last_login 的值转换为 DateTime+Timezone 字符串。它不再是 Carbon 对象。

      您可以通过使用单个 Carbon 对象的副本(下面的示例)或通过在底层模型上设置修改器(设置器)来修复错误。

      $now = Carbon::now();
      $user->last_login = $now;
      
      if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
          // This is the users first login
          $user->first_login = $now;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-10
        • 1970-01-01
        相关资源
        最近更新 更多