2038年問題にLaravelで対応する方法。UNIXタイムスタンプで保存する

Laravelで2038年問題に備える
目次

2038年問題に対応する

MySQLは2038年問題を抱えています。

協定世界時における1970年1月1日0時0分0秒日本標準時では1970年1月1日9時0分0秒)から2,147,483,647秒を経過した、2038年1月19日3時14分7秒(日本標準時では2038年1月19日12時14分7秒、閏秒は考慮していない)を過ぎると、この値がオーバーフローし、と扱われる[注釈 2]ため、もし時刻を正しく扱えていることを前提としたコードがあれば、誤動作する。

つまり、2038-01-19 12:14:07以降の日時だと0000-00-00 00:00:00になる問題です。

ぎゅう

デフォルトのままだと、いつか詰みますね

この対応策としては、下記の二つになります。

  • DATETIME型を利用する
  • INT型でUNIXタイムスタンプを管理する

DATETIME型は指定するだけなので、簡単ですよね

ですが今回は、INT型のUNIXタイムスタンプで管理したいと思います。

UNIXタイムスタンプで管理する。

なぜ採用するかというと、INT型の方が早いためです。

unixタイムスタンプは2147483647のように数字で日時を管理します。

数字だけで文字を入れていない分高速で処理できます。

また、どの国の日時にも変換可能なのでグローバルに対応したいときにも便利です。

でもどうやってやるか?って日本の記事だとあんまり見かけないので、まとめたいと思います

テーブル作成時

unixタイムスタンプは2147483647のように数字で日時を管理します。

migrationファイルを生成時、デフォルトだと下記のtimestamps()が追加されています。

$table->timestamps();

この箇所を削除し、代わりにint型で対応します。

$table->integer('created_at');
$table->integer('updated_at');

モデルの設定を変更する

int型にしましたが、デフォルトでは通常のタイムスタンプのままです。

そのため、保存形式を変えてあげます。

protected $dateFormat = 'U';

モデルに上記を追加して、保存フォーマットを変更します。
Unixの’U’を追加するだけで大丈夫です。

protected function getDateFormat()
{
    return 'U';
}

上記のやり方でオーバーライドする方法もあるようです。

基本的には$dateFormatを変更するやり方で問題ないでしょう

これだけでunixタイムスタンプ形式で保存されます。

変換する方法

通常のタイムスタンプからunix型に変更するときも同じです。

$start = new Carbon('2022-01-01 00:00:00');
$startUnix = $start->format('U');

逆にunix型から変換するときは、createFromTimestampで生成します

Carbon::createFromTimestamp($post->created_at)

検索する際

日付をintで表現をしているため、検索する際も形式を合わせます。

where('created_at', '>', Carbon::now()->getTimestamp())

このようにUnix タイムスタンプを取得を取得して検索をします。

終わりに

考えなしにデフォルトのままサービスを運用すると、重いし、2038問題あるしで 後々困ります

なので、新規案件の際は気をつけていきましょう!

検索負荷も軽減できるので、積極的に採用した方がよいです。

ぎゅう
WEBエンジニア
渋谷でWEBエンジニアとして働く。
LaravelとVue.jsをよく取り扱い、誰でも仕様が伝わるコードを書くことを得意とする。
先輩だろうがプルリクにコメントをして、リファクタしまくる仕様伝わるコード書くマン
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる