PHP calculate number of full months between two dates - php

I am trying to calculate the difference in months between two dates, but in a more specific way.
For example, I have two dates: 2017-11-01 and 2018-01-31
What I need as a result is 3 months. Meaning, there are 3 full billing months between these two dates.
Here is how it's supposed to work:
Month 1: 2017-11-01 until 2017-11-30
Month 2: 2017-12-01 until 2017-12-31
Month 3: 2018-01-01 until 2018-01-31
I have tried the diff method in the DateTime class, it produces something that doesn't help much. Here is an example
<?php
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 00:00:00');
$diff = $date1->diff($date2);
print_r($diff)
result:
DateInterval Object
(
[y] => 0
[m] => 2
[d] => 30
[h] => 0
[i] => 0
[s] => 0
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 0
[days] => 91
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)
It shows 2 months and 30 days.
However, in a slightly different scenario
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-30 00:00:00');
The diff between these two dates should show 2 months and 30 days, not 3 months.
Any help or ideas would be greatly appreciated.

Add one day to your ending date before doing the comparison. If the original ending date was the last day of the month, then the new ending date will roll over to the next month and you'll get the correct number of "full" months in the diff object. If the original was any day but the last day of the month, it won't change the result.
$start = '2017-11-01';
$end = '2018-01-31';
$date1 = DateTime::createFromFormat('Y-m-d', $start);
$date2 = DateTime::createFromFormat('Y-m-d', $end)->add(new DateInterval('P1D'));
echo $date1->diff($date2)->m, "\n";

Seems you lost one day during your calculation. Cause you need interval in months including first/last day - then you should add this day to interval.
So, the solution in this case will be:
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 23:59:59');
$diff = $date1->diff($date2);
or:
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-10-31 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 00:00:00');
$diff = $date1->diff($date2);
or even:
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-02-01 00:00:00');
$diff = $date1->diff($date2);

Using Carbon:
Carbon::parse('2017-10-31')->diffInMonths(Carbon::now());

Related

Show dates between two dates

I have a leave system where user select dates from and to dates let say 2018-02-26 - 2018-03-03 that is 6 days in total. On our portal it shows all users that is on leave. supposing that this user applied for 6 days leave, How am I going to display this user for 6 days on our portal?below is my code it works well but is show only for the current date.
$currentDate = date('Y-m-d');
$lf = Leave::where('leave_from', $currentDate)
->where('status', 'approved')
->get();
I am using eloquent. thanks
// Specify the start date. This date can be any English textual format
$date_from = "2018-02-03";
$date_from = strtotime($date_from); // Convert date to a UNIX timestamp
// Specify the end date. This date can be any English textual format
$date_to = "2018-02-10";
$date_to = strtotime($date_to); // Convert date to a UNIX timestamp
// Loop from the start date to end date and output all dates inbetween
for ($i=$date_from; $i<=$date_to; $i+=86400) {
echo date("Y-m-d", $i).'<br />';
}
You can use datetime function in PHP.
$first_date = new DateTime($currentDate);
$last_date = new DateTime($if);
$difference = $first_date->diff($last_date);
echo $difference->d.' days;
if you want month and year use $difference->m and $difference->y.And if you want accurate days even dates are negative use below one.
$result = $first_date->diff($last_date)->format("%r%a");
source:/ datetime
You can use date_diff() function:
$interval = date_diff($currentDate, $lf);
echo $interval->format('%d');
more on: http://php.net/manual/en/function.date-diff.php; https://www.w3schools.com/php/func_date_date_diff.asp
You can use DATEDIFF to get difference directly from query.
Select abs(DATEDIFF(`date_to`,`date_from`)) as diff from leaves;
In laravel you can write it as
$lf = Leave::where('status', 'approved')
->select(DB::raw("abs(DATEDIFF(`date_to`,`date_from`)) as diff"),"*")
->get();
Be sure to use where('leave_from', $currentDate), I think it's not necessary.
You can use DateTime function of PHP
in your case
$currentDate = date('Y-m-d');
$currentDate = new DateTime($currentDate);
$leaveDate = new DateTime($leaveFrom);
$difference = $currentDate->diff($leaveDate);
You will get result like
DateInterval Object ( [y] => 0 [m] => 0 [d] => 5 [h] => 0 [i] => 0 [s] => 0 [f] => 0 [weekday] => 0 [weekday_behavior] => 0 [first_last_day_of] => 0 [invert] => 0 [days] => 5 [special_type] => 0 [special_amount] => 0 [have_weekday_relative] => 0 [have_special_relative] => 0 )
$many_days=0;
$date_from = "2018-02-26";
$date_to = "2018-03-03";
for ($i=strtotime($date_from); $i<=strtotime($date_to);
$i+=86400) {
$many_days++;
}
echo "leaves $many_days";

PHP - Calculate Number of Months between a date and the current date

