2016-06-10 128 views
1

我有一个带有日期突变的模型,如created_at。我们假设一个通用的timestamp属性。Laravel5 Eloquent默认日期突变失败,JSON日期输入

当从JSON格式的客户端传递数据,我会得到

{ 
    timestamp: "2016-06-07T22:00:00.000Z" 
} 

该属性将用于设置一些模型,像这样:

$model = new Foo(); 
$model->timestamp = Input::get('timestamp'); 

因为这将触发日期mutator,php Carbon被调用并失败

InvalidArgumentException in Carbon.php line 425 
Unexpected data found. 
Trailing data 

现在,这是不是碳本身的问题,它能够处理JSON格式。如果你想尝试

new Carbon('2016-06-07T22:00:00.000Z'); 

你真的会得到预期的结果。

从我看到的问题出发,来自一个奇怪的雄辩行为。看到这个痕迹从上述InvalidArgumentException in Carbon.php line 425

in Carbon.php line 425 
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-06-07T22:00:00.000Z') in Model.php line 2915 
at Model->asDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2871 
at Model->fromDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2826 
at Model->setAttribute('timestamp', '2016-06-07T22:00:00.000Z') in Model.php line 3351 

雄辩试图createFromFormat传递格式错误其犯规反映实际的JSON格式,这是造成碳例外。

另一方面,像上面提到的new Carbon($jsonDate)这样的简单调用在这种情况下可以正常工作。

  1. 我该如何解决这个问题?
  2. 这不应该是一个雄辩的错误?

== ==编辑

我没有代码的任何突变自己。我使用的是默认的日期存取器,像这样:

public function getDates() { 
    return ['timestamp']; 
} 
+0

这应该按预期工作。你如何定义mutator?你可以发布Model代码和'Input :: get('timestamp)'(我假设它不是一个对象)的确切值。我将离开我在这里设置的mutator来测试:'public function setTimestampAttribute($ value){$ this-> attributes ['timestamp'] = new \ Carbon \ Carbon($ value); }'和控制器代码:'$ obj-> timestamp ='2016-06-07T22:00:00.000Z';' –

+0

请发布您的mutator。 –

+0

我没有使用任何自定义的mutator,请参阅编辑。 – brazorf

回答

1

雄辩分析你给它的日期,在属性中getDates功能设置。

在它的分析有四个步骤:(见澄清Modal.phpasDateTime方法,代码是很好说:https://github.com/illuminate/database/blob/master/Eloquent/Model.php#L2898

  1. 如果它已经是一个碳例如,使用
  2. 如果为实现DateTimeInterface一个实例,使用
  3. 如果是数字,解析为Unix时间戳
  4. 如果它是一个简单的年,月,日的格式(由正则表达式试过)使用
  5. 如果以上都不是,创建与格式您的默认

指定在你的情况下碳例子,1-4不匹配,所以它会试图5.

你有没有自定义在模型中指定的dateFormat,因此它使用适用于您正在使用的数据库连接类型的默认日期格式。您可以通过添加一个$ DATEFORMAT变量模型覆盖此:

protected $dateFormat = 'U';

但你的正常时间戳可能是正确的格式了。所以这个解决方案不适合你。

在你的情况我也只是做: $model->timestamp = Carbon::parse(Input::get('timestamp'));

或者使用Carbon::createFromFormat()用适当的格式。

我不完全知道他们为什么不直接用Carbon解析它。我想这是更容易出错,更难控制的。采用不同的国际格式,您可能会得到意想不到的结果(月份和日期切换等)。它也可能比他们目前的方法慢。