Finding last 7 working days in PHP - php

I am trying to find out last 7 working days (excluding Saturday and Sunday) from the current day. I am able to get last 7 days of the week, but unable to get the 7 working day's.
//code to found last 7 days
$date = '04/30/2009'; // set current date
// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime($date);
// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 1;
if ($offset < 0) {
$offset = 6;
}
// calculate timestamp for the Monday
$ts = $ts - $offset*86400;
// loop from Monday till Sunday
for ($i = 0; $i < 7; $i++, $ts += 86400){
print date("m/d/Y l", $ts) . "\n". "<br>";
}
But I wanted to find last 7 working days. Thanks in advance!

It's relatively easy to work backwards from a point int time to find the "working days" but finding "holidays" is far more complicated and would require considerably more code than this I suspect.
Using the DateTime class you can use the sub method to subtract whatever interval value you wish, in this case P1D is one day.
$strdate='04/30/2009';
$days=11;
$timezone=new DateTimeZone('Europe/London');
$interval=new DateInterval('P1D');
$start=new DateTime( date( DATE_COOKIE, strtotime( $strdate ) ), $timezone );
$end=new DateTime( date( DATE_COOKIE, strtotime( $start->format( DATE_COOKIE ) . '-' . $days .' days' ) ), $timezone );
$dates=array();
while( $start->sub( $interval ) > $end ){
/* is the day integer less than 6(sat)? */
if( $start->format('N') < 6 && count( $dates ) < 7 ) $dates[]=$start->format( DATE_COOKIE );
}
echo '<pre>',print_r( $dates,true ),'</pre>';
This outputs:
Array
(
[0] => Wednesday, 29-Apr-09 00:00:00 BST
[1] => Tuesday, 28-Apr-09 00:00:00 BST
[2] => Monday, 27-Apr-09 00:00:00 BST
[3] => Friday, 24-Apr-09 00:00:00 BST
[4] => Thursday, 23-Apr-09 00:00:00 BST
[5] => Wednesday, 22-Apr-09 00:00:00 BST
[6] => Tuesday, 21-Apr-09 00:00:00 BST
)
I did a little playing around with a public api for getting public holiday information and cobbled the following together...I don't know what sort of coverage this api has for different countries but might be worth investigation.
Different country and region codes can be found here
$api='http://kayaposoft.com/enrico/json/v1.0/';
$params=array(
'action' => 'getPublicHolidaysForDateRange',
'fromDate' => '',
'toDate' => '',
'country' => 'eng' #England
);
$strdate='2017/12/30';
$days=7;
$timezone=new DateTimeZone('Europe/London');
$interval=new DateInterval('P1D');
$start=new DateTime( date( 'Y-m-d', strtotime( $strdate ) ), $timezone );
$end=new DateTime( date( 'Y-m-d', strtotime( $start->format( 'Y-m-d' ) . '-' . $days .' days' ) ), $timezone );
$params['fromDate']=$end->format('d-m-Y');
$params['toDate']=$start->format('d-m-Y');
$query=http_build_query( $params );
$url=$api.'?'.$query;
$json=json_decode( file_get_contents( $url ) );
if( json_last_error() !== 0 ){
$json=false;
}
function isholiday( $obj=false, $y=0, $m=0, $d=0 ){
if( $obj && !empty( $obj ) ){
foreach( $obj as $item ){
$date=$item->date;
if( $date->day==$d && $date->month=$m && $date->year==$y ) return $item->localName;
}
}
return false;
}
$dates=array();
while( $start->sub( $interval ) > $end ){
if( $start->format('N') < 6 && count( $dates ) < $days ) {
$holiday=isholiday( $json, $start->format('Y'), $start->format('m'), $start->format('d') );
$date=$start->format( 'Y-m-d' );
$dates[]=$holiday ? $date .' - '.$holiday : $date;
}
}
echo '<pre>',print_r( $dates, true ),'</pre>';
This outputs the following:
Array
(
[0] => 2017-12-29
[1] => 2017-12-28
[2] => 2017-12-27
[3] => 2017-12-26 - Boxing Day
[4] => 2017-12-25 - Christmas Day
)

