Display Open/Closed based on day and time and location - php

I have ran through a few test examples I have found and tried to combined some answer but have been unsuccessful.
This is what I have so far & I will actually need to add another one for a second locations hours.
<?php
date_default_timezone_set('America/New_York');
$date = new DateTime;
echo date("D m/d/y h:i:s",time())
?>
<?php
$times = array(
'mon' => '7:30 AM - 12:00 PM, 12:30 PM - 4:30 PM',
'tue' => '7:30 AM - 12:00 PM, 12:30 PM - 6:30 PM',
'wed' => '7:30 AM - 12:00 PM, 3:30 PM - 4:30 PM',
'thu' => '7:30 AM - 12:00 PM, 12:30 PM - 6:30 PM',
'fri' => '7:30 AM - 4:30 PM',
'sat' => '7:30 AM - 12:00 PM',
'sun' => 'closed'
);
function compileHours($times, $timestamp) {
$times = $times[strtolower(date('D',$timestamp))];
if(!strpos($times, '-')) return array();
$hours = explode(",", $times);
$hours = array_map('explode', array_pad(array(),count($hours),'-'), $hours);
$hours = array_map('array_map', array_pad(array(),count($hours),'strtotime'), $hours, array_pad(array(),count($hours),array_pad(array(),2,$timestamp)));
end($hours);
if ($hours[key($hours)][0] > $hours[key($hours)][1]) $hours[key($hours)][1] = strtotime('+1 day', $hours[key($hours)][1]);
return $hours;
}
function isOpen($now, $times) {
$open = 0; // time until closing in seconds or 0 if closed
// merge opening hours of today and the day before
$hours = array_merge(compileHours($times, strtotime('yesterday',$now)),compileHours($times, $now));
foreach ($hours as $h) {
if ($now >= $h[0] and $now < $h[1]) {
$open = $h[1] - $now;
return $open;
}
}
return $open;
}
$now = strtotime('12:00am');
$open = isOpen($now, $times);
if ($open == 0) {
echo "Closed";
} else {
echo "Open";
}
?>
Here is the link to the test page I am mess with http://www.sullivanscrap.com/testtime.php Any suggestions would be greatly appreciated.

I believe your problem is that you are setting $now to midnight of today's morning, then checking that against your hour ranges. This will always return closed because none of your hour ranges contain that time. Changing this to $now = time() seems to yield the expected results.

Related

how can I create a list of times in php?

I have x.
x is minutes.
I have a string start_time like: 7:00
And I have a string end_time like: 14:00
how can print a list of time with increase x minutes for each loop?
I want print something like this:
if x = 30
7:00 - 7:30
7:30 - 8:00
...
13:30 - 14:00
I try do it with math functions in php like this:
$time = '7:00';
$mm = $hh = 0;
$str = explode(":",$time);
if(($str[1]+ $x) > 60)
{
...
}
but it there a more simple method? can date function in php do it?
You can use DatePeriod together with DateInterval to achieve this.
Create two DateTime intervals with your start and end times, and a DateInterval instance with the number of minutes you need. Then, create a DatePeriod with this information, and iterate over it to show the resulting times:
<?php
$minutes = 15;
$start = "07:00";
$end = "14:00";
$startDate = DateTime::createFromFormat("H:i", $start);
$endDate = DateTime::createFromFormat("H:i", $end);
$interval = new DateInterval("PT".$minutes."M");
$dateRange = new DatePeriod($startDate, $interval, $endDate);
foreach ($dateRange as $date) {
echo $date->format("H:i")."<br>";
}
Demo
Result
07:00
07:15
07:30
07:45
08:00
08:15
08:30
08:45
09:00
09:15
09:30
09:45
10:00
10:15
// etc
You can use the DatePeriod object along with a desired DateInterval object.
Example: https://3v4l.org/lg8QW
$start = new \DateTime('07:00');
$end = new \DateTime('14:00');
$interval = new \DateInterval('PT1M'); //change to desired interval
$periods = new \DatePeriod($start, $interval, $end);
foreach ($periods as $period) {
echo $period->format('H:i') ;
}
Result:
07:00
07:01
07:02
07:03
07:04
07:05
07:06
07:07
07:08
07:09
07:10
07:11
07:12
07:13
07:14
07:15
07:16
07:17
07:18
07:19
07:20
//...
13:59
You can use DateTime object.
just like this:
<?php
$start_time = '7:00';
$date1 = DateTime::createFromFormat('H:i', $start_time);
$old = $start_time;
while (true) {
$date1->modify('+30 min');
echo $old . '-' . $date1->format('H:i').PHP_EOL;
$old = $date1->format('H:i');
if ($old == '14:00') {
break;
}
}
Output:
7:00-07:30
07:30-08:00
08:00-08:30
...
13:30-14:00
More info just see the manual here: DateTime

