Laravel 5.3 return 没有设置 Carbon 日期格式?

Laravel 5.3 Carbon date format is not set on return?

我有我的 VitalSignSet 型号:

class VitalSignSet extends Model
{
  protected $dates = [
        'datetimetaken',
  ];

  . . .
}

现在在我的函数中我有这个函数,它 return 是 json 编码的遇到最新的生命体征集。 (Encounter 与 VitalSignSet 有 hasMany 关系)虽然在 return 之前,我希望 datetimetaken 字段被格式化以便于人类阅读,但只是为了这个特定的方法。 (这就是我没有使用访问器的原因)

public function get(Request $request, Encounter $encounter) {
   // Setting the latest vital sign set
   $encounter->latest_vitals = $encounter->VitalSignSets()
             ->orderBy('datetimetaken','desc')->get()->first();

   // Formatting the date :
   // Works when just returning the date.
   // Does not return in this format when returning the model with the date.
   $encounter->lastest_vitals->datetimetaken->format('M j, Y');

   return $encounter->toJson();
}

上述方法是从js ajax 请求访问的。当我解析并记录响应时,datetimetaken 格式没有改变。 (仍然是 YYYY-mm-dd H:i:s 格式)但是当我 return 只是 $encounter->latest_vitals->datetimetaken; 格式化后,一个字符串是 return 我设置的格式。但是当我 return 包含 VitalSignSet 模型 $encounter->latest_vitals; (json 响应)时,格式为 YYYY-mm-dd。这是为什么?

这是因为您只是在访问数据对象,实际上并未更改它。

不幸的是,无法(我已经找到)编辑模型中 Carbon 实例的格式。这是因为 Laravel 使用相同的格式从数据库解析日期时间,就像将其格式化为字符串一样。

此外,您将无法仅将格式化后的字符串分配给原始字符串,因为 Eloquent 会尝试解析该字符串(但会失败)。

一种方法(如果您 want/need 将密钥保留为 datetime)是将输出转换为数组,编辑值,然后 return 即:

$latestVitals = $encounter->VitalSignSets()
    ->orderBy('datetimetaken', 'desc')->first();

$encounter->latest_vitals = collect($latestVitals->toArray())
    ->pipe(function ($item) use ($latestVitals) {
        $item['datetimetaken'] = $latestVitals->datetimetaken->format('M j, Y');

        return $item;
    });

return $encounter;

如果您不介意将密钥更改为其他密钥(例如 formatted_datetimetaken),您可以为您使用的任何模型添加一个访问器 VitalSignSet:

public function getFormattedDatetimetakenAttribute()
{
    return $this->datetimetaken->format('M j, Y');
}

然后只需使用 append()

$encounter->latest_vitals = $encounter->VitalSignSets()
    ->orderBy('datetimetaken','desc')
    ->first()->append('formatted_datetimetaken');

最后,您可以使用 http://momentjs.com/docs 之类的内容简单地在您的 js 中编辑日期时间。假设您的响应分配给变量 response:

response.latest_vitals.datetimetaken = moment(response.latest_vitals.datetimetaken, "YYYY-MM-DD HH:mm:ss")
            .format("MMM D, YYYY")

希望对您有所帮助!