Фактические дни между двумя временными метками unix в PHP

Нет, это не стандарт +86400 секунд между датами.

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

$daysInBetweenTimestamps = ?

Это проблема, с которой я сейчас сталкиваюсь, поскольку временные метки могут варьироваться, например, в диапазоне от 5 минут до 5 часов, используя стандарт +86400, чтобы увидеть, не будет ли работать более суток, и из-за огромного количества индексации что я делаю, я хотел бы посмотреть, есть ли более эффективный способ проверить, начался ли новый день, вместо того, чтобы делать дату ("d") > $prevDay на втором уровне.

Обновление с тестом для первого примера:

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 />";
            }
        }
    }

Вывод выглядит следующим образом:

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

=== ПРИМЕР 1 НАЧАЛО ===

0 days
Single day so log files are NOT split

Я что-то пропустил в дифференциале?

=== ПРИМЕР 1 КОНЕЦ ===

=== ПРИМЕР 3 НАЧАЛО ===

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

=== ПРИМЕР 3 КОНЕЦ ===


person Will H    schedule 27.01.2012    source источник
comment
Вы не сказали нам, каково количество дней между двумя отметками времени, если это не количество прошедших 86400 секунд. Какой вывод вы хотите для приведенных вами примеров дат. Точно сформулируйте проблему.   -  person Susam Pal    schedule 27.01.2012
comment
Один из способов получить даты — выполнить тест в начале и в конце, например: if (date("d",$end_time) > date("d",$start_time)){$multiDays = true;} А затем выполнить последний подсчет секунд каждого дня и цикл между ними, это самый эффективный способ?`   -  person Will H    schedule 27.01.2012
comment
Итак, проблема в следующем... Файлы журналов Apache меняются ежедневно и сохраняются в формате access_log.2012.11.15, мое приложение-индексатор будет принимать время начала и окончания временной метки unix. который может длиться несколько дней. Вместо того, чтобы php вручную читал весь файл, я использую команду unix tools exec, чтобы сделать это для меня... Поэтому в моем цикле for мне нужно найти способ поймать, если есть изменение дней, чтобы посмотреть новый лог-файл. Причина того, что эти файлы журналов не читаются с помощью php, заключается в том, что некоторые из них имеют размер 2+ гигабайта, а php имеет 256 МБ, поэтому я пытаюсь индексировать в небольшой пользовательский промежуток времени.   -  person Will H    schedule 27.01.2012
comment
exec cmd вернет что-то вроде $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);, поэтому я в основном использую sed между временными промежутками, чтобы сделать всю работу за меня, но мне нужно знать, есть ли изменение в фактическом имени файла.   -  person Will H    schedule 27.01.2012


Ответы (3)


Используйте Юлианский день

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

или если вы не в UTC...

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

где $tz — смещение вашего часового пояса в секундах.

person Rob Agar    schedule 27.01.2012
comment
Этот пример работает на основе моего обновленного кода выше со следующими обновлениями кода: См. пример 2 в обновленном исходном сообщении - person Will H; 27.01.2012
comment
Кажется, это мое любимое решение из-за его простоты, хотя один быстрый вопрос: разве директива php ini для установки часового пояса автоматически не учитывает дополнительные секундные смещения? В моей функции мне не нужно об этом беспокоиться, но просто любопытно ... Я думал, что выполнение функций времени с набором директив ini будет автоматически корректироваться? - person Will H; 27.01.2012
comment
в целом да, но юлианская дата - это астрономическое понятие, а в астрономии UTC - единственное время, которое имеет значение - person Rob Agar; 28.01.2012

Используйте класс php5.3 DateInterval:

$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";

выходы:

then: 1973-11-29
13937 days
person Maerlyn    schedule 27.01.2012
comment
Обновил мой исходный пост этим примером выше и, похоже, он не работает в том формате, в котором он у меня есть. Я просто использую неправильный синтаксис, назначая первую дату и время PHP? - person Will H; 27.01.2012

Округлите временные метки до ближайших 86400 секунд, возьмите разницу и разделите на 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;

Округление вниз делает каждую отметку времени полночью этого дня, а деление дает вам количество дней, прошедших с эпохи. Однако это будет работать только в UTC.

person Alnitak    schedule 27.01.2012