Determine If Business Is Open/Closed Based On Business Hours

My code works fine if the times are AM to PM (Ex: 11 AM - 10 PM), but if the locations hours of operation are AM to AM (Ex: 9 AM - 1 AM) it breaks. Here is my code:
$datedivide = explode(" - ", $day['hours']); //$day['hours'] Example 11:00 AM - 10:00 PM
$from = ''.$day['days'].' '.$datedivide[0].'';
$to = ''.$day['days'].' '.$datedivide[1].'';
$date = date('l g:i A');
$date = is_int($date) ? $date : strtotime($date);
$from = is_int($from) ? $from : strtotime($from);
$to = is_int($to) ? $to : strtotime($to);
if (($date > $from) && ($date < $to) && ($dateh != 'Closed')) {
?>
<script type="text/javascript">
$(document).ready(function(){
$('.entry-title-container').append('<div class="column two"><h2 style="color:green;text-align: left;margin: 0;">OPEN<br /><span style="color:#222;font-size:12px;display: block;">Closes at <?php echo $datedivide[1]; ?></span></h2></div><br clear="all" />');
});
</script>
<?php
}
You would first need to create an array which will hold your days of the week, and their respective close/open time range(s).
/**
* I setup the hours for each day if they carry-over)
* everyday is open from 09:00 AM - 12:00 AM
* Sun/Sat open extra from 12:00 AM - 01:00 AM
*/
$storeSchedule = [
'Sun' => ['12:00 AM' => '01:00 AM', '09:00 AM' => '12:00 AM'],
'Mon' => ['09:00 AM' => '12:00 AM'],
'Tue' => ['09:00 AM' => '12:00 AM'],
'Wed' => ['09:00 AM' => '12:00 AM'],
'Thu' => ['09:00 AM' => '12:00 AM'],
'Fri' => ['09:00 AM' => '12:00 AM'],
'Sat' => ['12:00 AM' => '01:00 AM', '09:00 AM' => '12:00 AM']
];
You then loop over the current day's time range(s) and check to see if the current time or supplied timestamp is within a range. You do this by using the DateTime class to generate a DateTime object for each time range's start/end time.
The below will do this and allow you to specify a timestamp in case you are wanting to check a supplied timestamp instead of the current time.
// current or user supplied UNIX timestamp
$timestamp = time();
// default status
$status = 'closed';
// get current time object
$currentTime = (new DateTime())->setTimestamp($timestamp);
// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {
// create time objects from start/end times
$startTime = DateTime::createFromFormat('h:i A', $startTime);
$endTime = DateTime::createFromFormat('h:i A', $endTime);
// check if current time is within a range
if (($startTime < $currentTime) && ($currentTime < $endTime)) {
$status = 'open';
break;
}
}
echo "We are currently: $status";
See DEMO of above
Modified from the accepted answer for use on a AWS Debian Server (located on the west coast) where our store hours are actually EST... also dropped into a PHP function.
/*
* decide based upon current EST if the store is open
*
* #return bool
*/
function storeIsOpen() {
$status = FALSE;
$storeSchedule = [
'Mon' => ['08:00 AM' => '05:00 PM'],
'Tue' => ['08:00 AM' => '05:00 PM'],
'Wed' => ['08:00 AM' => '05:00 PM'],
'Thu' => ['08:00 AM' => '05:00 PM'],
'Fri' => ['08:00 AM' => '05:00 PM']
];
//get current East Coast US time
$timeObject = new DateTime('America/New_York');
$timestamp = $timeObject->getTimeStamp();
$currentTime = $timeObject->setTimestamp($timestamp)->format('H:i A');
// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {
// create time objects from start/end times and format as string (24hr AM/PM)
$startTime = DateTime::createFromFormat('h:i A', $startTime)->format('H:i A');
$endTime = DateTime::createFromFormat('h:i A', $endTime)->format('H:i A');
// check if current time is within the range
if (($startTime < $currentTime) && ($currentTime < $endTime)) {
$status = TRUE;
break;
}
}
return $status;
}
You should regroup all opening hours in a array since the openings hours of yesterday could be of influence if you stay opened after midnight. Also having the possibility to have several opening hours per day might be handy.
<?php
$times = array(
'mon' => '9:00 AM - 12:00 AM',
'tue' => '9:00 AM - 12:00 AM',
'wed' => '9:00 AM - 12:00 AM',
'thu' => '9:00 AM - 12:00 AM',
'fri' => '9:00 AM - 1:00 AM',
'sat' => '9:00 AM - 1:00 PM, 2:00 PM - 1:00 AM',
'sun' => 'closed'
);
function compileHours($times, $timestamp) {
$times = $times[strtolower(date('D',$timestamp))];
if(!strpos($times, '-')) return array();
$hours = explode(",", $times);
$hours = array_map('explode', array_pad(array(),count($hours),'-'), $hours);
$hours = array_map('array_map', array_pad(array(),count($hours),'strtotime'), $hours, array_pad(array(),count($hours),array_pad(array(),2,$timestamp)));
end($hours);
if ($hours[key($hours)][0] > $hours[key($hours)][1]) $hours[key($hours)][1] = strtotime('+1 day', $hours[key($hours)][1]);
return $hours;
}
function isOpen($now, $times) {
$open = 0; // time until closing in seconds or 0 if closed
// merge opening hours of today and the day before
$hours = array_merge(compileHours($times, strtotime('yesterday',$now)),compileHours($times, $now));
foreach ($hours as $h) {
if ($now >= $h[0] and $now < $h[1]) {
$open = $h[1] - $now;
return $open;
}
}
return $open;
}
$now = strtotime('7:59pm');
$open = isOpen($now, $times);
if ($open == 0) {
echo "Is closed";
} else {
echo "Is open. Will close in ".ceil($open/60)." minutes";
}
?>
On the other hand if you only want to resolve the problem with time like 9am - 5am you should check if $from > $to and add 1 day to $to if necessary.
A bit late but I have a solution for others, if the one's here don't quite fit their needs. I do like the solution of having multiple time sets for days that close after midnight but then this would add extra data handling to display the hours. You would first have to check if there are multiple time sets available then confirm that they are connected (no time in between).
My solution was instead to write a function that you pass the opening time, closing time, and time-in-question and it will return true for open and false for closed:
function is_open($open, $close, $query_time){
$open = new DateTime($open);
$close = new DateTime($close);
$query_time = new DateTime($query_time);
$is_open = false;
//Determine if open time is before close time in a 24 hour period
if($open < $close){
//If so, if the query time is between open and closed, it is open
if($query_time > $open){
if($query_time < $close){
$is_open = true;
}
}
}
elseif($open > $close){
$is_open = true;
//If not, if the query time is between close and open, it is closed
if($query_time < $open){
if($query_time > $close){
$is_open = false;
}
}
}
return $is_open;
}
Maybe this? I found it here and tweaked it a bit.
<?php
date_default_timezone_set('Europe/Stockholm'); // timezone
$today = date(N); // today ex. 6
//Opening hours
$opening_hours[1] = "12:00"; $closing_hours[1] = "00:00";
$opening_hours[2] = "12:00"; $closing_hours[2] = "00:00";
$opening_hours[3] = "12:00"; $closing_hours[3] = "00:00";
$opening_hours[4] = "12:00"; $closing_hours[4] = "02:00";
$opening_hours[5] = "12:00"; $closing_hours[5] = "04:00";
$opening_hours[6] = "13:00"; $closing_hours[6] = "04:00";
$opening_hours[7] = "13:00"; $closing_hours[7] = "00:00";
// correction for opening hours after midnight.
if(intval($closing_hours[$today - 1]) > 0)
$today = date(N,strtotime("-".intval($closing_hours[$today - 1])." hours"));
// now check if the current time is after openingstime AND smaller than closing hours of tomorrow
if (
(date("H:i") > $opening_hours[$today] &&
((date("Y-m-d H:i") < date("Y-m-d H:i", strtotime('tomorrow +'.intval($closing_hours[$today]).' hours'))))
) ||
date("H:i") < $closing_hours[$today] &&
((date("Y-m-d H:i") < date("Y-m-d H:i", strtotime('today +'.intval($opening_hours[$today]).' hours'))))
) {
$label = "label-success";
$label_text = "OPEN";
$label_time = $closing_hours[$today];
} else {
$label = "label-danger";
$label_text = "GESLOTEN";
$label_time = $opening_hours[$today];
}
?>
I tried this code for a day several different ways and found this to be a solution for me. Posting it in case it might help others. It is important to convert the time from AM/PM format back to UNIX time.
I use times pulled from a database so you would have to define $startTime and $endTime.
// define each days time like so
$monsta = "07:00 AM";
$monend = "05:00 PM";
$storeSchedule = [
'Mon' => ["$monsta" => "$monend"],
'Tue' => ["$tuessta" => "$tuesend"],
'Wed' => ["$wedssta" => "$wedsend"],
'Thu' => ["$thurssta" => "$thursend"],
'Fri' => ["$frista" => "$friend"],
'Sat' => ["$satsta" => "$satend"],
'Sun' => ["$sunsta" => "$sunend"]
];
// default time zone
$timestamp = time() - 18000;
// default status
$status = 'Closed';
// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {
// create time objects from start/end times
$startTime = strtotime($startTime);
$endTime = strtotime($endTime);
// check if current time is within a range
if ($startTime <= $timestamp && $timestamp <= $endTime ) {
$status = 'Open';
}
}
echo '<p><b>Today\'s Hours</b><br />'.$days[$d].'<br />';
echo "<b>We are currently: $status </b></p>";
Here is my version since the 12hr time format does not work for me.
Note that $pancits[] came from my database
$status = 'Closed';
// get current time object
$timestamp = time();
// $currentTime = (new DateTime())->setTimestamp($timestamp);
$currentTime = date('H:i');
$startTime = date('H:i', strtotime($pancits['p_oTime']));
$endTime = date('H:i', strtotime($pancits['p_cTime']));
if (($startTime <= $currentTime) && ($currentTime <= $endTime)) {
$status = 'Open';
//echo $status;
}
echo "<b>Currently $status</b>";
echo '
<p><b>Time Open: </b>'.date('h:ia', strtotime($pancits['p_oTime'])).'</p>
<p><b>Time Close: </b>'.date('h:ia', strtotime($pancits['p_cTime'])).'</p>
';
I would suggest making use of PHP's DateTime class. It was developed to solve all these problems by giving a simple interface for hard to accomplish tasks like this.

