LoginSignup
3
1

More than 5 years have passed since last update.

Eloquentを使ってみて、timestampでエラーになる件

Last updated at Posted at 2018-09-03

アプリケーションを移行している際に、DBの処理をEloquentに移行しました。
タイムスタンプの部分でエラーが出続けたため、試行錯誤した結果です。

現象

いまのサービスのtimestamp型に入っているデータで、ミリ秒まで入っているデータとミリ秒がないデータがありPHPのDatetime型にうまく変換してくれない状態です。

データベースのデータを修正する方針でもよかったけど、他のプロジェクトも直す必要があったため、Eloquent側で対応してみました。

登録する際になるエラーを対応した内容です。

対応内容

Modelクラスの$datasにカラムを指定すると、Carbonに変換してくれるみたいですね。

$datesに指定すると、asDateTime関数に処理が任されるため、オーバーライドして、全部ミり秒ありに変換して対応です。


<?php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

class AppEloquent extends Illuminate\Database\Eloquent\Model
{
    public function getDateFormat()
    {
        return 'Y-m-d H:i:s.u';
    }

    /**
     * オーバーライド
     * @param  [type] $value [description]
     * @return [type]        [description]
     */
    protected function asDateTime($value)
    {

        // If this value is already a Carbon instance, we shall just return it as is.
        // This prevents us having to re-instantiate a Carbon instance when we know
        // it already is one, which wouldn't be fulfilled by the DateTime check.
        if ($value instanceof Carbon) {
            return $value;
        }

        // If the value is already a DateTime instance, we will just skip the rest of
        // these checks since they will be a waste of time, and hinder performance
        // when checking the field. We will just return the DateTime right away.
        if ($value instanceof DateTimeInterface) {
            return new Carbon(
                $value->format('Y-m-d H:i:s.u'), $value->getTimezone()
            );
        }

        // If this value is an integer, we will assume it is a UNIX timestamp's value
        // and format a Carbon object from this timestamp. This allows flexibility
        // when defining your date fields as they might be UNIX timestamps here.
        if (is_numeric($value)) {
            return Carbon::createFromTimestamp($value);
        }

        // If the value is in simply year, month, day format, we will instantiate the
        // Carbon instances from that format. Again, this provides for simple date
        // fields on the database, while still supporting Carbonized conversion.
        if ($this->isStandardDateFormat($value)) {
            return Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
        }

        // 追加した内容
        $value = date( $this->getDateFormat(), strtotime($value));

        // Finally, we will just assume this date is in the format used by default on
        // the database connection and use that format to create the Carbon object
        // that is returned back out to the developers after we convert it here.
        return Carbon::createFromFormat(
            str_replace('.v', '.u', $this->getDateFormat()), $value
        );
    }

}
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1