Finding holidays will be more complicated.
One solution can be like saving the holidays in advance and skip them if they comes in the condition.
One simple solution for your problem can be like this.
<?php
$holiday = array(
'2017-12-16' => 'Victory Day of Bangladesh',
'2017-12-25' => 'Christmas'
);
$i = 0;
$work_day = '2017-12-26';
while($i != 7)
{
$work_day = date('Y-m-d', strtotime('-1 day', strtotime($work_day)));
$day_name = date('l', strtotime($work_day));
if($day_name != 'Saturday' && $day_name != 'Sunday' && !isset($holiday[$work_day]))
{
echo $work_day."\n";
$i++;
}
}
?>

If you need 7 days without weekend days you need to check the numeric representation of the day of the week, ie "N" Format of date('N').
When skipping 2 weekend days you need increase the for loop to 9 days:
//code to found last 7 days
$date = '04/30/2009'; // set current date
// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime($date);
// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 1;
if ($offset < 0) {
$offset = 6;
}
// calculate timestamp for the Monday
$ts = $ts - $offset*86400;
// loop from Monday till Sunday
for ($i = 0; $i < 9; $i++, $ts += 86400){
if(date("N", $ts) < 6){ // day code is less then weekday 6 & 7
print date("m/d/Y l", $ts) . "\n". "<br>";
}
}
https://eval.in/916514

Simple code with possibility to add holidays:
<?php
$date = new DateTime('03/02/2009');
$interval = new DateInterval('P1D');
function isWorkingDay($date)
{
$weekDay = $date->format('w');
if ($weekDay == 0) // sunday
return false;
if ($weekDay == 6) // saturday
return false;
if ($date->format('m-d') == '07-05') // your check, example 5th July
return false;
return true;
}
$workingDays = [];
while(count($workingDays) != 7) {
if(isWorkingDay($date)) {
$workingDays[] = clone $date;
}
$date->sub($interval);
}
foreach($workingDays as $workingDay) {
echo $workingDay->format('Y-m-d') . ', ';
}
Result - list of days without weekend days:
2009-03-02, 2009-02-27, 2009-02-26, 2009-02-25, 2009-02-24, 2009-02-23, 2009-02-20,

Related

Calculating working hours time difference in PHP