I need to work out the number of months between a date like this:
$inputDate = '09/08/2016';
that is entered in the MM/DD/YYYY format, and the current date, e.g.:
$today = date("m/d/Y");
I've been looking at the date_diff but can't seem to get the syntax right here and appreciate any help here.
You can use DateTime and diff
$datetime1 = new DateTime();
$datetime2 = new DateTime('09/08/2016');
$interval = $datetime1->diff($datetime2);
$months = $interval->format('%m months'); # you can also use %a days %h hours %i minutes %s seconds
echo $months;
# 8 months
# optimally you can use:
# echo $datetime1->diff($datetime2)->y*12;
# or
# echo $interval->m
Update based-on comments:
$datetime1 = new DateTime();
$datetime2 = new DateTime('09/08/2015');
$interval = $datetime1->diff($datetime2);
echo (($interval->format('%y') * 12) + $interval->format('%m')) . " full months difference";
Note:
A DateInterval Object looks like:
DateInterval Object
(
[y] => 3
[m] => 5
[d] => 15
[h] => 0
[i] => 0
[s] => 0
[invert] => 0
[days] => 1264
)
That's why we've to multiply the number of years * 12 and add the months in order to get the difference in months. Strange, but this is how it works...

geting specific dates in the future with php

so my problem is rather simple but the solution keeps evading me. i am trying to get a list of future dates at a set interval that respects week nr in month and day nr in week. for example i need to make a list of dates of the 2nd mondays at 3 months apart.
i have a form where user specifies 2 dates and the interval.
so what i have is something like:
$start_date = "2015-01-07";
$end_date = "2016-01-07";
$period = "+1 month";
then, using this function from this link stackoverflow i get what weeknr my start_date is: (ie: "first monday")
function literalDate($timestamp) {
$timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp);
$weekday = date('l', $timestamp);
$month = date('M', $timestamp);
$ord = 1;
while(date('M', ($timestamp = strtotime('-1 week', $timestamp))) == $month) {
$ord++;
}
$lit = array(null, 'first', 'second', 'third', 'fourth', 'fifth');
return $lit[$ord].' '.$weekday;
}
$day_number = literalDate($start_date);
$list=array();
then. i'm trying to do this
while(strtotime($start_date) <= strtotime($end_date))
{
$list[]=$start_date;
$start_date=date('Y-m-d', strtotime("$start_date $period"));
$month = date('F', strtotime($start_date));
$start_date = date('Y-m-d', strtotime($day_number.' of '.$month)); //this always returns 1970-01-01
}
print_r($list);
as asked in comment my expected output is something like
array(
[0] => 2015-01-07
[1] => 2015-02-04
[2] => 2015-03-04
[3] => 2015-04-01
[4] => 2015-05-06
[5] => 2015-06-03
[6] => 2015-07-01
[7] => 2015-08-05
[8] => 2015-09-02
[9] => 2015-10-07
[10] => 2015-11-04
[11] => 2015-12-02
)
From what I understand, DateInterval should get you what you need:
$start = new DateTime('2015-01-07');
$start->modify('first day of this month');
$end = new DateTime('2016-01-07');
$end->modify('first day of this month');
$interval = DateInterval::createFromDateString('first wednesday');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
$d = $dt->format("d");
if($d <= 7){
echo $dt->format("Y-m-d") . "\n";
}
}
will display:
2015-01-07
2015-02-04
2015-03-04
2015-04-01
2015-05-06
2015-06-03
2015-07-01
2015-08-05
2015-09-02
2015-10-07
2015-11-04
2015-12-02
2016-01-06
strtotime() which works in reference of today.
strtotime("+x days");
strtotime
if you need something in relation to another date...
date("Y-m-d", strtotime($yourdate) + 86400 * $days);

I want to find difference between these two date with days,hours and minutes

I want to find difference between these two date with days,hours and minutes.
$date1 = "27-09-2014 05:00 AM";
$date2 = "29-09-2014 03:00 PM";
From PHP Version > 5 below new date/time functions added to get difference:
$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);
Result as below:
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
)
I'm not sure whether I get your question right, but shouldn't the following work?
$datetime1 = new DateTime('27-09-2014');
$datetime2 = new DateTime('29-09-2014');
$datetime1->setTime(05, 00);
$datetime2->setTime(15, 00);
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%a Day and %h hours'
DateTime::diff

Calculating difference between dates

I need your help in how to subtract the last_modified and the final_manuscript_date in the following array:
Array (
[chapters_id] => 10736
[last_modified] => 2010-12-21 15:01:55
[steps_id] => 3
[sub_step_id] => 0
[steps_position] => 1
[final_manuscript_date] => 2010-09-27
)
So I can in this case get a value of N days between the dates 2010-12-21 and 2010-09-27?
Can't you simply do:
$diff = strtotime($arr["final_manuscript_date"]) - strtotime($arr["last_modified"]);
$days = $diff / 84600; // to get # of days, you can round them off or use ceil/floor
If you have 5.3+:
$date1 = new DateTime("2010-09-27");
$date2 = new DateTime("2010-12-21");
$interval = $date1->diff($date2);
echo $interval->d //returns days.
Have you checked strtotime?
http://php.net/manual/en/function.strtotime.php

Categories