PHP DateIntervalの合計秒数を計算します


99

2つの日付間の合計秒数を計算する最良の方法は何ですか?これまでのところ、私は次の線に沿って何かを試しました:

$delta   = $date->diff(new DateTime('now'));
$seconds = $delta->days * 60 * 60 * 24;

ただし、daysDateIntervalオブジェクトのプロパティは、現在のPHP5.3ビルドでは壊れているようです(少なくともWindowsでは、常に同じ6015値を返します)。私はまた、毎月の日数(30程度)、うるう年などを保存できない方法でそれを試みました:

$seconds = ($delta->s)
         + ($delta->i * 60)
         + ($delta->h * 60 * 60)
         + ($delta->d * 60 * 60 * 24)
         + ($delta->m * 60 * 60 * 24 * 30)
         + ($delta->y * 60 * 60 * 24 * 365);

しかし、私はこの中途半端なソリューションを使用することに本当に満足していません。


の結果は$delta->format("%r%s")何ですか?
warrenm 2010

1
@warrenmの問題formatは、秒数が0で分数が1である場合、$delta->format("%r%s")0であることが判明することです:(
Vadim Samokhin

4
さらに悪いことに、上記の正確なコードを貼り付けたコーダーからのコードレビューで見つかった欠陥を誰かが修正していると言うと、毎月30日ではなく、毎年365日ではありません。:) [編集:そして、そのコーダーは私自身だったかもしれません!]
taiganaut

回答:


205

代わりにタイムスタンプを比較できませんか?

$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()

11
私はRTFMをしなかったと思います...これは私が探していたものです。どうもありがとう!
efritz

3
+1:素晴らしく、きれいです!このgetTimestamp()メソッドはPHP 5.3.0以降で使用できることに注意してください。
Sk8erPeter 2012年

6
がらくた共有ホストでPHP 5.2を使用できformat('U')ない場合は、の代わりにを使用してくださいgetTimestamp()
サイボーグ

4
あなたのソリューションは2038年のバグと互換性がありません
ジャックM.

9
@JackM。知ってよかった。2037年には、現在ビルド中のものが何も実行されないことを願っています。2038年のバグセーフな代替ソリューションを提供してください。
Ben

34

この関数を使用すると、DateIntervalオブジェクトから合計時間を秒単位で取得できます

/**
 * @param DateInterval $dateInterval
 * @return int seconds
 */
function dateIntervalToSeconds($dateInterval)
{
    $reference = new DateTimeImmutable;
    $endTime = $reference->add($dateInterval);

    return $endTime->getTimestamp() - $reference->getTimestamp();
}

2
DateTimeImmutableはPHP 5.5以降でのみ使用できることに注意してください。
hschmieder、2015年

私はあなたのリターン変数を置き換えるために持っていると思う$endTime$reference、これは私の将来の間隔日時値とマイナスの結果を与えているので、お互いに。
AlexioVay

タイムスタンプも秒単位ではないと思います。PHP DateTime = Horrific API
Quadrivium 2018年

5

あなたはこのようにそれを行うことができます:

$currentTime = time();
$timeInPast = strtotime("2009-01-01 00:00:00");

$differenceInSeconds = $currentTime - $timeInPast;

time()は、エポック時刻(1970-01-01T00:00:00)からの現在の時刻を秒単位で返します。strtotimeも同じですが、指定した特定の日付/時刻に基づいています。


4
static function getIntervalUnits($interval, $unit)
{
    // Day
    $total = $interval->format('%a');
    if ($unit == TimeZoneCalc::Days)
        return $total;
    //hour
    $total = ($total * 24) + ($interval->h );
    if ($unit == TimeZoneCalc::Hours)
        return $total;
    //min
    $total = ($total * 60) + ($interval->i );
    if ($unit == TimeZoneCalc::Minutes)
        return $total;  
    //sec
    $total = ($total * 60) + ($interval->s );
    if ($unit == TimeZoneCalc::Seconds)
        return $total;  

    return false;
}

0

必要なものがすでにクラスとして存在しているときは、いつも気持ちがいいです。あなたのケースでは、合計秒数が必要です。それからクラスを作ってみませんか?コードは次のようになります。

(new TotalFullSeconds(
    new IntervalFromRange(
        new DateTimeFromISO8601String('2017-07-03T14:27:39+00:00'),
        new DateTimeFromISO8601String('2017-07-05T14:27:39+00:00')
    )
))
    ->value()

直感的であるだけでなく、IDEのオートコンプリート機能も利用できます。

より便利な実装については、このライブラリをチェックしてください。


-8

(60 * 60の代わりに-3600に入れる)ハード番号を入れるだけでよいので、毎回それらを計算する必要はありません。

編集-コメントに基づいて数値を修正しました。


これで問題ありません。PHPではおそらく1秒の速度で実行されますが、それでも上記の例と同じ計算ミスが残ります。
-efritz、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.