I wanted to calculate the number of hours between the encoded date and completion date. As of now I can compute the time difference between the two datetimes excluding the Saturdays and Sundays. My problem is I need to exclude the lunch breaks (12:00 am to 1:00 pm) and holidays.
Here is my code:
<?php
function business_hours($start, $end){
$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval( "PT1H" );
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
$count = 0;
$holidays = [
"Human Rights Day" => new DateTime(date('Y') . '-03-21'),
"Good Friday" => new DateTime(date('Y') . '-03-30'),
"Family Day" => new DateTime(date('Y') . '-04-02'),
"Freedom Day" => new DateTime(date('Y') . '-04-27'),
"Labour Day" => new DateTime(date('Y') . '-05-01'),
"Youth Day" => new DateTime(date('Y') . '-06-16'),
"National Women's Day" => new DateTime(date('Y') . '-08-09'),
"Heritage Day" => new DateTime(date('Y') . '-09-24'),
"Day of Reconciliation" => new DateTime(date('Y') . '-12-16'),
];
foreach($period as $date){
$startofday = clone $date;
$startofday->setTime(8,00);
$endofday = clone $date;
$endofday->setTime(17,00);
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday'))){
$count++;
}
}
echo $count;
}
$start = '2020-02-14 08:00:00';
$end = '2020-02-17 08:00:00';
$go = business_hours($start,$end);
//output 9 hours
?>
As per my code, I set the working hours from 8:00 to 17:00 and then excluded the Saturdays and Sundays. As per my example the output will be 9 (including the lunch break). How can I exclude the lunch break and holidays?
Update
The completion time can be more than 1 day. For example, the start date/time is 2020-02-14 08:00:00 and the completion time is 2020-02-19 08:00:00 the output is 27 hours. The calculation should exclude the lunch breaks of each day that have 12:00am to 1:00pm and holidays in between.
Update
I added an array of holidays, how can I exclude these holidays?
Since you're using a static/defined lunch break, you can use the following logic:
If $startDate is a weekday, and before 12:00, that's the start date for lunch calculation; otherwise it's the next weekday.
If the $endDate is a weekday, and after 13:00, that's the end date for lunch calculation; otherwise, it's the previous weekday
Actual number of lunch breaks equals the difference between those recalculated dates, at one hour each.
The following is pseudocode:
if(!in_array($startDate->format('l'), array('Sunday','Saturday')) && ($startDate->format('g') < 12) {
$startForLunch = $startDate;
}
else {
$startForLunch = new DateTime($start, '+1 day');
while(in_array($startDate->format('l'), array('Sunday','Saturday'))){
$startForLunch->add('1 day');
}
}
if(!in_array($endDate->format('l'), array('Sunday','Saturday')) && ($endDate->format('g') > 13) {
$endForLunch = $end;
}
else {
$endForLunch = new DateTime($endDate, '-1 day');
while(in_array($endDate->format('l'), array('Sunday','Saturday'))){
$endForLunch->add('-1 day');
}
}
$lunchPeriods = $endForLunch - $startForLunch + 1;
how about try add some condition inside loop each day to skip some hours
($date->format('H') <= 12 || $date->format('H') > 13)
it will skip if hour above 12 to 13 (if you use 24 format hour)
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13)){
$count++;
}
UPDATE
okay if your "holydays" is cutom maybe be good to add some paramerter to your function to store list of your holydays
function business_hours($start, $end,$holyDays = null){
//another line
}
and check every loop of dates is in on holydays list or not
in_array($date->format('Y-m-d'), $holyDays)
you will get filter of break time and custom holyday
function business_hours($start, $end,$holyDays = null){
$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval( "PT1H" );
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
$count = 0;
foreach($period as $date){
$startofday = clone $date;
$startofday->setTime(8,00);
$endofday = clone $date;
$endofday->setTime(17,00);
//just some var to use in conditional check
$notHolyday = true;
//now check the array of holyday and check if in range dates is same with holydays we have
if($holyDays != null && is_array($holyDays) && in_array($date->format('Y-m-d'), $holyDays)){
$notHolyday = false;
}
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13) && $notHolyday){
$count++;
}
}
echo $count;
}
$start = '2020-02-14 08:00:00';
$end = '2020-02-19 08:00:00';
$holyDays = array('2020-02-17','2020-02-18');
$count = business_hours($start,$end,$holyDays);
echo $count;
i hope this is want you want

How can we split dates in php?

How can we split dates using PHP? Is there any built in function in PHP?
2016-11-01 10:00:00 till 2016-11-03 18:00:00
I need to split above date in to required dates:-
2016-11-01 10:00:00 till 23:59:59
2016-11-02 00:00:00 till 23:59:59
2016-11-03 00:00:00 till 18:00:00
To my knowledge PHP does not provide such built-in feature.
But you can easily achieve this with th DateTime object :
$interval = '2016-11-01 10:00:00 till 2016-11-03 18:00:00';
$dates = explode(' till ', $interval);
if(count($dates) == 2) {
$current = $begin = new DateTime($dates[0]);
$end = new DateTime($dates[1]);
$intervals = [];
// While more than 1 day remains
while($current->diff($end)->format('%a') >= 1) {
$nextDay = clone $current;
$nextDay->setTime(23,59,59);
$intervals []= [
'begin' => $current->format('Y-m-d H:i:s'),
'end' => $nextDay->format('Y-m-d H:i:s'),
];
$current = clone $nextDay;
$current->setTime(0,0,0);
$current->modify('+1 day');
}
// Last interval : from $current to $end
$intervals []= [
'begin' => $current->format('Y-m-d H:i:s'),
'end' => $end->format('Y-m-d H:i:s'),
];
print_r($intervals);
}
You can use for loop to achieve such type of result. Your requirement is to print date in one day difference between start and end date. I have write code for this .
<?php
$startDate = strtotime('2016-11-01 10:00:00');
$endDate = strtotime('2016-11-03 18:00:00');
for ($loopStart = $startDate; $loopStart <= $endDate; $loopStart = strtotime('+1 day', $loopStart)) {
// check last date
if($endDate >= strtotime('+1 day', $loopStart)){
echo date('Y-m-d', $loopStart).' 23:59:59';
}
else{
echo date('Y-m-d', $loopStart).' '.date('H:i:s',$endDate);
}
echo "<br>";
}
?>
The output of the code is -
2016-11-01 23:59:59
2016-11-02 23:59:59
2016-11-03 18:00:00

