Actual days between two unix timestamps in PHP
Asked Answered
I

5

1

No this is not the standard +86400 seconds between dates.

$start_time = strtotime("2012-01-15 23:59");
$end_time = strtotime("2012-01-16 00:05");

$daysInBetweenTimestamps = ?

That is the problem I'm currently facing as the timestamps may range in between a 5 minute to 5 hour time span for instance, using standard +86400 to see if it's more than a day would not work, and due to massive amount of indexing that I'm doing I would like to see if there is a more efficient way to check if a new day has started instead of doing a date("d") > $prevDay on the second level.

Updating with the test for the first example:

echo "Absolute Start: ".date("Y-m-d H:i:s",$start)."<br />";
echo "Absolute End: ".date("Y-m-d H:i:s",$end)."<br />";
echo "Interval Used: $interval(seconds) OR ".($interval / 60)."(minutes)<br />";
$numberOfIntervals = ceil(($end - $start) / $interval);
echo "Number of intervals:$numberOfIntervals<br /><br />";
if ($numberOfIntervals > 0){
    for ($i = 0; $i < $numberOfIntervals; $i++){
        $curStart = $start + ($interval * $i);
        $curEnd = $curStart + $interval;
        if ($curEnd > $end){$curEnd = $end;}
        echo "Interval Start DateTime: ".date("Y-m-d H:i:s",$curStart)."<br />";
        echo "Interval End DateTime: ".date("Y-m-d H:i:s",$curEnd)."<br />";
/* EXAMPLE PHP5.3 DateTime START - NOT WORKING */
        $startDiff = new DateTime("@$curStart");
        $endDiff = new DateTime("@$curEnd");
        $diff = $startDiff->diff($endDiff);
        echo $diff->format("%a") . " days<br />";
        if ($diff->format("%a") > 0){
/* EXAMPLE PHP5.3 DateTime END */
/* EXAMPLE Julian START - WORKS */
            $days = unixtojd($curEnd) - unixtojd($curStart);
            echo "Number of days:$days<br />";
            if ($days > 0){
/* EXAMPLE Julian END */
                // Multiple days so the log files are split
                echo "Multiple days so log files are split<br />";
            }else{
                echo "Single day so log files are NOT split<br />";
            }
        }
    }

Output looks as follows:

Absolute Start: 2012-01-25 23:59:00
Absolute End: 2012-01-26 00:02:00
Interval Used: 180(seconds) OR 3(minutes)
Number of intervals:1
Interval Start DateTime: 2012-01-25 23:59:00
Interval End DateTime: 2012-01-26 00:02:00

=== EXAMPLE 1 START ===

0 days
Single day so log files are NOT split

Am I just missing something on the diff?

=== EXAMPLE 1 END ===

=== EXAMPLE 3 START ===

Number of days:1
Multiple days so log files are split

=== EXAMPLE 3 END ===

Interview answered 27/1, 2012 at 15:19 Comment(4)
You didn't tell us what is the number of days between two timestamps if it not the number of times 86400 seconds have elapsed. What output do you want for the example dates you have given. State the problem precisely.Candis
One way to get the dates would be to do a test on start and end, ex: if (date("d",$end_time) > date("d",$start_time)){$multiDays = true;} And then do the final second count of each day and loop between them, is this the most efficient way?`Interview
So the problem is this... Apache log files rotate daily and are saved in format of access_log.2012.11.15, my indexer app would take a unix timestamp start and end time. which could span multiple days. Instead of having php manually read the entire file I make use of unix tools exec command to do this for me... So in my for loop I need to find a way to catch if there is a change of days to look at the new log file. Reason for not reading these log files with php is some of them are 2+gig in size and php has 256mb so I try to index at a small user defined timespanInterview
The exec cmd would return something along the lines of $cmd = "cat /var/log/httpd/access_log." . date("Y", $current_index) . "." . date("m", $current_index) . "." . date("d", $current_index) . "|sed -n \"/$strDate\ $start_time/,/$strDate\ $end_time/p\""; $return = exec($cmd,$returnValue); So I basically use sed between time spans to do all the work for me, but I do have to know if there is a change in actual filenameInterview
G
2

Use the Julian Day

$days = unixtojd($t1) - unixtojd($t2);

or if you are not in UTC...

$days = unixtojd($t1 - $tz) - unixtojd($t2 - $tz);

where $tz is your timezone offset in seconds.

Goren answered 27/1, 2012 at 15:37 Comment(3)
This example does work based on my updated code above with the following updates to the code: See example 2 in updated original postInterview
This appears to be my favorite solution due to it's simplicity, one quick question though, doesn't the php ini directive to set the timezone automatically take into account the additional second offsets? Within my function I don't need to worry about it, but just curious... I thought doing time functions with the ini directive set will automatically adjust?Interview
generally yes, but the Julian date is an astronomical concept, and in astronomy UTC is the only time that mattersGoren
G
2

Use php5.3's DateInterval class:

$now = new DateTime();
$then = new DateTime("@123456789"); //this is your timestamp

$diff = $now->diff($then);

echo "then: " . $then->format("Y-m-d") . "\n";
echo $diff->format("%a") . " days\n";

outputs:

then: 1973-11-29
13937 days
Gladiate answered 27/1, 2012 at 15:28 Comment(1)
Updated my original post with this example above and appears it doesn't work in the format that I have it. Am I just using incorrect syntax by assigning the first PHP datetime?Interview
G
2

Use the Julian Day

$days = unixtojd($t1) - unixtojd($t2);

or if you are not in UTC...

$days = unixtojd($t1 - $tz) - unixtojd($t2 - $tz);

where $tz is your timezone offset in seconds.

Goren answered 27/1, 2012 at 15:37 Comment(3)
This example does work based on my updated code above with the following updates to the code: See example 2 in updated original postInterview
This appears to be my favorite solution due to it's simplicity, one quick question though, doesn't the php ini directive to set the timezone automatically take into account the additional second offsets? Within my function I don't need to worry about it, but just curious... I thought doing time functions with the ini directive set will automatically adjust?Interview
generally yes, but the Julian date is an astronomical concept, and in astronomy UTC is the only time that mattersGoren
B
0

Round the timestamps down to the nearest 86400 seconds, take the difference, and divide by 86400:

$start_time = strtotime("2012-01-15 23:59");
$end_time = strtotime("2012-01-16 00:05");

$start_time -= $start_time % 86400;
$end_time -= $end_time % 86400;

$days = ($end_time - $start_time) / 86400;

The rounding down makes each timestamp midnight of that day, and the division gives you the number of days since the epoch. This will only work in UTC, though.

Bailes answered 27/1, 2012 at 15:24 Comment(0)
C
0
<?php
$start_time = strtotime("2012-01-15 23:59");
$end_time = strtotime("2012-01-16 00:05");

$time_zone = 19800; # My time zone: UTC+0530 hours = UTC+19800 seconds

$days = intval(($end_time + $time_zone) / 86400) -
        intval(($start_time + $time_zone) / 86400);

echo "$days\n";
?>
Candis answered 27/1, 2012 at 15:30 Comment(0)
S
0
$current_time = time(); // or your date as well
$your_date = strtotime("2020-04-27"); //this is my submit time.

$date_diff = $current_time - $your_date;
$num_of_days = round($date_diff / (60 * 60 * 24));

//you have your answer in $num_of_days variable
Superabundant answered 27/4, 2020 at 12:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.