Calculate time period list between 2 time in php?

I want to generate 3 time-period-list column between two times.
if
$start_time = '08:00 AM';
$end_time = '10:00: PM';
Time Period List As:
Morning ----- Noon ----- Eve
8:00 AM 1:00 PM 6:00 PM
8:30 AM 1:30 PM 6:30 PM
9:00 AM 2:.0 PM 7:00 PM
to to to
... ... ...
12:00 PM 5:00 PM 10:00 PM
I have calculated times between $start_time and $end_time as:
$time = time();
$rounded_time = $time % 900 > 450 ? $time += (900 - $time % 900): $time -= $time % 900;
$start = strtotime('08:00 AM');
$end = strtotime('10:00 PM');
for( $i = $start; $i <= $end; $i += 1800)
{
echo "<input name='start_time' type='radio' value='".date('g:i A', $i)."' />"." ".date('g:i A', $i)."<br>";
}
Remaining work to divide these times in three column as mention above
Thanks in advance to all my mates.
You can use strtotime method to add and substract time period from given time. For example:
$time = strtotime('10:00');
$halfAnHourBefore = date("H:i", strtotime('-30 minutes', $time));
$halfAnHourAfter = date("H:i", strtotime('+30 minutes', $time));
would give $halfAnHourBefore as 09:30 and $halfAnHourAfter as 10:30

