如何将Laravel输出的日期格式更改为JSON?

7cjasjjr  于 2023-03-04  发布在  其他
关注(0)|答案(7)|浏览(342)

我已经在Laravel中构建了一个应用程序,并以下面的格式给出了清晰的返回日期:2015-04-17 00:00:00。我向JSON发送了一个特定的查询,这样我就可以用D3制作一个图形,我想我会喜欢ISO8601('1995-12-17T03:24:00')或其他一些与javascript Date()构造函数配合得很好的格式的日期。
有没有办法改变Laravel端输出到JSON的日期格式?我不确定使用mutator是否是最好的方法,因为它会影响应用程序其他部分的日期。
或者,让JSON输出保持原样,并在将其传递给Date()构造函数之前使用一些javascript字符串方法来处理日期格式,这样做是否更好?哪种方法更有效?
下面是我的模型:

class Issue extends Model {


protected $fillable = [
    'client_id',
    'do',
    'issue_advocate',
    'service_number',
    'issue_location',
    'issue_description',
    'level_of_service',
    'outcome',
    'referral_id',
    'file_stale_date',
    'date_closed',
    'issue_note',
    'staff_hours'
];

protected $dates = [
    'do',
    'date_closed',
    'file_stale_date'
];

public function setDoAttribute($value)
{
    $this->attributes['do'] = Carbon::createFromFormat('F j, Y', $value)->toDateString();
}
}

下面是我的疑问:

$issues = Issue::with('issuetypes')
->select(['do','level_of_service','outcome','id'])
->whereBetween('do',[$lastyear,$now])
->get()->toJson();

我得到的JSON:

[{"do":"2014-12-23 00:00:00","level_of_service":1,"outcome":1,"id":18995,"issuetypes":[{"id":9,"issuetype":"Non Liberty","pivot":{"issue_id":18995,"issuetype_id":9}}]}]
mzillmmw

mzillmmw1#

我知道这是一个老问题,但仍然没有很好的答案。更改protected $dateFormat将影响数据库,而必须覆盖方法serializeDate()

class MyModel extends Eloquent {
    protected function serializeDate(\DateTimeInterface $date) {
        return $date->getTimestamp();
    }
}

或者我自己我选择创造特质

trait UnixTimestampSerializable
{
    protected function serializeDate(\DateTimeInterface $date)
    {
        return $date->getTimestamp();
    }
}

然后加上

class SomeClassWithDates extends Model {    
    use UnixTimestampSerializable;

    ...
}
yjghlzjz

yjghlzjz2#

我对umbrel's answer进行了一些扩展,创建了一个trait,它将DateTimeInstance转换为Carbon示例,以便可以轻松地使用它的通用格式。
在我的特定情况下,我希望根据ISO-8601序列化所有日期。
其特点如下...

use DateTimeInterface;
use Carbon\Carbon;

trait Iso8601Serialization
{
    /**
     * Prepare a date for array / JSON serialization.
     *
     * @param  \DateTimeInterface  $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return Carbon::instance($date)->toIso8601String();
    }

}

从这里我可以简单地在相关的模型上使用它...

class ApiObject extends Model
{
    use Iso8601Serialization;
}

显然,如果你使用不同的格式,你可以更恰当地命名trait,但关键是你可以使用任何Carbon的通用格式,只需用你需要的格式替换toIso8601String()

ohtdti5x

ohtdti5x3#

我强烈建议你使用Carbon类来处理你所有的日期和日期时间变量,它已经附带了Laravel 5,所以你可以随时开始使用。
请在Carbon Repo上查看它,看看您可以使用它做些什么。
例如,您可以将模型中的日期格式设置为

Carbon::parse($model->created_at)->format('d-m-Y')

作为一个好的方法,我建议使用Repository Pattern沿着Presenter和Transformers,通过使用它,你可以定义你希望你的json如何显示/挂载,并选择跳过presenter,以便在你查询时仍然返回你的Eloquent模型。

zy1mlcev

zy1mlcev4#

在任何型号中使用此功能

protected function serializeDate(DateTimeInterface $date){
    return $date->format('Y-m-d h:i:s');
}

结果

inn6fuwd

inn6fuwd5#

当您的模型被序列化为JSON时,您可以通过将模型的**$dateFormat**属性设置为您需要的格式,轻松地更改用于将日期/时间转换为字符串的格式,例如:

class MyModel extends Eloquent {
  protected $dateFormat = 'Y-m-d';
}

您可以在以下格式字符串中使用的不同占位符上找到文档:http://php.net/manual/en/datetime.createfromformat.php

ny6fqffe

ny6fqffe6#

如果你使用常规技术

protected $dateFormat = 'Y-m-d';

protected function serializeDate(DateTimeInterface $date) { ... }

protected $casts = [ "myDate" => "date:Y-m-d" ];

只有当laravel序列化自己的对象时,它才能工作,而且你无论如何都要把这些代码放到所有的模型中,所有的属性。
因此,我的解决方案,你必须(太)把这个代码在所有的日期属性的所有模型,最后,它在所有的情况下工作:

public function getMyDateAttribute()
{
    return substr($this->attributes['my_date'], 0, 10);
}
ulmd4ohb

ulmd4ohb7#

我的用例适用于任何有类似问题的人(在Laravel 9中):数据库中的时间戳存储在EST(而不是UTC)时区(不要问我为什么,这是一个遗留的决定)。我需要所有的数据库查询写入和读取EST中的时间戳。在config/app.php中,我有'timezone' => 'America/New_York'。这照顾到了EST中的写入。为了阅读,我需要下面的内容。
覆盖protected function serializeDate(\DateTimeInterface $date)仅影响使用toArray()或toJson()序列化的Eloquent模型查询,如下所示:

$serializedModelRequest = MyModel::where('some_field', 'some_value')
        ->select('created_at')
        ->first()
        ->toArray();

如果你想让Eloquent Model查询和序列化查询都返回数据库中存储的时区时间戳,你需要覆盖protected function serializeDate(\DateTimeInterface $date)并添加访问器到时间戳字段。你可以在父类、trait或直接添加这些方法到你的模型中。在这里的例子中我使用了trait:

<?php

namespace App\Traits;

trait DbTimestamp
{
    public function getCreatedAtAttribute($value)
    {
        return $value;
    }

    public function getUpdatedAtAttribute($value)
    {
        return $value;
    }

    protected function serializeDate(\DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }
}

我的模型将使用特征:

use App\Traits\DbTimestamp;

class MyModel extends Model
{
    use DbTimestamp;
...

现在,所有三个请求都将返回EST时区的时间戳:

$serializedModelRequest = MyModel::where('some_field', 'some_value')
    ->select('created_at')
    ->first()
    ->toArray();

$eloquentModelRequest = MyModel::where('some_field', 'some_value')
    ->select('created_at')
    ->first();

$queryRequest = DB::table('my_model_table')
    ->where('some_field', '=', 'some_value')
    ->select('created_at')
    ->first();

$response->serialized_created_at = $serializedModelRequest['created_at'];
$response->eloquent_created_at = $eloquentModelRequest->created_at;
$response->query_created_at = $queryRequest->created_at;

相关问题