How to calculate exact months between two dates - php

Consider there are 44 days between two dates.The result what I want is 2 months and not 1 month or 1 month 14 days.I have tried several date functions in both php and mysql,but failed in obtaining the exact result. I've also tried my own(below)code.
$dt1 = some date
$dt2 = some date
$date1 = date_create("".$dtl."");
$date2 = date_create("".$dt2."");
$dateDiff = date_diff($date2, $date1);
$probDays = $dateDiff->days;
$probMon = $dateDiff->m;
$probYear = $dateDiff->y;
$month = $probDays / 30;
$totLeave = $month * 1;
if($month > $probmon)
{
$totLeave = $totLeave + 1;
}
But I failed.The code is about adding vacation days to the client.Any solution in php or mysql would be grateful.Thanks in advance for all the volunteers.

Using PHP 5.3, maybe you could try the following:
<?php
$dt1 = "2014-05-12";
$dt2 = "2014-06-15";
$date1 = new DateTime($dt1);
$date2 = new DateTime($dt2);
$months = $date1->diff($date2)->m;
$days = $date1->diff($date2)->d;
if ($days >= 1) $months++;
echo $months." months!";
?>

Try to check number of days, if not equal to zero, then add 1 to months count and return that value of months.

<?php
$dt_dif= $dt2 - $dt1 ;
$y = $tot_exp / 365;
$d = $tot_exp % 365;
$m = $d / 30;
$year = (int)$y;
$month = (int)$m;
$day= (int)$d;
$total="".$month."month(s) ".$day."day(s)";
?>

John Riedel answer is the correct one!
You need to use $start_date->diff($end_date)->m & $start_date->diff($end_date)->d to find out the month & date differences.. and if the days count is more than 0, then you need to increase the months count as stated here...
http://www.phpguy.in/finding-difference-between-2-dates-in-php/

$date_from = "2011-01-22";
$date_to = "2011-03-23";
$date_from = date('Y-m-d', strtotime($date_from));
$date_to = date('Y-m-d', strtotime($date_to));
$y1 = date('Y', strtotime($date_from));
$y2 = date('Y', strtotime($date_to));
$m1 = date('m', strtotime($date_from));
$m2 = date('m', strtotime($date_to));
$day1 = date('d', strtotime($date_from));
$day2 = date('d', strtotime($date_to));
$yearDiff = $y2 - $y1;
if ($m2 > $m1) {
$month = $m2 - $m1;
} else {
$month = 0;
}
if ($yearDiff > 0 && $m1 > $m2) {
$yearMonth = (($yearDiff * 12) - ($m1 - $m2));
} else {
$yearMonth = $yearDiff * 12;
}
if ($day1 > $day2) {
$month = ($month - 1);
}
$total_month = $yearMonth + $month;
$total_month = ($total_month > 1) ? $total_month . " months" : $total_month . " month";
echo "Total " . $total_month;

Related

Calculate days in months between two dates with PHP

