ランダムな日付だけでなくランダムな時刻も同時に生成
こんにちは。2038年問題まであと18年ですね。
今回は適当な日付と時間をランダムに作るPHPのコードサンプルです。
一応2038年問題も考慮して、date関数などは使わずにやりたいと思います。
DateTimeクラスを使えばいいじゃない...という意見もありますが、フレームワークやライブラリが使えるなら「むしろCarbonでいいじゃない」ということでCarbonを使っております。
Laravelとかではお馴染みですね。CarbonはDateTimeクラスをオーバーラップした日付操作ライブラリなので、DateTimeクラスの上位互換と言えそうです。
仮に、何かしらのテスト用データを大量に挿入しつつ、更新日時をランダムに生成したいとします。Laravelのseedsにそういったコードを書いてみます。
<?php
use Illuminate\Database\Seeder;
// Carbonを使うための宣言
use Carbon\Carbon;
// Products(商品)テーブルというものがあるとする
class ProductsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// ランダムに生成したい日時の期間を決める
// 仮に 2001-01-01 00:00:00 から 2020-05-01 23:59:59 とする
// 日付と時刻を format('U') でUNIXタイムスタンプへ変換しておく
$start = new Carbon('2001-01-01 00:00:00');
$startUnix = $start->format('U'); // 978274800 に変換される
$end = new Carbon('2020-05-01 23:59:59');
$endUnix = $end->format('U'); // 1588345199 に変換される
// ループで id=1 から id=1000 までの商品を自動で登録
for($i=1;$i<=1000;$i++){
// 用意しておいた開始・終了日時のUNIXタイムスタンプを使用してランダムな数値を生成
$randDate = mt_rand($startUnix, $endUnix);
// ランダムなUNIXタイムスタンプを引数にしてインスタンスを作成
$date = new Carbon($randDate);
DB::table('products')->insert([
'id' => $i,
'name' => '商品名_'.$i,
'created_at' => '2001-01-01 00:00:00',
// 日付&時刻は必要に応じてフォーマットを変更可
'updated_at' => $date->format('Y-m-d H:i:s'),
]);
}
}
}
日付や時間のフォーマットは基本的に date()
の関数と同じパラメータが使えます。
date() -> パラメータ format
なお乱数を発生させるときは rand()
ではなく mt_rand()
を使う方が実行速度も速くて良いそうです。(randの4倍以上)
暗号化に使うのはいずれも推奨されませんが、文字通りランダムな値を得るためだけであれば問題ありません。
参考URL:
rand — 乱数を生成する
mt_rand — メルセンヌ・ツイスター乱数生成器を介して乱数値を生成する
【PHP入門】ランダムな数値・文字列を生成する(rand、mt_rand)
date — ローカルの日付/時刻を書式化する
DateTime クラス
テストデータ用にランダムな日付文字列をn個生成する
特定の2つの日付の間から、ランダムに1日を取得
【PHP】DateTimeでの日時取得とフォーマット方法まとめ
PHPで2038年問題を回避するには?すぐできる対策とコード例
「2038年問題」を華麗に解決!~エンジニアの仕事~
DateTimeクラスで日付文字列とUNIX時間(タイムスタンプ)を相互変換するときのまとめ
DateTime クラスのまとめメモ
PHPで日付時刻処理を書くならCarbonを使うべき