モンモンブログ

技術的な話など

(php) 日付を1日ずつインクリメントして出力

php

2013-01-01, 2013-01-02, ..., 2013-12-31

って具合に、日付をインクリメントしながら文字列として出力したいような場合 DateTime クラス + DateInterval クラス による実装と、
date 関数 + strtotime 関数 による実装と、
2通り考えられるかなーと思います。
どっちのが速いんだ? って思ったので実験してみました。

結論から言っちゃうと date 関数 + strtotime 関数 のが歴然と速かった。3倍〜4倍くらい速かった。まあそんなもんかもね。。。

実験コード

<?php
// 実験回数
$times = 1000;

// DateTime + DateInterval で実験
print "*** DateTime + DateInterval ***\n";
$time1_msec = ceil(microtime(true)*1000);
for ($i = $times; $i > 0; $i--) {
    $start_at = new DateTime('2013-01-01');    // 開始日
    $end_at = new DateTime('2013-12-31');      // 終了日
    $_1day = new DateInterval('P1D');          // 「1日」を表す DateInterval 型インスタンス
    $date = $start_at;
    while ((int)($date->diff($end_at)->format('%R%a')) >= 0) {
        $date_string = $date->format('Y-m-d');
        //print "$date_string\n";
        $date->add($_1day);     // 1日インクリメント
    }
}
$time2_msec = ceil(microtime(true)*1000);
printf("%d msec\n", ($time2_msec - $time1_msec));

// date + strtotime で実験
print "*** date + strtotime ***\n";
$time1_msec = ceil(microtime(true)*1000);
for ($i = $times; $i > 0; $i--) {
    $start_at_string = '2013-01-01';    // 開始日
    $end_at_string = '2013-12-31';      // 終了日
    $start_at_unixtime = strtotime($start_at_string);
    $end_at_unixtime = strtotime($end_at_string);
    $date_unixtime = $start_at_unixtime;
    while ($date_unixtime <= $end_at_unixtime) {
        $date_string = date('Y-m-d', $date_unixtime);
        //print "$date_string\n";
        $date_unixtime += 86400;    // 1日インクリメント
    }
}
$time2_msec = ceil(microtime(true)*1000);
printf("%d msec\n", ($time2_msec - $time1_msec));

実行結果。3回叩いてこんな感じ。

$ php date-iteration.php
*** DateTime + DateInterval ***
3353 msec
*** date + strtotime ***
949 msec

$ php date-iteration.php
*** DateTime + DateInterval ***
4058 msec
*** date + strtotime ***
1113 msec

$ php php-date-iteration.php
*** DateTime + DateInterval ***
3371 msec
*** date + strtotime ***
962 msec

いじょ