I have a period with startdate of 2016-12-26 and end date 2017-03-04.
Now I would like to find out how many days in each months there is, from a given period. Expected output from the above period dates (array):
2016-12: 5
2017-01: 31
2017-02: 28
2017-03: 4
How can I accomplish this cleanest way? I have tried to:
first looking at the period_start, get the days = 26 and
find out the start/end dates of the months between 2016-12 and 2017-03, to then calculate the days here (31 respectively 28 in february)
then finally calculating the 4 days in 2017-03.
But is there any cleaner/better way?
This can be achieved easily using the DateTime class. Create the objects, and use DateTime::diff() on them, then use the days property.
$start = new DateTime("2016-12-26");
$end = new DateTime("2017-03-04");
echo $start->diff($end)->days; // Output: 68
Live demo
http://php.net/datetime.construct
#Karem hope this logic will help you, this is working case for all your conditions please try this below one:
<?php
$startDate = '2016-12-26';
$endDate = '2017-03-04';
$varDate = $startDate;
while($varDate < $endDate){
$d = date('d', strtotime($varDate));
$Y = date('Y', strtotime($varDate));
$m = date('m', strtotime($varDate));
$days = cal_days_in_month(CAL_GREGORIAN,$m,$Y);
$time = strtotime($varDate);
if($varDate == $startDate){
$time = strtotime(date('Y-m-01', $time));
$days = $days - $d;
}
else if(date("Y-m", strtotime($varDate)) == date("Y-m", strtotime($endDate))){
$days = date("j", strtotime($endDate));
}
echo date('Y-m', strtotime($varDate)). ": ".$days."<br>";
$varDate = date('Y-m-d', strtotime("+1 month", $time));
}
This is long but easy to understand that how to achieve you your goal
<?php
function getMonthDays($start,$end){
if($start < $end){
$start_time = strtotime($start);
$last_day_of_start = strtotime(date("Y-m-t",$start_time));
$start_month_days = ($last_day_of_start - $start_time)/(60*60*24);
echo date("Y-m",$start_time).": ".$start_month_days."\n";
$days = "";
$start = date("Y-m-d", strtotime("+1 month", $start_time));
$start_time = strtotime($start);
while($start < $end){
$month = date("m",$start_time);
$year = date("Y",$start_time);
$days = date('t', mktime(0, 0, 0, $month, 1, $year));
echo date("Y-m",$start_time).": ".$days."\n";
$start = date("Y-m-d", strtotime("+1 month", $start_time));
$start_time = strtotime($start);
}
echo date("Y-m",strtotime($end)).": ".date("d",strtotime($end))."\n";
}else{
echo "Wrong Input";
}
}
getMonthDays('2016-12-26','2017-03-04');
?>
live demo : https://eval.in/781724
Function returns array : https://eval.in/781741
<?php
$d1 = strtotime('2016-12-26');
$d2 = strtotime('2017-03-04');
echo floor(($d2 - $d1)/(60*60*24));
?>
i used Carbon (https://carbon.nesbot.com/docs/) but you can do it with any other time lib.
$startDate = Carbon::createFromFormat('!Y-m-d', '2017-01-11');;
$endDate = Carbon::createFromFormat('!Y-m-d', '2018-11-13');;
$diffInMonths = $endDate->diffInMonths($startDate);
for ($i = 0; $i <= $diffInMonths; $i++) {
$start = $i == 0 ? $startDate->copy()->addMonth($i) : $startDate->copy()->addMonth($i)->firstOfMonth();
$end = $diffInMonths == $i ? $endDate->copy() : $start->copy()->endOfMonth();
echo $end->format('Y-m') . ' ' . ($end->diffInDays($start) + 1) . PHP_EOL;
}

First day between two dates in php

I want to get the first day of the year between two dates, for example if date1 is 2015-02-01 and date2 is 2017-01-07, the answer will be [2015-01-01, 2016-01-01, 2017-01-01]
I have tried the following for the data above:
$date1_rep_val=2015-02-01;
$date2_rep_val=2017-01-07;
$date1=(new DateTime("$date1_rep_val"))->modify('first day of this year');
$date2=(new DateTime("$date2_rep_val"))->modify('first day of this year');
$interval = DateInterval::createFromDateString('1 year');
$period = new DatePeriod($date1, $interval, $date2);
$f_cnt=0;
foreach ($period as $dt)
{
$tick_data[$f_cnt]= $dt->format("Y-m-d");
echo $tick_data[$f_cnt];
$f_cnt++;
}
But, the above code gives only 2015-01-01 and 2016-01-01 it is not giving 2017-01-01 , thanks for any help related to this question.
Why not simply:
$date1 = '2015-02-01';
$date2 = '2017-01-07';
$y1 = substr($date1, 0, 4);
$y2 = substr($date2, 0, 4);
$res= array();
for ($y = $y1; $y <= $y2; $y++) {
$res[] = $y . "-01-01";
}
Alternate (but essentially the same) solution with DateTime type using:
$date1_rep_val='2015-02-01';
$date2_rep_val='2017-01-07';
$date1 = new DateTime($date1_rep_val);
$date2 = new DateTime($date2_rep_val);
$year1 = $date1->format('Y');
$year2 = $date2->format('Y');
$newYearsDates = [];
if (new DateTime($year1 . '-01-01') == $date1) {
$newYearsDates[] = $date1;
}
if ($year2 > $year1) {
for ($year = $year1 + 1; $year <= $year2; $year++) {
$newYearsDates[] = new DateTime($year . '-01-01');
}
}
print_r($newYearsDates);

Based on start date and end date how to get financial years using php?

Financial years starts from April. So for example:
$startDate='2014-11-25' // Start date
$endDate ='2015-05-29' // End date
Output shows only FY-14-15 , But i want FY-14-15,FY-15-16
function calcFY($startDate,$endDate) {
$prefix = 'FY-';
$ts1 = strtotime($startDate);
$ts2 = strtotime($endDate);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
//get months
$diff = (($year2 - $year1) * 12) + ($month2 - $month1);
/**
* if end month is greater than april, consider the next FY
* else dont consider the next FY
*/
$total_years = ($month2 > 4)?ceil($diff/12):floor($diff/12);
$fy = array();
while($total_years >= 0) {
$prevyear = $year1 - 1;
//We dont need 20 of 20** (like 2014)
$fy[] = $prefix.substr($prevyear,-2).'-'.substr($year1,-2);
$year1 += 1;
$total_years--;
}
/**
* If start month is greater than or equal to april,
* remove the first element
*/
if($month1 >= 4) {
unset($fy[0]);
}
/* Concatenate the array with ',' */
return implode(',',$fy);
}
echo calcFY('2014-11-25','2015-05-29');
My problem is, Missing Fiscal year FY-15-16. Also what i have tried is not a better code to get this for more number of years say startdate ='2014-11-25' and endDate ='2015-05-29',
$total_years returns 1 instead of 2 - you have to adjust your calculation of $diff.
function calcFY($startDate, $endDate) {
$prefix = 'FY-';
$ts1 = strtotime($startDate);
$ts2 = strtotime($endDate);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
$fy = array();
$idx = 0;
if((int)$month1<4)
{
$fy[$idx] = $prefix . substr($year1-1, -2). '-'. substr($year1, -2);
$idx++;
}
for($i = $year1; $i<=$year2; $i++)
{
$fy[$idx] = $prefix . substr($i, -2).'-'.substr($i+1, -2); $idx++;
}
return implode(',',$fy);
}

Calculate hours within a date range and given time limit

Lets say I have the following daterange:
2014-01-10 11:00 - 2014-01-13 15:00
I also know that I can only count the hours between 09:00 - 16:00, how do I achieve this with PHP?
The above daterange should give me 25 hours (5 + 7 + 7 + 6), not sure how such PHP-function should look, though.
Completely untested, without any varatny
<?php
$time1 = new DateTime("11:00");
$time2 = new DateTime("15:00");
$date1 = new DateTime("2014-01-10");
$date2 = new DateTime("2014-01-13");
$start = new DateTime("9:00");
$end = new DateTime("16:00");
$maxperday = $end->diff($start)->format("%h");
$full_day_hours = ($date2->diff($date1)->format("%a")-1)*$maxperday;
$first_day_hours = min($maxperday,max(0,$end->diff($time1)->format("%h")));
$last_day_hours = min($maxperday,max(0,$time2->diff($start)->format("%h")));
$hours = $first_day_hours + $full_day_hours + $last_day_hours;
?>
EDIT: Tested now, corrected two errors, seems to work now.
I have made a solution now, but not too happy with my calculation if it is just one day. Here is the code:
$startDate = strtotime("2014-01-22 15:00");
$endDate = strtotime("2014-01-24 18:00");
$time1 = new DateTime(date("H:i", $startDate));
$time2 = new DateTime(date("H:i", $endDate));
$date1 = new DateTime(date("Y-m-d", $startDate));
$date2 = new DateTime(date("Y-m-d", $endDate));
$start = new DateTime("11:00");
$end = new DateTime("18:00");
$maxPerDay = $end->diff($start)->format("%h") != 0 ? $end->diff($start)->format("%h") : 24;
$days = $date2->diff($date1)->format("%a");
$hours = 0;
//Is it just one day and is time intersecting?
if($days == 0 && ($start <= $time2 && $time1 <= $end)){
$hours = $maxPerDay;
if($start < $time1 || $end > $time2){
if($time1 < $start){
$hours = $maxPerDay - $time2->diff($end)->format("%h");
}else if($time2 > $end){
$hours = $maxPerDay - $time1->diff($start)->format("%h");
}else{
$hours = $time1->diff($time2)->format("%h");
}
}
}else if($days > 0){
$firstDay = 0;
$lastDay = 0;
if($time1 < $end){
$firstDay = $time1 < $start ? $maxPerDay : $maxPerDay - $time1->diff($start)->format("%h");
}
if($time2 > $start){
$lastDay = $time2 > $end ? $maxPerDay : $maxPerDay - $time2->diff($end)->format("%h");
}
$hours = $lastDay + $firstDay + ($days - 1) * $maxPerDay;
}
echo $hours;

getting remaining days excluding weekends

i just want to know how to get the remaining days excluding the weekends. i tried subtracting two dates but i cant seem to find any solutions on removing weekends. well this is my code:
$date_registered = date('Y-m-d');
$date_planned = $_POST['start_date'];
$dueDate = $date_registered;
$numDays = 3;
$counter = 1;
while ($counter <= $numDays) {
$dueDate = date("Y-m-d", strtotime(date("Y-m-d", strtotime($dueDate)) . " +1 day"));
$dayOfTheWeek = date("l",strtotime($dueDate));
if ($dayOfTheWeek == "Saturday" || $dayOfTheWeek == "Sunday") {
continue;
}else {
$counter++;
}
}
echo $date_registered.'<br>';
echo $date_planned.'<br>';
//echo $dueDate;
$remaining_days = strtotime($date_registered) - strtotime($date_planned);
echo $remaining_days/86400;
i dont have any idea how to exclude the weekends .i hope you could help me.
Try this one
$date = date('Y-m-d');
$total_days_left = (strtotime($end_date) - strtotime($current_date)) / (60 * 60 * 24);
while (strtotime($date) <= strtotime($end_date)) {
$timestamp = strtotime($date);
$day = date('D', $timestamp);
if($day=='Sat' || $day=='Sun') {
$count++ ;
}
$date = date ("Y-m-d", strtotime("+1 day", strtotime($date)));
}
Let me know if you face any issue. Count will provide the number of week end days falling between these two days.From that you can count remaining day easily.
$total_day_left_excluding_weekends = $total_days_left - $count;
Refer date and strtotime on official PHP site.
$time = $sTime = START_TIMESTAMP;
$eTime = END_TIMESTAMP;
$count = 0;
while(date('w', $time) != 0) {
$time += 86400;
}
while($time < $eTime) {
$count++;
$time += 7 * 86400;
}

Categories