Finding every nth X-day of the month using PHP, will it always be correct?

OK, I've put together some code which, in this particular case, finds the second (2nd) Sunday of every month depending on whether or not you're before or after it (specifically at 5:00PM that day).
<?php
$count = 0;
for( $i = 1 ; $i <=30 ; $i++ )//30 is much more than is needed
{
$date = date_create_from_format('Y-m-d H:i:s',date('Y-m-').$i.' 17:00:00');
if( $date->format('D') == 'Sun' )
{
$count++;
}
if( $count == 2 )
{
break;
}
}
$count = 0;
if( date('Y-m-d H:i:s') > $date->format('Y-m-d H:i:s') )
{
for( $i = 1 ; $i <=30 ; $i++ )
{
$date = date_create_from_format('Y-m-d H:i:s',date('Y-').(string)(((int)date('n')+1)%12).'-'.$i.' 17:00:00');
if( $date->format('D') == 'Sun' )
{
$count++;
}
if( $count == 2 )
{
break;
}
}
echo $date->format('F jS, Y');
}
else
{
echo $date->format('F jS, Y');
}
?>
So if you are at the green star it will display August 14, and if you're at the blue star it will display September 11:
My question is will this always be correct indefinitely?
Using DateTime class:
$date = new DateTime( 'second sunday of this month, 17:00' );
if( date_create()->diff( $date )->invert )
{
$date = new DateTime( 'second sunday of next month, 17:00' );
}
To retrieve second sunday of this month... just pass “second sunday of this month” to DateTime, then, if the date is in the past (DateInterval->invert return 1 if the interval is negative, 0 otherwise), you can retrieve second sunday of next month.
The code seems all right. But you don't even need to use all the string comparison and loops. Just pass an argument like "Second Sunday of 2016-04, 17:00" to strtotime() and then check whether the date has passed or not.
Strtotime() takes care of all the exceptional situations like leap-year, next month being Janury of the next year, etc.
$currentMonthSecondSunday = date( 'Y-m-d H:i:s', strtotime( 'Second Sunday of ' . date( 'Y-m' ) . ', 17:00' ) );
$currentDate = date( 'Y-m-d H:i:s' );
if ( $currentDate < $currentMonthSecondSunday ) {
echo $currentMonthSecondSunday;
} else {
$nextMonthSecondSunday = date( 'Y-m-d H:i:s', strtotime( 'Second Sunday of ' . date( 'Y-m', strtotime( 'next month' ) ) . ', 17:00' ) );
echo $nextMonthSecondSunday;
}

Find week number dates with php

