【问题标题】:Laravel Carbon Data MissingLaravel Carbon 数据丢失
【发布时间】:2016-04-30 07:31:59
【问题描述】:

在我的模型中,我有以下内容:

protected $dates = [
    'start',
    'end',
    'created_at',
    'updated_at'
];

我正在使用日期时间选择器插入开始和结束日期,格式如下:

2016-01-23 22:00

没有秒。当我这样做时,我得到了这个错误:

InvalidArgumentException in Carbon.php line 425:
Data missing
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-01-23 22:00') in Model.php line 3015

如果我确实包含秒数,它会起作用。秒对我来说并不重要,我不想将它们包含在我的日期时间选择器字段中。有什么办法可以让我仍然可以将这些字段用作日期字段?

【问题讨论】:

    标签: php laravel format php-carbon


    【解决方案1】:

    tl;博士

    您的日期字符串和您的日期格式不同,您必须更改格式字符串或修改日期字符串以使其匹配。

    说明

    问题

    当 Carbon 的 createFromFormat 函数接收到与传递的格式字符串不匹配的日期字符串时,会出现此错误。更准确地说,这来自 DateTime::createFromFormat 函数,因为 Carbon 只是调用它:

    public static function createFromFormat($format, $time, $tz = null)
    {
        if ($tz !== null) {
            $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
        } else {
            $dt = parent::createFromFormat($format, $time); // Where the error happens.
        }
    
        if ($dt instanceof DateTime) {
            return static::instance($dt);
        }
    
        $errors = static::getLastErrors();
        throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors'])); // Where the exception was thrown.
    }
    

    数据不足

    如果您的日期字符串比这种情况下的格式字符串“短”:

    Carbon::createFromFormat('Y-m-d H:i:s', '2017-01-04 00:52');
    

    碳会抛出:

    Carbon.php 第 425 行中的 InvalidArgumentException:
    数据缺失

    数据过多

    如果您的日期字符串比这种情况下的格式字符串“长”:

     Carbon::createFromFormat('Y-m-d H:i', '2017-01-02 00:27:00');
    

    碳会抛出:

    Carbon.php 第 425 行中的 InvalidArgumentException:
    追踪数据

    引擎盖下

    根据documentation on mutators,默认日期格式为:'Y-m-d H:i:s'。日期处理发生在Model's asDateTime function。在最后一个条件下,getDateFormat function 被调用,这就是自定义格式的来源。默认格式为defined in the Database's Grammar class

    解决方案

    您必须确保日期字符串与格式字符串匹配。

    更改格式字符串

    您可以像这样覆盖默认格式字符串:

    class Event extends Model {
        protected $dateFormat = 'Y-m-d H:i';
    }
    

    这种方法有两个问题:

    • 这将应用于模型的 $dates 数组中定义的每个字段。
    • 您必须以这种格式将数据存储在数据库中。

    编辑和格式化日期字符串

    我推荐的解决方案是日期格式应保持默认'Y-m-d H:i:s',并且您应该填写日期的缺失部分,如下所示:

    public function store(Request $request) {
        $requestData = $request->all();
        $requestData['start_time'] .= ':00';
        $requestData['end_time'] .= ':00';
        $event = new Event($requestData);
        $event->save();
    }
    

    当你想使用日期时,你应该格式化它:

    public function show(Request request, $eventId) {
        $event = Event::findOrFail($eventId);
        $startTime = $event->start_time->format('Y-m-d H:i');
        $endTime = $event->end_time->format('Y-m-d H:i');
    }
    

    当然,字段应该被修改为日期:

    class Event extends Model {
        protected $dates = [
            'start_time',
            'end_time',
            'created_at',
            'updated_at',
            'deleted_at',
        ];
    }
    

    【讨论】:

    • 很好的答案。如此优质的答案。我忍不住评论了这个毫无意义的评论。 :)
    • 我有同样的问题,这个解决方案没有帮助我,你能看看
    • 这对于日期时间来说非常有用,但对于仅日期字段来说则是一个 PITA。为这些添加时间是没有意义的,它们也不能以这种方式存储;但是命名有很大的歧义,因为它们是真正意义上的“日期”
    • 当我使用 Postgresql 时,一些时间值会在没有毫秒部分的情况下保存(当它只是零时)。那么日期格式总是会像上面一样出错。所以最后我只能用该字段的特定访问器来修复它。但是这个解决方案只是忽略了原始数据格式。
    • 答案是完美的,但是 IMO,根据 Laravel 的文档,这不应该是必需的:当一个列被认为是一个日期时,你可以将它的值设置为一个 UNIX 时间戳,日期字符串 (Ymd)、日期时间字符串或 DateTime / Carbon 实例。日期值将正确转换并存储在您的数据库中 请参阅here。现实情况是,根据文档,它不起作用,我们必须求助于这样的黑客。
    【解决方案2】:

    型号

    此功能已禁用,日期时间中的碳模拟 https://laravel.com/docs/5.0/eloquent#date-mutators

    public function getDates()
    {
        return [];
    }
    

    【讨论】:

      【解决方案3】:

      您可以像 Christian 所说的那样在模型中设置 $dateFormat,但是如果您不想将 updated_at 和 created_at 字段隐含到操作中,您可以在将 datetime 对象保存到数据库之前使用事件来“更正”它.

      这里有关于它的官方文档:https://laravel.com/docs/5.2/eloquent#events

      【讨论】:

      • 接受它,因为它给了我更多选择,完全错过了$dateFormat 选项。
      【解决方案4】:

      您需要在模型中将protected $dateFormat 设置为'Y-m-d H:i',请参阅https://laravel.com/docs/5.2/eloquent-mutators#date-mutators

      【讨论】:

        【解决方案5】:

        确保您没有省略数据库中某些行中的“created_at”或“updated_at”字段,这是必需的;如果是这种情况,请删除具有这些空字段的记录或以有效时间戳格式输入值,例如“2018-09-01 15:18:53”。

        【讨论】:

          【解决方案6】:

          这是一种可能性

          您需要检查结果数据列。如果您的列名 'created_at' 或 'updated_at' 为 null,那么它将通过此​​错误。

          如何解决? 首先,您需要使用 Laravel carbon 将数据存储在这两列中。 例如:

          $user = new User();
          $user->created_at = Carbon::now()->setTime(0,0)->format('Y-m-d H:i:s');
          $user->updated_at = Carbon::now()->setTime(0,0)->format('Y-m-d H:i:s');
          $user->save();
          

          就是这样,我希望它会起作用

          快乐编码....

          【讨论】:

            【解决方案7】:

            对我来说,问题在于位于供应商 (vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\SqlServerGrammar.php) 中的 SQLServerGrammar。 SQLServerGramma 中的默认值为 Y-m-d H:i:s.v

            我们扩展了类末尾删除.v

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-10
              • 1970-01-01
              • 1970-01-01
              • 2018-07-10
              • 2021-10-16
              相关资源
              最近更新 更多