Расчет даты PHP

Каков наилучший (независимый от формата даты способ) в PHP для расчета разницы в днях между двумя датами в указанном формате.

Я попробовал следующую функцию:

function get_date_offset($start_date, $end_date)
{
  $start_time = strtotime($start_date);
  $end_time = strtotime($end_date);
  return round(($end_time-$start_time)/(3600*24));
}

Он работает нормально в Linux, но при запуске под Windows возвращается strtotime ''.

РЕДАКТИРОВАТЬ:

Дата ввода находится в формате мм / дд / гггг, но я хотел бы, чтобы он принимал формат $ в качестве параметра.

Мне нужна только разница в днях.

Как выглядят $ start_date и $ end_date?

Vilx- 23.12.2008 14:38

Кстати - это не лучший способ. Рассмотрим, например, вычитание 23:00 22.12.2008 из 01:00 23.12.2008. У вас будет 2 часа. Ваш алгоритм скажет - 0 дней. Но это будет на следующий день!

Vilx- 23.12.2008 14:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
2
7 048
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Я не уверен, что считается Лучший, поскольку в PHP нет встроенной функции для этого, но некоторые люди использовали грегориантойд (), например, в это сообщение на форуме.

Проблема с PHP в том, что у него нет определенного типа DateTime. Вы можете использовать временную метку Unix или встроенный класс DateTime, но их функциональность довольно ограничена. Я ожидаю, что должны быть некоторые сторонние классы с более широкой поддержкой вычислений даты и времени, но я не искал этого.

Использование временных меток Unix для вычисления даты (не времени) также сложно. Вам придется отказаться от временной части, но простой сброс на 00:00 небезопасен из-за перехода на летнее время (DST). Летнее время приводит к тому, что в году есть два дня, а не ровно 24 часа. Таким образом, при сложении / вычитании дат вы можете получить значение, которое не делится равномерно на 3600 * 24.

Я бы посоветовал поискать какой-нибудь сторонний класс, который имеет надлежащую поддержку для всего этого. Вычисления даты и времени просто ужасны в своем безобразии. :П

Класс PEAR Date предлагает всевозможные функции для поиска различий между датами, а также около 1000 других вещей. Документы для него: здесь...

В Zend Framework есть класс Zend_Date для работы с «математикой дат». Он работает с ограничениями временных меток, специфичных для системы, с помощью расширения BCMath, или, если он недоступен, ограничивает временные метки максимальным значением с плавающей запятой для вашей системы.

// example printing difference in days
require('Zend/Date.php');

$date1 = new Zend_Date();
$date1->set(2, Zend_Date::MONTH);
$date1->set(27, Zend_Date::DAY);
$date1->set(2008, Zend_Date::YEAR);

$date2 = new Zend_Date();
$date2->set(3, Zend_Date::MONTH);
$date2->set(3, Zend_Date::DAY);
$date2->set(2008, Zend_Date::YEAR);

echo ($date2->getTimestamp() - $date1->getTimestamp()) / (3600*24);

Да, определенно лучший ответ на данный момент.

OIS 23.12.2008 22:43
Ответ принят как подходящий

Если вы не хотите или не можете использовать пакет Zend Framework или Pear, попробуйте эту функцию, надеюсь, это поможет:

function dateDifference($date1, $date2)
{
    $d1 = (is_string($date1) ? strtotime($date1) : $date1);
    $d2 = (is_string($date2) ? strtotime($date2) : $date2);

    $diff_secs = abs($d1 - $d2);
    $base_year = min(date("Y", $d1), date("Y", $d2));

    $diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);

    return array
    (
        "years"         => abs(substr(date('Ymd', $d1) - date('Ymd', $d2), 0, -4)),
        "months_total"  => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
        "months"        => date("n", $diff) - 1,
        "days_total"    => floor($diff_secs / (3600 * 24)),
        "days"          => date("j", $diff) - 1,
        "hours_total"   => floor($diff_secs / 3600),
        "hours"         => date("G", $diff),
        "minutes_total" => floor($diff_secs / 60),
        "minutes"       => (int) date("i", $diff),
        "seconds_total" => $diff_secs,
        "seconds"       => (int) date("s", $diff)
    );
}

