Як знайти кількість днів між двома датами за допомогою PHP?
(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
Як знайти кількість днів між двома датами за допомогою PHP?
(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
Відповіді:
$now = time(); // or your date as well
$your_date = strtotime("2010-01-31");
$datediff = $now - $your_date;
echo round($datediff / (60 * 60 * 24));
$your_date-$now
, якщо ви хочете, щоб майбутня дата повернула додатне ціле число.
Якщо ви використовуєте PHP 5.3 >
, це, безумовно, найбільш точний спосіб обчислення різниці:
$earlier = new DateTime("2010-07-06");
$later = new DateTime("2010-07-09");
$diff = $later->diff($earlier)->format("%a");
$date1
це перед $date2
), тоді використовуйте $diff = $date2->diff($date1)->format("%r%a");
замість цього.
DateTime("2010-07-06")
?, Це Y-m-d
чи Y-d-m
?, Який формат DateTime
параметра. який день?
Починаючи з PHP версії 5.3 і новіших, нові функції дати / часу були додані, щоб отримати різницю:
$datetime1 = new DateTime("2010-06-20");
$datetime2 = new DateTime("2011-06-22");
$difference = $datetime1->diff($datetime2);
echo 'Difference: '.$difference->y.' years, '
.$difference->m.' months, '
.$difference->d.' days';
print_r($difference);
Результат, як показано нижче:
Difference: 1 years, 0 months, 2 days
DateInterval Object
(
[y] => 1
[m] => 0
[d] => 2
[h] => 0
[i] => 0
[s] => 0
[invert] => 0
[days] => 367
)
Сподіваюся, це допомагає!
Перетворіть ваші дати в часові позначки Unix, а потім підкресліть одну від іншої. Це дасть вам різницю в секундах, яку ви розділите на 86400 (кількість секунд в день), щоб отримати приблизну кількість днів у цьому діапазоні.
Якщо ваші дати у форматі 25.1.2010
, 01/25/2010
або 2010-01-25
ви можете скористатися strtotime
функцією:
$start = strtotime('2010-01-25');
$end = strtotime('2010-02-20');
$days_between = ceil(abs($end - $start) / 86400);
Використовуючи ceil
раунди кількість днів до наступного повного дня. Використовуйте floor
натомість, якщо ви хочете отримати кількість повних днів між цими двома датами.
Якщо ваші дати вже є у форматі часових позначок Unix, ви можете пропустити перетворення та просто виконати $days_between
частину. Для отримання більш екзотичних форматів побачень вам, можливо, доведеться провести спеціальний розбір, щоб правильно це зробити.
$day
та часовою міткою UNIX в 1:00 на $day+1
не завжди становить 86400 секунд у часових поясах, які спостерігають за DST. Це може тривати 23 або 25 годин, а не 24 години.
time()
. Якщо ви це зробите, будьте готові, якщо надійність 989825% не підведе вас. Використовуйте DateTime (або Carbon).Правильна відповідь є один задається Saksham Гупта (інші відповіді теж правильно):
$date1 = new DateTime('2010-07-06');
$date2 = new DateTime('2010-07-09');
$days = $date2->diff($date1)->format('%a');
Або процедурно як однолінійний:
/**
* 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, щоб уникнути більшості підводних каменів, описаних нижче.
Більшість відповідей, використовуючи часові позначки UNIX (і 86400 для перетворення цього в дні), роблять два припущення, які, у сукупності, можуть призвести до сценаріїв з неправильними результатами та тонкими помилками, які важко відстежувати, і виникають навіть дні, тижні чи місяці після успішне розгортання. Справа не в тому, що рішення не працює - воно працює. Сьогодні Але це може припинити роботу завтра.
Перша помилка - це не враховуючи, що на запитання «Скільки днів минуло з вчорашнього дня?» Комп'ютер може правдиво відповісти нулю, якщо між потоком і моментом, зазначеним «вчора», пройшло менше одного цілого дня .
Зазвичай при перетворенні "дня" на часову позначку UNIX, одержується часова мітка для опівночі цього конкретного дня.
Так між півночі 1 жовтня та 15 жовтня минуло п’ятнадцять днів. Але між 13:00 1 жовтня та 14:55 15 жовтня минуло п’ятнадцять днів мінус 5 хвилин , і більшість рішень, що використовують floor()
або роблять неявне ціле перетворення , звітують на один день менше, ніж очікувалося .
Отже, "скільки днів тому було Ymd H: i: s"? дасть неправильну відповідь .
Друга помилка - це прирівнювання одного дня до 86400 секунд. Це майже завжди так - це трапляється досить часто, щоб не помітити часів, яких це не відбувається. Але відстань у секундах між двома поспіль опівночами, безумовно, не становить 86400, принаймні двічі на рік, коли в гру починається літній час. Порівняння двох дат через межу DST дасть неправильну відповідь.
Тож навіть якщо ви використовуєте "хак" примушування всіх часових позначок дат до фіксованої години, скажіть опівночі (це також робиться неявно різними мовами та рамками, коли ви вказуєте лише день-місяць-рік, а також не годину-хвилину-секунду; Це ж задовольняє тип DATE в базах даних, таких як MySQL), широко використовуваній формулі
(unix_timestamp(DATE2) - unix_timestamp(DATE1)) / 86400
або
floor(time() - strtotime($somedate)) / 86400
повернеться, скажімо, 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, що завгодно); не котиться сам
писати вичерпні тестові випадки, використовуючи дійсно злий вибір дати - через межі DST, протягом високосних років, протягом високосних секунд тощо, а також звичайні дати. В ідеалі (дзвінки до дати швидкі !) Генерують дати за цілі чотири роки (і один день) , збираючи їх з рядків послідовно, і слідкуйте за тим, щоб різниця між першим днем і днем тестування постійно зростала на одиницю. Це забезпечить, що якщо що-небудь зміниться в підпрограмах низького рівня та виправлення секундних виправлень, спробуй завдати хаос, принаймні, ти будеш знати .
регулярно виконуйте ці тести разом з рештою тестового набору. Вони знаходяться в мілісекундах і можуть врятувати вас буквально за кілька годин від чухання голови.
Нижче 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";
Результат:
This function failed 280 of its 14603 tests
Це насправді сталося кілька місяців тому. Геніальний програміст вирішив зберегти кілька мікросекунд від обчислення, яке зайняло максимум тридцять секунд, підключивши сумнозвісний код "(MidnightOfDateB-MidnightOfDateA) / 86400" в декількох місцях. Це була настільки очевидна оптимізація, що він навіть не документував її, а оптимізація пройшла інтеграційні тести і ховалася в коді кілька місяців, все непомітно.
Це сталося в програмі, яка розраховує заробітну плату для кількох найпродажніших продавців, найменший з яких має жахливо набагато більше, ніж ціла скромна команда програмістів з п'яти людей. Одного разу кілька місяців тому, з незначних причин, виникла помилка - і деякі з цих хлопців змінили один цілий день жирових комісій. Їх точно не розвеселили.
Нескінченно гірше, вони втратили (вже дуже мало) віри, яку вони мали в програмі, яка не розроблена для того, щоб їх шахрайсько скалупали, і зробили вигляд - і отримали - повний, детальний огляд коду з тестовими справами, пробіг і прокоментував лайківські умови (плюс багато лікування червоною доріжкою в наступні тижні).
Що я можу сказати: з позитивного боку ми позбулися багато технічної заборгованості і змогли переписати та переробляти кілька шматочків спагетті, які повернулися до зараження COBOL у колишніх 90-х. Програма зараз, безсумнівно, працює краще, і є набагато більше інформації про налагодження, яка швидко нульова, коли що-небудь виглядає рибним. Я вважаю, що саме ця остання річ заощадить, можливо, один-два людино-дні на місяць в осяжному майбутньому.
З мінусового боку, весь brouhaha коштував компанії близько 200 000 євро на передній план - плюс обличчя, а також, безсумнівно, деяку торгуючу силу (а, отже, і більше грошей).
Хлопець, відповідальний за «оптимізацію», змінив роботу рік тому, перед катастрофою, але все ще розмовляли з позовом до нього про відшкодування збитків. І не було добре з верхніми ешелонами, що це "вина останнього хлопця" - це було схоже на налаштування, щоб ми підійшли до чистої справи, і врешті-решт, ми все ще знаходимося в собачій домі і хтось із команди планує вийти.
Дев'яносто дев'ять разів із ста, "86400 хак" працюватиме бездоганно. (Наприклад, в PHP, strtotime()
ігноруйте DST та повідомляйте, що між опівночі останньої суботи жовтня та наступного понеділка минуло рівно 2 * 24 * 60 * 60 секунд, навіть якщо це явно не вірно ... і дві кривди щасливо зроблять одне правильно).
Це, панове, панове, був одним із випадків, коли цього не було. Як і у випадку з подушками безпеки і ременями безпеки, вам, можливо, ніколи не знадобиться складність (і простота використання) DateTime
або Carbon
. Але день, коли ви, можливо, (або день, коли вам доведеться довести, що ви думали про це), настане як злодій у ніч. Будь готовий.
days between two days in php
чи подібних, просто тому, що життя занадто коротке, щоб все написати самому.
Простий у використанні date_diff
$from=date_create(date('Y-m-d'));
$to=date_create("2013-03-15");
$diff=date_diff($to,$from);
print_r($diff);
echo $diff->format('%R%a days');
$diff
змінної в цьому випадку). Щось на кшталт if ($diff->days > 30) { [doyourstuff]; }
Об'єктно-орієнтований стиль:
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
Процедурний стиль:
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%a days');
Користувався цим :)
$days = (strtotime($endDate) - strtotime($startDate)) / (60 * 60 * 24);
print $days;
Зараз це працює
Добре, що обрана відповідь не є найбільш правильною, оскільки вона не вийде за 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 = new DateTime("2016-03-27");
$date2 = new DateTime("2016-03-29");
echo $date2->diff($date1)->format("%a");
^-- the output will be **2**
Обчисліть різницю між двома датами:
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
Вихід: +272 дні
Функція date_diff () повертає різницю між двома об'єктами DateTime.
Ви можете знайти дати просто за адресою
<?php
$start = date_create('1988-08-10');
$end = date_create(); // Current time and date
$diff = date_diff( $start, $end );
echo 'The difference is ';
echo $diff->y . ' years, ';
echo $diff->m . ' months, ';
echo $diff->d . ' days, ';
echo $diff->h . ' hours, ';
echo $diff->i . ' minutes, ';
echo $diff->s . ' seconds';
// Output: The difference is 28 years, 5 months, 19 days, 20 hours, 34 minutes, 36 seconds
echo 'The difference in days : ' . $diff->days;
// Output: The difference in days : 10398
кількість днів між двома датами в PHP
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 ";
Ви можете спробувати код нижче:
$dt1 = strtotime("2019-12-12"); //Enter your first date
$dt2 = strtotime("12-12-2020"); //Enter your second date
echo abs(($dt1 - $dt2) / (60 * 60 * 24));
Якщо ви хочете повторювати всі дні між датою початку та кінця, я придумав це:
$startdatum = $_POST['start']; // starting date
$einddatum = $_POST['eind']; // end date
$now = strtotime($startdatum);
$your_date = strtotime($einddatum);
$datediff = $your_date - $now;
$number = floor($datediff/(60*60*24));
for($i=0;$i <= $number; $i++)
{
echo date('d-m-Y' ,strtotime("+".$i." day"))."<br>";
}
Найпростіший спосіб знайти різницю днів між двома датами
$date1 = strtotime("2019-05-25");
$date2 = strtotime("2010-06-23");
$date_difference = $date2 - $date1;
$result = round( $date_difference / (60 * 60 * 24) );
echo $result;
// 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";
Ось моя вдосконалена версія, яка показує 1 рік (и) 2 місяць (и) 25 день (и), якщо другий параметр пройдений.
class App_Sandbox_String_Util {
/**
* Usage: App_Sandbox_String_Util::getDateDiff();
* @param int $your_date timestamp
* @param bool $hr human readable. e.g. 1 year(s) 2 day(s)
* @see http://stackoverflow.com/questions/2040560/finding-the-number-of-days-between-two-dates
* @see http://qSandbox.com
*/
static public function getDateDiff($your_date, $hr = 0) {
$now = time(); // or your date as well
$datediff = $now - $your_date;
$days = floor( $datediff / ( 3600 * 24 ) );
$label = '';
if ($hr) {
if ($days >= 365) { // over a year
$years = floor($days / 365);
$label .= $years . ' Year(s)';
$days -= 365 * $years;
}
if ($days) {
$months = floor( $days / 30 );
$label .= ' ' . $months . ' Month(s)';
$days -= 30 * $months;
}
if ($days) {
$label .= ' ' . $days . ' day(s)';
}
} else {
$label = $days;
}
return $label;
}
}
$early_start_date = date2sql($_POST['early_leave_date']);
$date = new DateTime($early_start_date);
$date->modify('+1 day');
$date_a = new DateTime($early_start_date . ' ' . $_POST['start_hr'] . ':' . $_POST['start_mm']);
$date_b = new DateTime($date->format('Y-m-d') . ' ' . $_POST['end_hr'] . ':' . $_POST['end_mm']);
$interval = date_diff($date_a, $date_b);
$time = $interval->format('%h:%i');
$parsed = date_parse($time);
$seconds = $parsed['hour'] * 3600 + $parsed['minute'] * 60;
// display_error($seconds);
$second3 = $employee_information['shift'] * 60 * 60;
if ($second3 < $seconds)
display_error(_('Leave time can not be greater than shift time.Please try again........'));
set_focus('start_hr');
set_focus('end_hr');
return FALSE;
}
<?php
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
?>
використаний вищезгаданий код дуже простий. Дякую.
function get_daydiff($end_date,$today)
{
if($today=='')
{
$today=date('Y-m-d');
}
$str = floor(strtotime($end_date)/(60*60*24)) - floor(strtotime($today)/(60*60*24));
return $str;
}
$d1 = "2018-12-31";
$d2 = "2018-06-06";
echo get_daydiff($d1, $d2);
Використовуючи цю просту функцію. Оголосити функцію
<?php
function dateDiff($firstDate,$secondDate){
$firstDate = strtotime($firstDate);
$secondDate = strtotime($secondDate);
$datediff = $firstDate - $secondDate;
$output = round($datediff / (60 * 60 * 24));
return $output;
}
?>
і викликайте цю функцію так, куди ви хочете
<?php
echo dateDiff("2018-01-01","2018-12-31");
// OR
$firstDate = "2018-01-01";
$secondDate = "2018-01-01";
echo dateDiff($firstDate,$secondDate);
?>
$diff = strtotime('2019-11-25') - strtotime('2019-11-10');
echo abs(round($diff / 86400));
Якщо ви використовуєте 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]);
}
function execQ($q){
$result = mysql_query( $q);
if(!$result){echo ('Database error execQ' . mysql_error());echo $q;}
return $result;
}
Спробуйте використовувати Carbon
$d1 = \Carbon\Carbon::now()->subDays(92);
$d2 = \Carbon\Carbon::now()->subDays(10);
$days_btw = $d1->diffInDays($d2);
Також ви можете використовувати
\Carbon\Carbon::parse('')
створити об'єкт дати Carbon за допомогою заданого рядка часової позначки.
Переглядаючи всі відповіді, я складаю універсальну функцію, що працює у всіх версіях PHP.
if(!function_exists('date_between')) :
function date_between($date_start, $date_end)
{
if(!$date_start || !$date_end) return 0;
if( class_exists('DateTime') )
{
$date_start = new DateTime( $date_start );
$date_end = new DateTime( $date_end );
return $date_end->diff($date_start)->format('%a');
}
else
{
return abs( round( ( strtotime($date_start) - strtotime($date_end) ) / 86400 ) );
}
}
endif;
Загалом я використовую 'DateTime', щоб знайти дні між двома датами. Але якщо з якихось причин у деяких настройках сервера не включено 'DateTime', він буде використовувати простий (але не безпечний) обчислення з 'strtotime ()'.