Calculate hours within a date range and given time limit - php

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;

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);

How to calculate exact months between two dates

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;

PHP - Find the difference between two times

I'm trying to calculate the time difference (in hours) between two times inputted via a timepicker. I have working JavaScript code, but would rather use server side code to make this calculation as it's quite important. If you want me to post the working JS code let me know in comments.
Calculating the difference between the times is easy enough, but I require the output in a particular format. For example inputs of '07:30' and '14:00' would return 6.5 rather than 6.3. The reason for this is to make it easier for me to use this time difference in calculations.
PHP Code i've tried:
Attempt #1:
<?php
$start_time = new DateTime('07:30');
$end_time = new DateTime('14:00');
$time_diff = date_diff($start_time,$end_time);
echo $time_diff->format('%h.%i');
?>
Returns 6.3 as expected.
Attempt #2:
<?php
$start_time = "07:30";
$end_time = "14:00";
$start_time = str_replace(":", "", $start_time);
$end_time = str_replace(":", "", $end_time);
$res = $end_time - $start_time;
$result = $res / 100;
echo $result;
?>
Returns 6.7.
Tool used to test output: http://codepad.viper-7.com/
Just extract the minutes:
<?php
$start_time = new DateTime('07:30');
$end_time = new DateTime('14:00');
$time_diff = date_diff($start_time,$end_time);
$hours = (int)$time_diff->format('%h');
$hour_part = ((int)$time_diff->format('%i')) / 60;
echo $hours + $hour_part;
?>
Make sure to change the type to (int) before any calculations.
If you divide the minutes by 60 you will get what part of a hour they represent.
<?php
$start_time = new DateTime('07:30');
$end_time = new DateTime('14:00');
$time_diff = date_diff($start_time,$end_time);
echo $time_diff->format('%h') + $time_diff->format('%i')/60;
?>
Returns 6.5 as expected.
You can try this:
<?php
$start_time = strtotime("07:30");
$end_time = strtotime("14:00");
$diff = $end_time - $start_time;
echo $diff;
1 hour = 60 min.
Demo.
$start_time = "07:30";
$end_time = "14:00";
list($h1, $m1) = explode(':', $start_time);
list($h2, $m2) = explode(':', $end_time);
// 1 hr = 60 min
$res = ($h2*60 - $m2) - ($h1*60 + $m1);
$result = floor($res/60) .'.'. $res % 60;
echo $result;
Try this
function time_difference($time1, $time2) {
$time1 = strtotime("1980-01-01 $time1");
$time2 = strtotime("1980-01-01 $time2");
if ($time2 < $time1) {
$time2 += 86400;
}
return date("H:i:s", strtotime("1980-01-01 00:00:00") + ($time2 - $time1));
}
echo time_difference("11:30:30", "22:40:59");
You can use this function to get the time difference between two times:
function timeBetween($start_date,$end_date)
{
$diff = $end_date-$start_date;
$seconds = 0;
$hours = 0;
$minutes = 0;
if($diff % 86400 <= 0){$days = $diff / 86400;} // 86,400 seconds in a day
if($diff % 86400 > 0)
{
$rest = ($diff % 86400);
$days = ($diff - $rest) / 86400;
if($rest % 3600 > 0)
{
$rest1 = ($rest % 3600);
$hours = ($rest - $rest1) / 3600;
if($rest1 % 60 > 0)
{
$rest2 = ($rest1 % 60);
$minutes = ($rest1 - $rest2) / 60;
$seconds = $rest2;
}
else{$minutes = $rest1 / 60;}
}
else{$hours = $rest / 3600;}
}
if($days > 0){$days = $days.' days, ';}
else{$days = false;}
if($hours > 0){$hours = $hours.' hours, ';}
else{$hours = false;}
if($minutes > 0){$minutes = $minutes.' minutes, ';}
else{$minutes = false;}
$seconds = $seconds.' seconds';
return $days.''.$hours.''.$minutes.''.$seconds;
}

How to get a day of month from "what I know"?

Need some logic here:
Need to get day of month date("d")
What I know:
$year = 2013;
$month = 10;
$week_nr_of_month = 3; // from 1 to 6 weeks in month
$day_of_week = 0; // Sunday date("w")
Thanks for logic
Result must be: 13 October
This was fun to figure out.
<?php
$year = 2013;
$month = 10;
$week_nr_of_month = 3; // from 1 to 6 weeks in month
$day_of_week = 0; // Sunday date("w")
$start = new DateTime();
$start->setDate($year, $month, '1');
$end = clone $start;
$end->modify('last day of this month');
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
if ($date->format('w') == $day_of_week) {
$wom = week_of_month($date->format('Y-m-d'));
if ($week_nr_of_month == $wom) {
echo $date->format('Y-m-d');
}
}
}
function week_of_month($date) {
$dt = new DateTime($date);
$bg = clone $dt;
$bg->modify('first day of this month');
$day_of_first = $bg->format('N');
$day_of_month = $dt->format('j');
return floor(($day_of_first + $day_of_month - 1) / 7) + 1;
}
See it in action
Used this answer for inspiration to get the week number for the date.
strtotime may be of help. Can't test right now, but...
$ordinal = array("first","second","third","fourth","fifth");
$weekdays = array("monday","tuesday","wednesday","thursday","friday","saturday","sunday");
$timestamp = strtotime($year."-".$month." ".$ordinal[$week_nr_of_month]." ".$weekdays[$day_of_week]);

Categories