How to get elapsed week with start and end date, and week is started with Monday to Sunday
Example:
start - end = output week
2013-11-20 - 2013-11-24 = 1 week
2013-11-20 - 2013-11-28 = 2 weeks
2013-11-20 - 2013-12-10 = 4 weeks
You can use UNIX like time to easily manipulate things. Assuming $start and $end are in format YYYY-MM-DD
$start = strtotime($start); //To convert it into UNIX time
$end = strtotime($end);
echo "Number of weeks are : ".(($end-$start)/7*24*60*60);
This will print the number of weeks.
Related
I'm struggling to to write a PHP function that would calculate time difference between two hours (minus the brake) and the result would be in decimal format. My inputs are strings in 24-hour format (hh:mm):
$start = '07:00'; //started at 7 after midnight
$brake = '01:30'; //1 hour and 30 minutes of brake
$finish = '15:00'; //finished at 3 afternoon
//the desired result is to print out '6.5'
example 2
$start = '19:00'; //started late afternoon
$brake = '00:30'; //30 minutes of brake
$finish = '03:00'; //finished at 3 after midnight
//the desired result is to print out '7.5'
I used to have following formula in MS Excel which worked great:
=IF(D12>=F12,((F12+1)-D12-E12)*24,(F12-D12-E12)*24) '7.5 worked hours
where
D12 - Start time '19:00
F12 - Finish time '03:00
E12 - Brake time '00:30
I tried to play with strtotime() with no luck. My PHP version is 5.4.45. Please help
To provide a solution that doesn't require as much mathematics or parsing of the time values.
Assuming the day is not known, we can also account for the offset of the finish time and start time, when the start time is late at night.
Example: https://3v4l.org/FsRbT
$start = '07:00'; //started at 7 after midnight
$break = '01:30'; //1 hour and 30 minutes of brake
$finish = '15:00'; //finished at 3 afternoon
//create the start and end date objects
$startDate = \DateTime::createFromFormat('H:i', $start);
$endDate = \DateTime::createFromFormat('H:i', $finish);
if ($endDate < $startDate) {
//end date is in the past, adjust to the next day
//this is only needed since the day the time was worked is not known
$endDate->add(new \DateInterval('PT24H'));
}
//determine the number of hours and minutes during the break
$breakPeriod = new \DateInterval(vsprintf('PT%sH%sM', explode(':', $break)));
//increase the start date by the amount of time taken during the break period
$startDate->add($breakPeriod);
//determine how many minutes are between the start and end dates
$minutes = new \DateInterval('PT1M');
$datePeriods = new \DatePeriod($startDate, $minutes, $endDate);
//count the number of minute date periods
$minutesWorked = iterator_count($datePeriods);
//divide the number of minutes worked by 60 to display the fractional hours
var_dump($minutesWorked / 60); //6.5
This will work with any time values within a 24 hour period 00:00 - 23:59. If the day the times were worked are known, the script can be modified to allow for the day to be given and provide more precise timing.
To do this, convert you string times into a unix timestamp. This is an integer number of seconds since the unix epoch (00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, minus the number of leap seconds that have taken place since then). Do your math, then use the Date() function to format it back into your starting format:
<?php
$start = '19:00'; //started late afternoon
$break = '00:30'; //30 minutes of brake
$finish = '03:00'; //finished at 3 after midnight
//get the number of seconds for which we took a $break
//do this by converting break to unix timestamp, then extracting the hour and multiplying by 360
//and do the same extracting minutes and multiplying by 60
$breaktime = date("G",strtotime($break))*60*60 + date("i",strtotime($break))*60;
//get start time
$unixstart=strtotime($start);
//get finish time. Add a day if finish is tomorrow
if (strtotime($finish) < $unixstart) {
$unixfinish = strtotime('+1 day', strtotime($finish));
} else {
$unixfinish = strtotime($finish);
}
//figure out time worked
$timeworked = ($unixfinish - $unixstart - $breaktime) / 3600;
echo $timeworked;
?>
Another way, using DateTime. Basically, create 2 DateTime objects with the times of start and finish. To the start time, subtract the brake time, and the subtract from the result the end time.
You need to split the brake time in order to use modify().
<?php
$start = '07:00'; //started at 7 after midnight
$brake = '01:30'; //1 hour and 30 minutes of brake
$brakeBits = explode(":", $brake);
$finish = '15:00'; //finished at 3 afternoon
$startDate = \DateTime::createFromFormat("!H:i", $start);
$startDate->modify($brakeBits[0]." hour ".$brakeBits[1]." minutes");
$endDate = \DateTime::createFromFormat("!H:i", $finish);
$diff = $startDate->diff($endDate);
echo $diff->format("%r%H:%I"); // 06:30
Demo
I have some problem with the week number calculation in PHP/Mysql. here is my need
i have a start date and time ex."2014-09-27 00:00:00" saturday. So this week will be take as
firstweek (ie) 1. If the current date is 2014-10-03 12:16:11 this will be taking as second week or if the current date is 2014-10-08 09:09:12 it will shown as third week. So how can i calculate the week number for the current date from the start date.
2014-09-21 to 2014-09-27 is 1 week
2014-09-28 to 2014-10-04 is 2 week
2014-10-05 to 2014-10-11 is 3 week // It will continue
So please suggest me how can i do that?
You can do this with the DateTime object:
$datetime1 = new DateTime('2014-09-28');
$datetime2 = new DateTime('2014-10-04');
$interval = $datetime1->diff($datetime2);
// Output the difference in days, and convert to int
$days = (int) $interval->format('%d');
// Get number of full weeks by dividing days by seven,
// rounding it up, and adding one since you wanted start
// day to be week one.
$weeks = ceil($days / 7) + 1;
Here's a phiddle to demonstrate: http://phiddle.net/4
How would I structure the conditions to add two hours only to dates between 08:30 in the morning until 18:30 of the evening, excluding Saturday and Sunday?
In the case that a time near the border (e.g. 17:30 on Tuesday) is given, the left over time should be added to the beginning of the next "valid" time period.
For example: if the given date was in 17:30 on Tuesday, the two hour addition would result in 9:30 on Wednesday (17:30 + 1 hour = 18:30, 8:30 + the remainder 1 hour = 9:30). Or if the given date was in 17:00 on Friday, the result would be 9:00 on Monday (17:00 Friday + 1.5 hours = 18:30, 8:30 Monday + the remainder .5 hours = 9:00)
I know how to simply add two hours, as follows:
$idate1 = strtotime($_POST['date']);
$time1 = date('Y-m-d G:i', strtotime('+120 minutes', $idate1));
$_POST['due_date'] = $time1;
i have tried this this function and it works great except when i use a date like ( 2013-11-26 12:30 ) he gives me ( 2013-11-27 04:30:00 )
the problem is with 12:30
function addRollover($givenDate, $addtime) {
$starttime = 8.5*60; //Start time in minutes (decimal hours * 60)
$endtime = 18.5*60; //End time in minutes (decimal hours * 60)
$givenDate = strtotime($givenDate);
//Get just the day portion of the given time
$givenDay = strtotime('today', $givenDate);
//Calculate what the end of today's period is
$maxToday = strtotime("+$endtime minutes", $givenDay);
//Calculate the start of the next period
$nextPeriod = strtotime("tomorrow", $givenDay); //Set it to the next day
$nextPeriod = strtotime("+$starttime minutes", $nextPeriod); //And add the starting time
//If it's the weekend, bump it to Monday
if(date("D", $nextPeriod) == "Sat") {
$nextPeriod = strtotime("+2 days", $nextPeriod);
}
//Add the time period to the new day
$newDate = strtotime("+$addtime", $givenDate);
//print "$givenDate -> $newDate\n";
//print "$maxToday\n";
//Get the new hour as a decimal (adding minutes/60)
$hourfrac = date('H',$newDate) + date('i',$newDate)/60;
//print "$hourfrac\n";
//Check if we're outside the range needed
if($hourfrac < $starttime || $hourfrac > $endtime) {
//We're outside the range, find the remainder and add it on
$remainder = $newDate - $maxToday;
//print "$remainder\n";
$newDate = $nextPeriod + $remainder;
}
return $newDate;
}
I don't know if you still need this but here it is anyway. Requires PHP 5.3 or higher
<?php
function addRollover($givenDate, $addtime) {
$datetime = new DateTime($givenDate);
$datetime->modify($addtime);
if (in_array($datetime->format('l'), array('Sunday','Saturday')) ||
17 < $datetime->format('G') ||
(17 === $datetime->format('G') && 30 < $datetime->format('G'))
) {
$endofday = clone $datetime;
$endofday->setTime(17,30);
$interval = $datetime->diff($endofday);
$datetime->add(new DateInterval('P1D'));
if (in_array($datetime->format('l'), array('Saturday', 'Sunday'))) {
$datetime->modify('next Monday');
}
$datetime->setTime(8,30);
$datetime->add($interval);
}
return $datetime;
}
$future = addRollover('2014-01-03 15:15:00', '+4 hours');
echo $future->format('Y-m-d H:i:s');
See it in action
Here's an explanation of what's going on:
First we create a DateTime object representing our starting date/time
We then add the specified amount of time to it (see Supported Date and Time Formats)
We check to see if it is a weekend, after 6PM, or in the 5PM hour with more than 30 minutes passed (e.g. after 5:30PM)
If so we clone our datetime object and set it to 5:30PM
We then get the difference between the end time (5:30PM) and the modified time as a DateInterval object
We then progress to the next day
If the next day is a Saturday we progress to the next day
If the next day is a Sunday we progress to the next day
We then set our time to 8:30AM
We then add our difference between the end time (5:30PM) and the modified time to our datetime object
We return the object from the function
Hy, I have in database number of the week date ("W") and I want to display week interval like 28 Jan -> 3 Feb in this format, and I don't know if it's possible. Can you help?
Thanks!
Try this
$year = 2013;
$week_no = 6;
$week_start = new DateTime();
$week_start->setISODate($year,$week_no);
$week_end = clone $week_start;
$week_end = $week_end->add(new DateInterval("P1W"));
echo $week_start->format('d-M-Y') . " - ".$week_end->format('d-M-Y');
Transform your intervals into timestamps.
If its not the first day of the week get the first day of that week with strtotime "last sunday" (or monday) for the first date.
Do the same for the second date this time geting the last day of the week with "next saturday" (or sunday);
Get both dates W and make a mysql comparison between the weeks.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Grab current first and last day in week in php
I am trying to get the first and last day of the week, month, quarter, and year for a given day.
For instance, for day 2013-01-16, the first and last days would be:
Week - It would be 2013-01-13 and 2013-01-19 (assuming Sunday to Saturday)
Month - It would be 2013-01-01 and 2013-01-31
Quarter - It would be 2013-01-01 and 2013-03-31
Year - It would be 2013-01-01 and 2013-12-31
My purpose is to include them in a WHERE myDate BETWEEN 2013-01-13 AND 2013-01-19.
Both a standard MYSQL function solution (but not stored procedure, etc) or PHP solution is acceptable. Thank you
Solution for first and last day of given quarter.
$q=ceil($date->format("n")/3);
$months_start=array('January','April','July','October');
$months_end=array('March','June','September','December');
$m_start=$months_start[$q-1];
$m_end=$months_end[$q-1];
$modifier='first day of '.$m_start.' '.$date->format('Y');
$date->modify($modifier);
echo $modifier.': '.$date->format('Y-m-d').'<br>';
$modifier='last day of '.$m_end.' '.$date->format('Y');
$date->modify($modifier);
echo $modifier.': '.$date->format('Y-m-d').'<br>';
You can use strtotime:
$date = strtotime('2013-01-16');
// First/last day of week
$first = strtotime('last Sunday');
$last = strtotime('next Saturday');
Or PHP's native DateTime functionality:
$date = new DateTime('2013-01-16');
// First/last day of month
$first = $date->modify('first day of this month');
$last = $date->modify('last day of this month');
Getting the first/last day of a year might be a little bit more tricky:
// Get date
$date = new DateTime('2013-01-16');
// Format to get date
$year = $date->format('Y');
// Get first day of Jan and last day of Dec
$first = $date->modify("first day of January $year");
$last = $date->modify("last day of December $year");