Я думаю, что возвращение отрицательного числа дней предоставляет соответствующую информацию. И вы должны использовать $your_date-$now, если вы хотите, чтобы будущая дата возвращала положительное целое число.
Тим
23
Как насчет високосных секунд? Не все дни имеют ровно 24 * 60 * 60 секунд. Этот код может быть достаточным для практических целей, но он не является точным в очень редких крайних случаях.
Бенджамин Бриззи
49
Забудьте о високосных секундах (нет, на самом деле учитывайте их тоже), но это НЕ учитывает изменения летнего времени! Он может быть выключен на целый день за этими границами каждый год. Вам нужно использовать классы DateTime.
Леви
6
@billynoah Извините, я никогда не возвращался, чтобы обновить свой комментарий. Вы должны быть осторожны с летними часовыми поясами. Если сравнить дату с переходом на летнее время без даты, например, вместо возврата 7 дней, возвращается 6,9 дня. Принимая слово возвращается 6 вместо 7.
Алекс Анджелико
4
Strtotime () не только терпит неудачу через 20 лет, но и непригоден прямо сейчас. ОП указывает Даты, а не Время. Даты могут быть довольно старыми. Вот более простой ответ: $ NumberDays = gregoriantojd ($ EndM, $ EndD, $ EndY) - gregoriantojd ($ StartM, $ StartD, $ StartY); (для инклюзивного ассортимента). В отличие от класса Datetime, от григорианского до юлианского доступно в v4 и выше. Допустимый диапазон: от 4714 до н.э. до 9999 г. н.э. Остерегайтесь порядка в стиле фанк-параметров (как будто вам нужно это предупреждение для php).
Гай Гордон
524
Если вы используете PHP 5.3 >, это, безусловно, самый точный способ расчета разницы:
Обратите внимание, что поскольку речь идет о временных интервалах, а не конкретных точках времени, синтаксис формата отличается от синтаксиса date () и strftime (). Синтаксис временного интервала можно найти здесь: php.net/manual/en/dateinterval.format.php
Эндрю
1
или в моем случае число дней между: $ date2-> diff ($ date1) -> format ("% a") - 1
xeo
13
Имейте в виду, что если у вас есть время в ваших датах, это не сработает, как вы могли ожидать. Например, если у вас есть интервал 23:30 часов ... и они в разные дни, разница будет равна 0.
Layke
20
Если вам нужно относительное количество дней (отрицательное, когда $date1перед $date2), используйте $diff = $date2->diff($date1)->format("%r%a");вместо этого.
Socce
1
Какой формат даты в DateTime("2010-07-06")?, Это Y-m-dили Y-d-m?, Каков формат DateTimeпараметра. какой день?
Да, это кажется лучше, чем принятый ответ, который в некоторых случаях не работает. Как: $ from = '2014-03-01'; $ к = '2014-03-31';
MBozic
1
Я согласен, так легко следовать и прекрасно работает !!! Только не забудьте использовать функцию date_default_timezone_set (), иначе она даст вам странные результаты, основанные на времени UTC.
Зекдуд
2
Эта функция не прошла 0 из 14603 тестов между 1980 и 2020 годами.
LSerni
128
Преобразуйте свои даты в метки времени Unix, затем вычтите одно из другого. Это даст вам разницу в секундах, которую вы поделите на 86400 (количество секунд в дне), чтобы получить приблизительное количество дней в этом диапазоне.
Если ваши даты в формате 25.1.2010, 01/25/2010или 2010-01-25, вы можете использовать strtotimeфункцию:
Использование ceilраундов количество дней до следующего полного дня. использованиеfloor вместо этого, если вы хотите получить количество полных дней между этими двумя датами.
Если ваши даты уже в формате метки времени Unix, вы можете пропустить преобразование и просто выполнить $days_betweenчасть. Для более экзотических форматов дат вам, возможно, придется выполнить какой-то пользовательский анализ, чтобы сделать его правильным.
@ toon81 - мы используем метки времени Unix, чтобы избежать таких беспорядков! ;)
Аластер
6
Позвольте мне уточнить: скажем, сегодня утром в 3 часа утра почти вся Европа перевела часы на час назад. Это означает, что у сегодняшнего дня есть дополнительные 3600 секунд, и это должно быть отражено в метках времени UNIX. Если это так, то это означает, что сегодня будет учитываться два дня с указанным выше способом вычисления количества дней. И я даже не начинаю с високосных секунд, поскольку ни PHP, ни UNIX, кажется, не учитывают их (что на самом деле понятно для ИМО). TL; DR: не все дни имеют продолжительность 86 400 секунд .
toon81
2
@ toon81 На эту дату НЕ 3600 секунд. Ничего не происходит с отметкой времени UNIX при переходе к DST или из него.
nickdnk
1
Если с отметкой времени UNIX ничего не происходит, вы соглашаетесь со мной: разница между отметкой времени UNIX в 13:00 $dayи отметкой времени UNIX в 13:00 $day+1не всегда составляет 86400 секунд в часовых поясах, в которых наблюдается DST. Это может быть секунд 23 или 25 часов вместо 24 часов.
toon81
112
TL; DR действительно не использовать UNIX метки времени. Не используйтеtime() . Если вы делаете, будьте готовы если его надежность 98.0825% подведет вас. Используйте DateTime (или Carbon).
Правильный ответ является один задается Saksham Гупта (другие ответы тоже правильно):
/**
* Number of days between two dates.
*
* @param date $dt1 First date
* @param date $dt2 Second date
* @return int
*/function daysBetween($dt1, $dt2){return date_diff(
date_create($dt2),
date_create($dt1))->format('%a');}
С оговоркой: «% a» указывает на абсолютное количество дней. Если вы хотите, чтобы оно представляло собой целое число со знаком, то есть отрицательное, когда вторая дата находится перед первой, тогда вам нужно использовать префикс «% r» (т.е. format('%r%a')).
Если вам действительно нужно использовать метки времени UNIX, установите часовой пояс на GMT, чтобы избежать большинства ошибок, описанных ниже.
Длинный ответ: почему деление на 24 * 60 * 60 (86400) небезопасно
Большинство ответов, использующих метки времени UNIX (и 86400 для преобразования их в дни), делают два предположения, которые, вместе взятые, могут привести к сценариям с неправильными результатами и незначительным ошибкам, которые могут быть трудно отследить, и возникают даже через дни, недели или месяцы после успешное развертывание. Дело не в том, что решение не работает - оно работает. Cегодня. Но это может перестать работать завтра.
Первая ошибка не в том, что, когда спрашивают: «Сколько дней прошло со вчерашнего дня?», Компьютер может правдиво ответить на ноль, если между настоящим моментом и моментом, указанным «вчера», прошло менее одного целого дня .
Обычно при преобразовании «дня» в метку времени UNIX получается метка времени для полуночи этого конкретного дня.
Таким образом, между полуночью 1 октября и 15 октября прошло пятнадцать дней. Но между 13:00 1 октября и 14:55 15 октября прошло пятнадцать дней минус 5 минут , и большинство решений, использующих floor()или выполняющих неявное целочисленное преобразование , сообщат на один день меньше ожидаемого .
Итак, "сколько дней назад был Ymd H: i: s"? даст неправильный ответ .
Вторая ошибка - приравнивание одного дня к 86400 секундам. Это почти всегда так - это случается достаточно часто, чтобы не замечать того времени, когда этого не происходит. Но расстояние в секундах между двумя последовательными полуночностями, безусловно, не 86400, по крайней мере, два раза в год, когда наступает летнее время. Сравнение двух дат за границей летнего времени даст неправильный ответ.
Таким образом, даже если вы используете «хак» для принудительной установки всех временных меток даты на фиксированный час, скажем, полночь (это также делается неявно различными языками и средами, когда вы указываете только день-месяц-год, а не час-минута-секунда; То же самое можно сказать о типе DATE в базах данных, таких как MySQL), широко используемой формуле
вернет, скажем, 17, когда DATE1 и DATE2 находятся в одном и том же сегменте DST года; но он может вернуть 17.042, и еще хуже, 16.958. Использование floor () или любого неявного усечения в целое число затем преобразует то, что должно было быть 17, в 16. В других случаях выражения типа «$ days> 17» вернутся trueдля 17.042, даже если это указывает на то, что счетчик прошедших дней 18
И все становится еще хуже, так как такой код не переносим между платформами, потому что некоторые из них могут применять дополнительные секунды, а некоторые нет . На этих платформах , которые делают различие между двумя датами не будет 86400 , а 86401, или , может быть , 86399. Так код , который работал в мае и на самом деле прошел все испытания сломается в июне следующего года , когда 12.99999 дней считаются 12 дней вместо 13. Две даты который работал в 2015 году, не будет работать в 2017 году - те же даты, и ни один год не является високосным. Но между 2018-03-01 и 2017-03-01, на тех платформах, которые заботятся, пройдет 366 дней вместо 365, что сделает 2018 високосным годом (а это не так).
Так что если вы действительно хотите использовать метки времени UNIX:
используйте round()функцию с умом, а не floor().
в качестве альтернативы не рассчитывайте разницу между D1-M1-YYY1 и D2-M2-YYY2. Эти даты будут действительно рассматриваться как D1-M1-YYY1 00:00:00 и D2-M2-YYY2 00:00:00. Скорее, конвертируйте между D1-M1-YYY1 22:30:00 и D2-M2-YYY2 04:30:00. Вы всегда получите остаток около двадцати часов. Это может быть двадцать один час или девятнадцать, а может быть, восемнадцать часов, пятьдесят девять минут, тридцать шесть секунд. Не важно. Это большой запас, который останется там и останется позитивным в обозримом будущем. Теперь вы можете обрезать его floor()в безопасности.
Однако правильное решение, чтобы избежать магических констант, округления клуджей и долга за обслуживание, состоит в том, чтобы
использовать библиотеку времени (Datetime, Carbon, что угодно); не катай свой собственный
написать всесторонние контрольные примеры с использованием действительно неправильных выборов дат - через границы летнего времени, через високосные годы, за високосные секунды и т. д., а также заурядные даты. В идеале (вызовы datetime выполняются быстро !) Генерируют даты за целые четыре года (и один день) , последовательно собирая их из строк и обеспечивая постоянное увеличение разницы между первым и тестируемым днем. Это будет гарантировать, что, если что-то изменится в низкоуровневых подпрограммах и исправлениях високосных секунд, попытается нанести ущерб, по крайней мере, вы будете знать .
регулярно запускайте эти тесты вместе с остальным набором тестов. Они считаются миллисекундами и могут сэкономить вам буквально часы царапин на голове.
Каким бы ни было ваше решение, протестируйте его!
Приведенная funcdiffниже функция реализует одно из решений (как это принято, принятое) в реальном сценарии.
<?php
$tz ='Europe/Rome';
$yearFrom =1980;
$yearTo =2020;
$verbose =false;function funcdiff($date2, $date1){
$now = strtotime($date2);
$your_date = strtotime($date1);
$datediff = $now - $your_date;return floor($datediff /(60*60*24));}########################################
date_default_timezone_set($tz);
$failures =0;
$tests =0;
$dom = array (0,31,28,31,30,31,30,31,31,30,31,30,31);(array_sum($dom)===365)||die("Thirty days hath September...");
$last = array();for($year = $yearFrom; $year < $yearTo; $year++){
$dom[2]=28;// Apply leap year rules.if($year %4===0){ $dom[2]=29;}if($year %100===0){ $dom[2]=28;}if($year %400===0){ $dom[2]=29;}for($month =1; $month <=12; $month ++){for($day =1; $day <= $dom[$month]; $day++){
$date = sprintf("%04d-%02d-%02d", $year, $month, $day);if(count($last)===7){
$tests ++;
$diff = funcdiff($date, $test = array_shift($last));if((double)$diff !==(double)7){
$failures ++;if($verbose){print"There seem to be {$diff} days between {$date} and {$test}\n";}}}
$last[]= $date;}}}print"This function failed {$failures} of its {$tests} tests between {$yearFrom} and {$yearTo}.\n";
В результате
Thisfunction failed 280of its 14603 tests
История ужасов: стоимость «экономии времени»
Это на самом деле произошло несколько месяцев назад. Гениальный программист решил сэкономить несколько микросекунд за счет вычисления, которое занимало не более тридцати секунд, подключив печально известный код "(MidnightOfDateB-MidnightOfDateA) / 86400" в нескольких местах. Оптимизация была настолько очевидна, что он даже не задокументировал ее, и оптимизация прошла интеграционные тесты и скрывалась в коде в течение нескольких месяцев, причем все это было незамеченным.
Это произошло в программе, которая рассчитывает заработную плату нескольких продавцов, пользующихся наибольшим спросом, у меньшего из которых ужасное влияние гораздо больше, чем у всей скромной команды программистов из пяти человек вместе взятых. Однажды, несколько месяцев назад, по причинам, которые мало что значат, ошибка произошла - и некоторые из этих ребят получили целый день лишних комиссионных. Они определенно не были удивлены.
Бесконечно хуже, они потеряли (и без того очень мало) веру, которую они имели в программе, не предназначенной для того, чтобы тайно их подбросить, и притворились - и получили - полный, подробный обзор кода с тестовыми примерами, выполненными и прокомментированными с точки зрения непрофессионала (плюс много лечения красной ковровой дорожке в следующие недели).
Что я могу сказать: с другой стороны, мы избавились от большого технического долга и смогли переписать и реорганизовать несколько кусочков спагетти-беспорядка, которые были возвращены к заражению КОБОЛОМ в бурные 90-е годы. Программа, несомненно, работает лучше, и есть гораздо больше отладочной информации, чтобы быстро сосредоточиться, когда что-то выглядит подозрительно. Я полагаю, что только эта последняя вещь сэкономит, возможно, один или два человека в месяц в обозримом будущем.
С другой стороны, вся эта затея обошлась компании примерно в 200 000 евро - плюс лицо, плюс, несомненно, некоторая переговорная сила (и, следовательно, еще больше денег).
Парень, ответственный за «оптимизацию», сменил работу год назад, до катастрофы, но все же ходили разговоры, чтобы подать в суд на него за ущерб. И с высшими эшелонами не очень хорошо, что это «вина последнего парня» - это выглядело как подстава для нас, чтобы разобраться в этом вопросе, и, в конце концов, мы все еще в конуре и одна из команды планирует выйти.
Девяносто девять раз из ста, «86400 взломать» будет работать безупречно. (Например, в PHP strtotime()будет игнорировать DST и сообщать, что между полуночью последней субботы октября и следующего понедельника прошло ровно 2 * 24 * 60 * 60 секунд, даже если это явно не соответствует действительности ... и два блага с радостью сделают одно правым).
Дамы и господа, это был один случай, когда этого не произошло. Как и в случае с подушками безопасности и ремнями безопасности, вам, вероятно, никогда не понадобится сложность (и простота использования) DateTimeили Carbon. Но день, когда вы можете (или день, когда вам придется доказать, что вы подумали об этом) ночью придет как вор. Будь готов.
Когда я увидел эти ответы, я подумал, что я глуп и сумасшедший, потому что я всегда использую DateTime, но вы дали мне понять, что использование DateTime - правильный путь. Спасибо
Syncro
Эй, все здесь, на SO, попали сюда с помощью поиска в Google days between two days in phpили подобном, просто потому, что жизнь слишком коротка, чтобы написать все самостоятельно.
Денис Матафонов
1
подробное объяснение. + 1
Анант Сингх --- Жив, чтобы умереть
1
Иногда я хотел бы, чтобы мы могли добавить ответы вместо вопроса в избранное.
Это хороший процедурный способ сделать это с помощью класса DateTime. Ему не хватает только четкого использования объекта интервала ( $diffв данном случае, переменной). Нечто подобное if ($diff->days > 30) { [doyourstuff]; }
Очень старый комментарий выше, но это неверно. StackOverflow это позволит вам ответить на свой вопрос (даже если вы спросите ваш вопрос). Ответ на вопрос самостоятельно после того, как кто-то уже опубликовал такое же решение, считается грубым.
Maarten Bodewes
Эта функция не прошла 560 тестов из 14603 в период с 1980 по 2020 год.
LSerni
10
Что ж, выбранный ответ не самый правильный, потому что он потерпит неудачу вне UTC. В зависимости от часового пояса ( списка ) могут быть корректировки времени, создающие дни «без» 24 часов, и это приведет к сбою в вычислениях (60 * 60 * 24).
Вот пример этого:
date_default_timezone_set('europe/lisbon');
$time1 = strtotime('2016-03-27');
$time2 = strtotime('2016-03-29');
echo floor(($time2-$time1)/(60*60*24));^-- the output will be **1**
Таким образом, правильное решение будет использовать DateTime
date_default_timezone_set('europe/lisbon');
$date1 =newDateTime("2016-03-27");
$date2 =newDateTime("2016-03-29");
echo $date2->diff($date1)->format("%a");^-- the output will be **2**
function dateDiff($date1, $date2)//days find function{
$diff = strtotime($date2)- strtotime($date1);return abs(round($diff /86400));}//start day
$date1 ="11-10-2018";// end day
$date2 ="31-10-2018";// call the days find fun store to variable
$dateDiff = dateDiff($date1, $date2);
echo "Difference between two dates: ". $dateDiff ." Days ";
Для старых вопросов, на которые уже есть ответы, полезно объяснить, какой новый аспект дает ваш ответ на вопрос. Если это уместно, также полезно признать любые изменения, которые могли произойти после того, как был задан вопрос.
// Change this to the day in the future
$day =15;// Change this to the month in the future
$month =11;// Change this to the year in the future
$year =2012;// $days is the number of days between now and the date in the future
$days =(int)((mktime (0,0,0,$month,$day,$year)- time(void))/86400);
echo "There are $days days until $day/$month/$year";
Добро пожаловать на ТАК! Когда вы отвечаете на пост только с кодом, пожалуйста, объясните это немного. Код, который вы привносите, рассчитывается между 2019-11-10 и 2019-11-25. Так что это не ответ на вопрос. Вот почему это хорошо, чтобы объяснить ваш POV лучше, чем получить отрицательный голос.
Дэвид Гарсия Бодего
0
Если вы используете MySql
function daysSince($date, $date2){
$q ="SELECT DATEDIFF('$date','$date2') AS days;";
$result = execQ($q);
$row = mysql_fetch_array($result,MYSQL_BOTH);return($row[0]);
В общем, я использую DateTime, чтобы найти дни между двумя датами. Но если по какой-то причине в некоторых настройках сервера не включен «DateTime», он будет использовать простые (но не безопасные) вычисления с помощью «strtotime ()».
(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
Ответы:
источник
$your_date-$now
, если вы хотите, чтобы будущая дата возвращала положительное целое число.Если вы используете
PHP 5.3 >
, это, безусловно, самый точный способ расчета разницы:источник
$date1
перед$date2
), используйте$diff = $date2->diff($date1)->format("%r%a");
вместо этого.DateTime("2010-07-06")
?, ЭтоY-m-d
илиY-d-m
?, Каков форматDateTime
параметра. какой день?Начиная с версии PHP 5.3 и выше, были добавлены новые функции даты / времени , чтобы получить разницу:
Результат как ниже:
Надеюсь, поможет !
источник
Преобразуйте свои даты в метки времени Unix, затем вычтите одно из другого. Это даст вам разницу в секундах, которую вы поделите на 86400 (количество секунд в дне), чтобы получить приблизительное количество дней в этом диапазоне.
Если ваши даты в формате
25.1.2010
,01/25/2010
или2010-01-25
, вы можете использоватьstrtotime
функцию:Использование
ceil
раундов количество дней до следующего полного дня. использованиеfloor
вместо этого, если вы хотите получить количество полных дней между этими двумя датами.Если ваши даты уже в формате метки времени Unix, вы можете пропустить преобразование и просто выполнить
$days_between
часть. Для более экзотических форматов дат вам, возможно, придется выполнить какой-то пользовательский анализ, чтобы сделать его правильным.источник
$day
и отметкой времени UNIX в 13:00$day+1
не всегда составляет 86400 секунд в часовых поясах, в которых наблюдается DST. Это может быть секунд 23 или 25 часов вместо 24 часов.TL; DR действительно не использовать UNIX метки времени. Не используйте
time()
. Если вы делаете, будьте готовы если его надежность 98.0825% подведет вас. Используйте DateTime (или Carbon).Правильный ответ является один задается Saksham Гупта (другие ответы тоже правильно):
Или процедурно как однострочник
С оговоркой: «% a» указывает на абсолютное количество дней. Если вы хотите, чтобы оно представляло собой целое число со знаком, то есть отрицательное, когда вторая дата находится перед первой, тогда вам нужно использовать префикс «% r» (т.е.
format('%r%a')
).Если вам действительно нужно использовать метки времени UNIX, установите часовой пояс на GMT, чтобы избежать большинства ошибок, описанных ниже.
Длинный ответ: почему деление на 24 * 60 * 60 (86400) небезопасно
Большинство ответов, использующих метки времени UNIX (и 86400 для преобразования их в дни), делают два предположения, которые, вместе взятые, могут привести к сценариям с неправильными результатами и незначительным ошибкам, которые могут быть трудно отследить, и возникают даже через дни, недели или месяцы после успешное развертывание. Дело не в том, что решение не работает - оно работает. Cегодня. Но это может перестать работать завтра.
Первая ошибка не в том, что, когда спрашивают: «Сколько дней прошло со вчерашнего дня?», Компьютер может правдиво ответить на ноль, если между настоящим моментом и моментом, указанным «вчера», прошло менее одного целого дня .
Обычно при преобразовании «дня» в метку времени UNIX получается метка времени для полуночи этого конкретного дня.
Таким образом, между полуночью 1 октября и 15 октября прошло пятнадцать дней. Но между 13:00 1 октября и 14:55 15 октября прошло пятнадцать дней минус 5 минут , и большинство решений, использующих
floor()
или выполняющих неявное целочисленное преобразование , сообщат на один день меньше ожидаемого .Итак, "сколько дней назад был Ymd H: i: s"? даст неправильный ответ .
Вторая ошибка - приравнивание одного дня к 86400 секундам. Это почти всегда так - это случается достаточно часто, чтобы не замечать того времени, когда этого не происходит. Но расстояние в секундах между двумя последовательными полуночностями, безусловно, не 86400, по крайней мере, два раза в год, когда наступает летнее время. Сравнение двух дат за границей летнего времени даст неправильный ответ.
Таким образом, даже если вы используете «хак» для принудительной установки всех временных меток даты на фиксированный час, скажем, полночь (это также делается неявно различными языками и средами, когда вы указываете только день-месяц-год, а не час-минута-секунда; То же самое можно сказать о типе DATE в базах данных, таких как MySQL), широко используемой формуле
или
вернет, скажем, 17, когда DATE1 и DATE2 находятся в одном и том же сегменте DST года; но он может вернуть 17.042, и еще хуже, 16.958. Использование floor () или любого неявного усечения в целое число затем преобразует то, что должно было быть 17, в 16. В других случаях выражения типа «$ days> 17» вернутся
true
для 17.042, даже если это указывает на то, что счетчик прошедших дней 18И все становится еще хуже, так как такой код не переносим между платформами, потому что некоторые из них могут применять дополнительные секунды, а некоторые нет . На этих платформах , которые делают различие между двумя датами не будет 86400 , а 86401, или , может быть , 86399. Так код , который работал в мае и на самом деле прошел все испытания сломается в июне следующего года , когда 12.99999 дней считаются 12 дней вместо 13. Две даты который работал в 2015 году, не будет работать в 2017 году - те же даты, и ни один год не является високосным. Но между 2018-03-01 и 2017-03-01, на тех платформах, которые заботятся, пройдет 366 дней вместо 365, что сделает 2018 високосным годом (а это не так).
Так что если вы действительно хотите использовать метки времени UNIX:
используйте
round()
функцию с умом, а неfloor()
.в качестве альтернативы не рассчитывайте разницу между D1-M1-YYY1 и D2-M2-YYY2. Эти даты будут действительно рассматриваться как D1-M1-YYY1 00:00:00 и D2-M2-YYY2 00:00:00. Скорее, конвертируйте между D1-M1-YYY1 22:30:00 и D2-M2-YYY2 04:30:00. Вы всегда получите остаток около двадцати часов. Это может быть двадцать один час или девятнадцать, а может быть, восемнадцать часов, пятьдесят девять минут, тридцать шесть секунд. Не важно. Это большой запас, который останется там и останется позитивным в обозримом будущем. Теперь вы можете обрезать его
floor()
в безопасности.Однако правильное решение, чтобы избежать магических констант, округления клуджей и долга за обслуживание, состоит в том, чтобы
использовать библиотеку времени (Datetime, Carbon, что угодно); не катай свой собственный
написать всесторонние контрольные примеры с использованием действительно неправильных выборов дат - через границы летнего времени, через високосные годы, за високосные секунды и т. д., а также заурядные даты. В идеале (вызовы datetime выполняются быстро !) Генерируют даты за целые четыре года (и один день) , последовательно собирая их из строк и обеспечивая постоянное увеличение разницы между первым и тестируемым днем. Это будет гарантировать, что, если что-то изменится в низкоуровневых подпрограммах и исправлениях високосных секунд, попытается нанести ущерб, по крайней мере, вы будете знать .
регулярно запускайте эти тесты вместе с остальным набором тестов. Они считаются миллисекундами и могут сэкономить вам буквально часы царапин на голове.
Каким бы ни было ваше решение, протестируйте его!
Приведенная
funcdiff
ниже функция реализует одно из решений (как это принято, принятое) в реальном сценарии.В результате
История ужасов: стоимость «экономии времени»
Это на самом деле произошло несколько месяцев назад. Гениальный программист решил сэкономить несколько микросекунд за счет вычисления, которое занимало не более тридцати секунд, подключив печально известный код "(MidnightOfDateB-MidnightOfDateA) / 86400" в нескольких местах. Оптимизация была настолько очевидна, что он даже не задокументировал ее, и оптимизация прошла интеграционные тесты и скрывалась в коде в течение нескольких месяцев, причем все это было незамеченным.
Это произошло в программе, которая рассчитывает заработную плату нескольких продавцов, пользующихся наибольшим спросом, у меньшего из которых ужасное влияние гораздо больше, чем у всей скромной команды программистов из пяти человек вместе взятых. Однажды, несколько месяцев назад, по причинам, которые мало что значат, ошибка произошла - и некоторые из этих ребят получили целый день лишних комиссионных. Они определенно не были удивлены.
Бесконечно хуже, они потеряли (и без того очень мало) веру, которую они имели в программе, не предназначенной для того, чтобы тайно их подбросить, и притворились - и получили - полный, подробный обзор кода с тестовыми примерами, выполненными и прокомментированными с точки зрения непрофессионала (плюс много лечения красной ковровой дорожке в следующие недели).
Что я могу сказать: с другой стороны, мы избавились от большого технического долга и смогли переписать и реорганизовать несколько кусочков спагетти-беспорядка, которые были возвращены к заражению КОБОЛОМ в бурные 90-е годы. Программа, несомненно, работает лучше, и есть гораздо больше отладочной информации, чтобы быстро сосредоточиться, когда что-то выглядит подозрительно. Я полагаю, что только эта последняя вещь сэкономит, возможно, один или два человека в месяц в обозримом будущем.
С другой стороны, вся эта затея обошлась компании примерно в 200 000 евро - плюс лицо, плюс, несомненно, некоторая переговорная сила (и, следовательно, еще больше денег).
Парень, ответственный за «оптимизацию», сменил работу год назад, до катастрофы, но все же ходили разговоры, чтобы подать в суд на него за ущерб. И с высшими эшелонами не очень хорошо, что это «вина последнего парня» - это выглядело как подстава для нас, чтобы разобраться в этом вопросе, и, в конце концов, мы все еще в конуре и одна из команды планирует выйти.
Девяносто девять раз из ста, «86400 взломать» будет работать безупречно. (Например, в PHP
strtotime()
будет игнорировать DST и сообщать, что между полуночью последней субботы октября и следующего понедельника прошло ровно 2 * 24 * 60 * 60 секунд, даже если это явно не соответствует действительности ... и два блага с радостью сделают одно правым).Дамы и господа, это был один случай, когда этого не произошло. Как и в случае с подушками безопасности и ремнями безопасности, вам, вероятно, никогда не понадобится сложность (и простота использования)
DateTime
илиCarbon
. Но день, когда вы можете (или день, когда вам придется доказать, что вы подумали об этом) ночью придет как вор. Будь готов.источник
days between two days in php
или подобном, просто потому, что жизнь слишком коротка, чтобы написать все самостоятельно.Легко использовать date_diff
источник
$diff
в данном случае, переменной). Нечто подобноеif ($diff->days > 30) { [doyourstuff]; }
Объектно-ориентированный стиль:
Процедурный стиль:
источник
Использовал это :)
Теперь работает
источник
Что ж, выбранный ответ не самый правильный, потому что он потерпит неудачу вне UTC. В зависимости от часового пояса ( списка ) могут быть корректировки времени, создающие дни «без» 24 часов, и это приведет к сбою в вычислениях (60 * 60 * 24).
Вот пример этого:
Таким образом, правильное решение будет использовать DateTime
источник
Рассчитайте разницу между двумя датами:
Выход: +272 дня
Функция date_diff () возвращает разницу между двумя объектами DateTime.
источник
источник
Я использую Carbon в своих композиторских проектах для этой и подобных целей.
Это было бы так просто, как это:
источник
Вы можете найти даты просто
источник
и, если необходимо:
источник
Если у вас есть время в секундах (IE Unix Time Stamp), то вы можете просто вычесть время и разделить на 86400 (секунд в день)
источник
источник
Вы можете попробовать код ниже:
источник
источник
Если вы хотите повторить все дни между начальной и конечной датой, я придумал это:
источник
Самый простой способ найти разницу дней между двумя датами
источник
источник
Вот моя улучшенная версия, которая показывает 1 год (ы) 2 месяца (ов) 25 дней, если передан второй параметр.
источник
источник
Использованный выше код очень прост. Спасибо.
источник
источник
Используя эту простую функцию. Объявить функцию
и вызвать эту функцию, как это, где вы хотите
источник
источник
Если вы используете MySql
}
}
источник
Попробуйте использовать углерод
Также вы можете использовать
создать объект даты Углерода, используя данную строку метки времени.
источник
Просматривая все ответы я составляю универсальную функцию, которая работает на всех версиях PHP.
В общем, я использую DateTime, чтобы найти дни между двумя датами. Но если по какой-то причине в некоторых настройках сервера не включен «DateTime», он будет использовать простые (но не безопасные) вычисления с помощью «strtotime ()».
источник