is there a solution to find the start and the end date for a specific week number. Example:
If i enter $week = 5, i want to get 2016-03-28 - 2016-04-03. I need only for the current year.
I think what you're looking for is strtotime and date.
<?php
$year = 2016;
$week = 1;
$a = strtotime('January 1 ' . $year);
$b = date('N', $a) - 1;
$c = $a;
$a += (7 - $b) * 86400;
if($week > 1) {
$start = $a + (($week - 2) * 604800);
$end = $start + ($b ? 518400 : 604800);
}
else {
$start = $c;
$end = $a - 86400;
}
echo date('l jS \of F Y', $start);
echo '<br />';
echo date('l jS \of F Y', $end);
Friday 1st of January 2016
Sunday 3rd of January 2016
As a function with some validation. This version will even keep the last week of the year short, like the first week, if the last week rolls into the next year. Returns false if the week does not fall within the year:
<?php
function weekdays($week, $year = false) {
$week = floor($week);
if($week < 0 || $week > 53)
return false;
if($year == false)
$year = date('Y');
$a = strtotime('January 1 ' . $year);
$b = date('N', $a) - 1;
$c = $a;
$a += (7 - $b) * 86400;
if($week > 1) {
$a += (($week - 2) * 604800);
$b = $a + ($b ? 518400 : 604800);
return
date('Y', $a) == $year
? array(
'first' => $a,
'last' =>
date('Y', $b) > $year
? $b - (8 - date('N', $b)) * 86400
: $b
) : false;
}
else
return array('first' => $c, 'last' => $a - 86400);
}
$week = weekdays(14, 2016);
echo date('l jS \of F Y', $week['first']);
echo '<br />';
echo date('l jS \of F Y', $week['last']);
Monday 28th of March 2016
Sunday 3rd of April 2016
You can do this with DateTime:
$year = 2016;
$week = 13;
$date = new DateTime();
$date->setISODate($year, $week);
$start = $date->format('Y-m-d');
$end = $date->modify('+6 days')->format('Y-m-d');
echo 'Week start: '. $start , "\n"; // 2016-03-28
echo 'Week end: '. $end , "\n"; // 2016-04-03
You could use PHP relative datetime functions (http://php.net/manual/en/datetime.formats.relative.php) like:
//date_default_timezone_set('Europe/Amsterdam');
$date = new DateTime();
$date->modify('2016W5'); //First day of week 5 of 2016
$date->modify('2016W5 +6 days'); //Last day of week 5 of 2016
Or build your own function:
function week_start_date($wk_num, $yr, $first = 1, $format = 'F d, Y')
{
$wk_ts = strtotime('+' . $wk_num . ' weeks', strtotime($yr . '0101'));
$mon_ts = strtotime('-' . date('w', $wk_ts) + $first . ' days', $wk_ts);
return date($format, $mon_ts);
}
$sStartDate = week_start_date($week_number, $year);
$sEndDate = date('F d, Y', strtotime('+6 days', strtotime($sStartDate)));
Extracted from here: Finding First day of week via php
If i enter $week = 5, i want to get 2016-03-28 - 2016-04-03.
So, I think you want monday and sunday of 5th week of march.
To obtain this, I create a simple function that require a date string (YYYY-MM-DD) and the week number. The function create a DateTime object from given string, then modify it in the first day of month, then retrieve first day of date week and add $week -1 weeks. At this point we have the first day (monday) of desired week. We clone this date to $end and we add to it 6 days.
Function returns an object with $start and $end dates as properties, obtained casting an array created by compact():
function monthWeek( $date, $week )
{
$start = new DateTime( $date );
$start->modify( 'first day of this month' );
$start->modify( '-'.($start->format( 'w' )-1).' days' );
$start->modify( '+'.($week-1).' weeks' );
$end = clone $start;
$end->modify( '+6 days' );
return (object) compact( 'start', 'end' );
}
Calling above function with a casual day of march:
$week = monthWeek( '2016-03-25', 5 );
echo $week->start->format( 'l, Y-m-d' );
echo " => ";
echo $week->end->format( 'l, Y-m-d' );
we obtain this:
Monday, 2016-03-28 => Sunday, 2016-04-03
You can use the function also for retrieve year-based week, using a day of january as first arguments:
$week = monthWeek( '2016-01-25', 14 );
echo $week->start->format( 'l, Y-m-d' );
echo " => ";
echo $week->end->format( 'l, Y-m-d' );
will output:
Monday, 2016-03-28 => Sunday, 2016-04-03
phpFiddle demo

Get Start and End Days for a Given Week in PHP

I'm trying to get the week range using Sunday as the start date, and a reference date, say $date, but I just can't seem to figure it out.
For example, if I had $date as 2009-05-01, I would get 2009-04-26 and 2009-05-02. 2009-05-10 would yield 2009-05-10 and 2009-05-16. My current code looks like this (I can't remember where I lifted it from, as I forgot to put down the url in my comments):
function x_week_range(&$start_date, &$end_date, $date)
{
$start_date = '';
$end_date = '';
$week = date('W', strtotime($date));
$week = $week;
$start_date = $date;
$i = 0;
while(date('W', strtotime("-$i day")) >= $week) {
$start_date = date('Y-m-d', strtotime("-$i day"));
$i++;
}
list($yr, $mo, $da) = explode('-', $start_date);
$end_date = date('Y-m-d', mktime(0, 0, 0, $mo, $da + 6, $yr));
}
I realized all it did was add 7 days to the current date. How would you do this?
I would take advantange of PHP's strtotime awesomeness:
function x_week_range(&$start_date, &$end_date, $date) {
$ts = strtotime($date);
$start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts);
$start_date = date('Y-m-d', $start);
$end_date = date('Y-m-d', strtotime('next saturday', $start));
}
Tested on the data you provided and it works. I don't particularly like the whole reference thing you have going on, though. If this was my function, I'd have it be like this:
function x_week_range($date) {
$ts = strtotime($date);
$start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts);
return array(date('Y-m-d', $start),
date('Y-m-d', strtotime('next saturday', $start)));
}
And call it like this:
list($start_date, $end_date) = x_week_range('2009-05-10');
I'm not a big fan of doing math for things like this. Dates are tricky and I prefer to have PHP figure it out.
To everyone still using mktime(), strtotime() and other PHP functions... give the PHP5 DateTime Class a try. I was hesitant at first, but it's really easy to use. Don't forget about using clone() to copy your objects.
Edit: This code was recently edited to handle the case where the current day is Sunday. In that case, we have to get the past Saturday and then add one day to get Sunday.
$dt_min = new DateTime("last saturday"); // Edit
$dt_min->modify('+1 day'); // Edit
$dt_max = clone($dt_min);
$dt_max->modify('+6 days');
Then format as you need it.
echo 'This Week ('.$dt_min->format('m/d/Y').'-'.$dt_max->format('m/d/Y').')';
Make sure to set your timezone early in your code.
date_default_timezone_set('America/New_York');
Apparently 'w' formatting value of date() or the format method of a DateTime object will return the day of the week as a number (by default, 0=Sunday, 1=Monday, etc)
You could take this and subtract it's value as days from the current day to find the beginning of the week.
$start_date = new DateTime("2009-05-13");
$day_of_week = $start_date->format("w");
$start_date->modify("-$day_of_week day");
$start_date will now be equal to the Sunday of that week, from there you can add 7 days to get the end of the week or what-have-you.
Base on #jjwdesign's answer, I developed a function that can calculate the beginning and ending of a week for a specific date using the DateTime class. WILL WORK ON PHP 5.3.0++
The difference is you can set the day you want as the "beginning" between 0 (monday) and 6 (sunday).
Here's the function :
if(function_exists('grk_Week_Range') === FALSE){
function grk_Week_Range($DateString, $FirstDay=6){
# Valeur par défaut si vide
if(empty($DateString) === TRUE){
$DateString = date('Y-m-d');
}
# On va aller chercher le premier jour de la semaine qu'on veut
$Days = array(
0 => 'monday',
1 => 'tuesday',
2 => 'wednesday',
3 => 'thursday',
4 => 'friday',
5 => 'saturday',
6 => 'sunday'
);
# On va définir pour de bon le premier jour de la semaine
$DT_Min = new DateTime('last '.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString);
$DT_Max = clone($DT_Min);
# On renvoie les données
return array(
$DT_Min->format('Y-m-d'),
$DT_Max->modify('+6 days')->format('Y-m-d')
);
}
}
Results :
print_r(grk_Week_Range('2013-08-11 16:45:32', 0));
print_r(grk_Week_Range('2013-08-11 16:45:32', 1));
print_r(grk_Week_Range('2013-08-11 16:45:32', 2));
print_r(grk_Week_Range('2013-08-11 16:45:32', 3));
print_r(grk_Week_Range('2013-08-11 16:45:32', 4));
print_r(grk_Week_Range('2013-08-11 16:45:32', 5));
print_r(grk_Week_Range('2013-08-11 16:45:32', 6));
Array
(
[0] => 2013-07-29
[1] => 2013-08-04
)
Array
(
[0] => 2013-07-30
[1] => 2013-08-05
)
Array
(
[0] => 2013-07-31
[1] => 2013-08-06
)
Array
(
[0] => 2013-07-25
[1] => 2013-07-31
)
Array
(
[0] => 2013-07-26
[1] => 2013-08-01
)
Array
(
[0] => 2013-07-27
[1] => 2013-08-02
)
Array
(
[0] => 2013-07-28
[1] => 2013-08-03
)
I have decided to go with the approach at http://boonedocks.net/mike/archives/114-Figuring-the-Start-of-the-Week-with-PHP.html instead.
Here's my version, which uses a similar notion to Clay's:
/**
* Start of the week
*
* 0 = Sun, 1 = Mon, etc.
*/
define( 'WEEK_START', 0 );
/**
* Determine the start and end dates for
* the week in which the specified date
* falls
*
* #param $date Date in week
* #param $start Week start (out)
* #param $end Week end (out)
*/
function week_bounds( $date, &$start, &$end ) {
$date = strtotime( $date );
// Find the start of the week, working backwards
$start = $date;
while( date( 'w', $start ) > WEEK_START ) {
$start -= 86400; // One day
}
// End of the week is simply 6 days from the start
$end = date( 'Y-m-d', $start + ( 6 * 86400 ) );
$start = date( 'Y-m-d', $start );
}
Lightly tested. Code may not be bulletproof, or handle dates in the far past or future. Use at your own risk. Do not immerse the code in water. Do not show the code to those of a nervous disposition, or with a hatred of the dollar sign. Not tested on animals. Safe for use by vegetarians. Author warrants that the code will never, ever speak to you. In the unlikely event that the code does try to engage you in conversation, the author advises you to disregard any and all advice it gives.
Use this to get the "week" number from any given date.
//October 29, 2009 is my birthday
echo $week date('W', strtotime('2009-10-29'));
//OUTPUT: 44
//October 29 is the 44th week in the year 2009
Now pass the parameters for getWeekDates function as "year (2009)" and "$week".
function getWeekDates($year, $week, $start=true){
$from = date("Y-m-d", strtotime("{$year}-W{$week}-1")); //Returns the date of monday in week
$to = date("Y-m-d", strtotime("{$year}-W{$week}-7")); //Returns the date of sunday in week
if($start) {
return $from;
} else {
return $to;
}
//return "Week {$week} in {$year} is from {$from} to {$to}.";
}
For More Info Please refer this link
http://blog.ekini.net/2009/07/09/php-get-start-and-end-dates-of-a-week-from-datew/
In trying to find a more streamlined version of the accepted answer by Paolo Bergantino, I discovered a really nice way to get this done:
function x_week_range2($date) {
$ts = strtotime($date);
$start = strtotime('sunday this week -1 week', $ts);
$end = strtotime('sunday this week', $ts);
return array(date('Y-m-d', $start), date('Y-m-d', $end));
}
The 'sunday this week' string always means "The Sunday at the end of this week." If used on a timestamp that falls on a Sunday, it will be the following Sunday. This lets you avoid the need for the ternary operator in Paola's solution.
You can now use DateTime to get start/end dates of week(s)
function getDateRangeForAllWeeks($start, $end){
$fweek = getDateRangeForWeek($start);
$lweek = getDateRangeForWeek($end);
$week_dates = [];
while($fweek['sunday']!=$lweek['sunday']){
$week_dates [] = $fweek;
$date = new DateTime($fweek['sunday']);
$date->modify('next day');
$fweek = getDateRangeForWeek($date->format("Y-m-d"));
}
$week_dates [] = $lweek;
return $week_dates;
}
function getDateRangeForWeek($date){
$dateTime = new DateTime($date);
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');
return ['monday'=>$monday->format("Y-m-d"), 'sunday'=>$sunday->format("Y-m-d")];
}
Usage
print_r( getDateRangeForWeek("2016-05-07") );
print_r( getDateRangeForAllWeeks("2015-11-07", "2016-02-15") );
To be honest, I have trouble understanding the code you posted ;)
I guess something like this should do the trick:
function get_week($date) {
$start = strtotime($date) - strftime('%w', $date) * 24 * 60 * 60;
$end = $start + 6 * 24 * 60 * 60;
return array('start' => strftime('%Y-%m-%d', $start),
'end' => strftime('%Y-%m-%d', $end));
}
Without doing so much string manipulation, you can do some simple math on the timestamps.
function getDateRange(&$start, &$end, $date) {
$seconds_in_day = 86400;
$day_of_week = date("w", $date);
$start = $date - ($day_of_week * $seconds_in_day);
$end = $date + ((6 - $day_of_week) * $seconds_in_day);
}
Based on David Bélanger's version (unfortunatelly, my rep. won't allow me to post comment as reaction to his post..).
When input date is monday and first day of week is set as monday, original version returns previous week, not current.
Here's the little fix (with the rest of orig. function):
if(function_exists('grk_Week_Range') === FALSE){
function grk_Week_Range($DateString, $FirstDay=6){
if(empty($DateString) === TRUE){
$DateString = date('Y-m-d');
}
# fix
$dayOfWeek = date('N', strtotime($DateString));
if ($dayOfWeek == ($FirstDay +1)) { $whichWeek = 'this '; }
else { $whichWeek = 'last '; }
$Days = array(
0 => 'monday',
1 => 'tuesday',
2 => 'wednesday',
3 => 'thursday',
4 => 'friday',
5 => 'saturday',
6 => 'sunday'
);
# fix
$DT_Min = new DateTime( $whichWeek.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString);
$DT_Max = clone($DT_Min);
return array(
$DT_Min->format('Y-m-d'),
$DT_Max->modify('+6 days')->format('Y-m-d')
);
}
}
A simple code to return the days from start DateTime and end DateTime. Using gmdate() method you can format date/time.
$start_str_date = strtotime($start_date);
$end_str_date = strtotime($end_date);
$interval_days = $end_str_date - $start_str_date;
$days = gmdate('d',$interval_days);
echo $days;
I noticed that most of the answers here make use of strtotime/DateTime. While correct, personally I rather calculating dates without using English words.
Here's a simple solution that makes use of mtkime :
$now = time();
$day_of_week = (int)date('w', $now);
$week_start = mktime(0, 0, 0, date('n', $now), date('j', $now)-$day_of_week, date('Y', $now));
$week_end = mktime(23, 59, 59, date('n', $week_start), date('j', $week_start)+6, date('Y', $week_start));
function weekRange($year, $week){
$dateFrom = new \DateTime();
$dateFrom->setISODate($year, $week);
$dateTo = new \DateTime();
$dateTo->setISODate($year, $week, 7);
return array(
'week' => $dateFrom->format('Y-W'),
'start'=> $dateFrom->format('Y-m-d'),
'end' => $dateTo->format('Y-m-d')
);
}
Example:
$weekInformation = weekRange(2020, 38);
echo $weekInformation['start'];
// Display: 2020-09-14
echo $weekInformation['end'];
// Display: 2020-09-20
from PHP DateTime doc :
<?php
$date = new DateTime();
$date->setISODate(2008, 2);
$startDay = $date->format('Y-m-d');
$date->setISODate(2008, 2, 7);
$endDay = $date->format('Y-m-d');
?>

Categories