Time of day script

I have a small script that depending on the time and day; I would like it to output different things:
<?php
$currenttime = ((date("H")+7). ":" .date("i"));
if ($currenttime >= "16:30") {
$tomorrow = mktime(0, 0, 0, date("m") , date("d")+2, date("Y"));
$jsdate = (date("Y"). "-" .date("m"). "-" .(date("d")+1). "-16-30");
}
else{
$tomorrow = mktime(0, 0, 0, date("m") , date("d")+1, date("Y"));
$jsdate = (date("Y"). "-" .date("m"). "-" .date("d"). "-16-30");
}
echo " Time left for delivery on <b><center>" .date("l \\t\h\e jS F", $tomorrow). "</b>:</center>";
?>
<center>
<script>
// deadline(date, width, height, style, background, number color, small text color);
deadline("<? echo $jsdate; ?>", "220", "37", "digital2", "#FFFFFF", "#000099", "#000000");
</script>
</center>
For instance on a Monday before 16:30 it would need the following:
Time left for delivery on Tuesday the {date} of {month}
Then display how long left until 16:30 in DD HH MM SS format(Preferable to be servertime rather than users local time.)
Then after 16:30 on a Monday it would need to read:
Time left for delivery on Wednesday the {date} of {month}
Then display how long left until
16:30 in DD HH MM SS
format(Preferable to be servertime
rather than users local time.)
Then from 16:30 on Thursday until Monday 16:30 it would need to read:
Time left for delivery on Tuesday the {date} of {month}
Then display how long left until
16:30 in DD HH MM SS
format(Preferable to be servertime
rather than users local time.)
I hope this all make sense and thanks for looking.
Ta,
B.
You can use strtotime and the (php 5.3+) class DateTime to create, compare and format the timestamps and intervals.
e.g. (neither really tested nor exactly in the format you've described):
<?php
$now = new DateTime();
$deliveries = array(
'monday' => strtotime('monday 16:30'),
'tuesday' => strtotime('tuesday 16:30')
);
// timestamps in the past are "advanced" one week
foreach($deliveries as &$dt) {
if ( $dt < $now->getTimestamp() ) {
$dt = strtotime('+1 week', $dt);
}
}
// get the diff between 'Now' and the next delivery (smallest timestamp in $deliveries)
$nextDelivery = new DateTime();
$nextDelivery->setTimestamp( min($deliveries) );
$remaining = $nextDelivery->diff($now);
echo $nextDelivery->format(DateTime::RFC2822), " | ", $remaining->format('%d days %H:%i:%S'), "\n";
edit: without using DateTime:
<?php
$now = time();
$deliveries = array(
'monday' => strtotime('monday 16:30', $now),
'tuesday' => strtotime('tuesday 16:30', $now)
);
// timestamps in the past are "advanced" one week
foreach($deliveries as &$dt) {
if ( $dt < $now) {
$dt = strtotime('+1 week', $dt);
}
}
// get the diff between 'Now' and the next delivery (smallest timestamp in $deliveries)
$nextDelivery = min($deliveries);
// (when) a day has exactly 86400 seconds, an hour 3600 seconds, ...
$remaining = array(
'days'=> intval(($nextDelivery - $now) / 86400),
'hours'=> intval( ($nextDelivery - $now) / 3600) % 24,
'minutes'=> intval( ($nextDelivery - $now) / 60) % 60,
'seconds'=> ($nextDelivery - $now) % 60
);
echo 'next: ', date(DateTime::RFC2822, $nextDelivery), "\n";
printf('remaining: %d days %02d:%02d:%02d',
$remaining['days'], $remaining['hours'], $remaining['minutes'], $remaining['seconds']);
No fix for your program, but this line
$jsdate = (date("Y"). "-" .date("m"). "-" .date("d"). "-16-30");
could just as easy be
$jsdate = date("Y-m-d-16-30");
It's a lot more readable.

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