Не будем перегибать палку, ребята.

$d1 = strtotime($first_date);
$d2 = strtotime($second_date);
$delta = $d2 - $d1;
$num_days = ($delta / 86400);

Это то же самое, что и в вопросе. Проблема в том, что strtotime не работает в окне Windows так же, как в Linux, и что он не может анализировать произвольные форматы даты.

Marko 24.12.2008 15:01

gregoriantojd () дает те же результаты, что и использование strtotime (), см. этот блог, чтобы узнать, как это сделать:

http://www.phpro.org/examples/Calculate-Age-With-PHP.html

Следующее работает для меня. Поверьте, я нашел его где-то в документации php.net.

* Edit - Woops, не видел сообщение csl. Это точная функция из его ссылки, должно быть, я ее нашел. ;)

//Find the difference between two dates
function dateDiff($startDate, $endDate)
{
    // Parse dates for conversion
    $startArry = date_parse($startDate);
    $endArry = date_parse($endDate);

    // Convert dates to Julian Days
    $start_date = gregoriantojd($startArry["month"], $startArry["day"], $startArry["year"]);
    $end_date = gregoriantojd($endArry["month"], $endArry["day"], $endArry["year"]);

    // Return difference
    return round(($end_date - $start_date), 0);
}

Я пытался вычислить разницу двух дат, чтобы показать продолжительность события. Большинство функций, указанных в задаче, не работают, если событие длится с пятницы с 17:00 до воскресенья в 15:00. Моей целью было найти разницу между такими датами, как:

date('Ymd',$end)-date('Tmd',$begining);

Но это, скорее всего, потерпит неудачу, потому что в году нет 99 месяцев и 99 дней в месяце. Я мог бы преобразовать строку даты в временную метку UNIX и разделить ее на 60 * 60 * 12, но в некоторые дни количество часов больше или меньше, а иногда бывает и так. Поэтому я создал свою собственную функцию, используя getdate (), функцию, которая возвращает массив информации о метке времени.

/*
 * datediff($first,$last)
 * $first - unix timestamp or string aksepted by strtotime()
 * $last - unix timestamp or string aksepted by strtotime()
 * 
 * return - the difference in days betveen the two dates
 */
function datediff($first,$last){
 $first = is_numeric($first) ? $first : strtotime($first);
 $last  = is_numeric($last ) ? $last  : strtotime($last );
 if ($last<$first){
  // Can't calculate negative difference in dates
  return -1;
 }
 $first = getdate($first);
 $last =  getdate($last );
 // find the difference in days since the start of the year
 $datediff = $last['yday'] - $first['yday'];
 // if the years do not match add the appropriate number of days.
 $yearCountedFrom = $first['year'];
 while($last['year'] != $yearCountedFrom ){
  // Take leap years into account
  if ( $yearCountedFrom % 4 == 0 && $yearCountedFrom != 1900 && $yearCountedFrom != 2100 ){
   //leap year
   $datediff += 366;
  }else{
   $datediff += 365;
  }
  $yearCountedFrom++;
 }
 return $datediff;
}

Что касается функции GregorianToJD (), она может сработать, но мне немного не по себе, так как я не понимаю, как она работает.

Вычислите разницу между двумя датами (и временем) с помощью Php. На следующей странице представлен ряд различных методов (всего 7) для вычисления даты / времени с использованием Php, чтобы определить разницу во времени (часы, муниты), днях, месяцах или годах между двумя датами.

См. Php Date Time - 7 методов расчета разницы между двумя датами

В PHP 5.2 представлены классы DateTime и DateInterval, которые упрощают эту задачу:

function get_date_offset($start_date, $end_date)
{
    $start_time = new DateTime($start_date);
    $end_time   = new DateTime($end_date);
    $interval   = $end_time->diff($start_time);
    return $interval->format('%a days');
}

Другие вопросы по теме