Determine If Business Is Open/Closed Based On Business Hours - php

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.

Related

Specify if date is a weekend and/or a holiday PHP

I need to write a program that generates a random date
$start = strtotime('2010-01-01');
$end = strtotime('2018-01-01');
$random_date = date('n F Y l ', rand($start, $end));
then I need to translate the names of months and days into russian
$lat = array ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'January', 'February', 'March', 'April', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
$rus = array ('Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Января', 'Февраля', 'Марта', 'Апреля', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
return str_replace($lat,$rus, $random_date) ;
$holidays = array('8 января','7 января','14 января', '23 февраля','8 марта','1 апреля','12 апреля','1 мая','9 мая','12 июня','22 июня','1 сентября','27 сентября','4 ноября','12 декабря','31 декабря','1 января');//dates of rus holidays
Then I need to display the date in this format:
2 Февраля 2014 Пятница (2 February 2014 Friday).
Here's what I am having trouble with:
The end result must look like this: 2 February 2014 Friday holiday and/or weekend.
So, I need to specify whether the displayed date is a weekend or/ and a holiday. Could someone help?
You put the date in $date, then we set $weekend to false until we check it, then we check the date and if it is a weekend set $weekend to true. then if the date is a weekend I print it is a weekend and if it is not i print it is not a weekend, but you can do anything you like with it...
date = '2018-03-16';
$weekend = false;
$day = date("D", strtotime($date));
if($day == 'Sat' || $day == 'Sun'){
$weekend = true;
}
if($weekend){
echo $date . ' It is a weekend';
} else{
echo $date . ' It is not a weekend';
}
and as function(didnt test this one yet):
function isitweekend($date){
$date = '2018-03-16';
$weekend = false;
$day = date("D", strtotime($date));
if($day == 'Sat' || $day == 'Sun'){
$weekend = true;
}
}
For start, lets make a function that will return random date:
function randomDate($start_date, $end_date)
{
$min = new DateTime($start_date . ' 00:00:00 UTC');
$max = new DateTime($end_date . ' 23:59:59 UTC');
return new DateTime('#' . rand($min->getTimestamp(), $max->getTimestamp()));
}
Then just created while loop which checks for weekends and holidays:
// Fill this array with your holidays
$holidays = ['*-12-25', '*-01-01', '*-01-07', '*-05-01'];
while (true) {
// Get random date
$randomDate = randomDate('2010-01-01', '2018-01-01');
// Get random date again, since this one is on weekend.
if ($randomDate->format('N') >= 6) continue;
// Get random date again, since this one is on holiday.
if (in_array($randomDate->format('*-m-d'), $holidays)) continue;
// Exit the loop, since random date is ok!
break;
}
// Random date
echo $randomDate->format('Y-m-d');
And then just transform day and month names to your language.
demo
If you mean to check for International Holidays here is a function I wrote for it.
function checkHoliday($date){
if(date('l', strtotime($date)) == 'Saturday'){
return "Saturday";
}else if(date('l', strtotime($date)) == 'Sunday'){
return "Sunday";
}else{
$receivedDate = date('d M', strtotime($date));
$holiday = array(
'01 Jan' => 'New Year Day',
'18 Jan' => 'Martin Luther King Day',
'22 Feb' => 'Washington\'s Birthday',
'05 Jul' => 'Independence Day',
'11 Nov' => 'Veterans Day',
'24 Dec' => 'Christmas Eve',
'25 Dec' => 'Christmas Day',
'31 Dec' => 'New Year Eve'
);
foreach($holiday as $key => $value){
if($receivedDate == $key){
return $value;
}
}
}
}
And call it this way
$date = '01/01/2021';
echo checkHoliday($date);
Yes, you will have to manually add the holidays to the array above.

Compare 2 time which is greater without date in PHP

I am trying to get the result that which time is greater. I mean there is no date only time.
$open_time = date("g:i A", strtotime($restaurant['open_time']));
$close_time = date("g:i A", strtotime($restaurant['close_time']));
$curren_time = date("h:i");
$restaurant['open_time'] and $restaurant['close_time'] is the result from database. It is coming in 24 hour format like 22:30, 10:20.
What i want exactly.
if(($current_time > $open_time) && ($current_time < $close_time)
{
echo "Opened";
}
else
{
echo "Closed";
}
If current_time is 2:00 AM and open_time is 11:00 AM then the result should echo Closed. And like this if current_time is 1:00 PM and closed_time is 11:00 PM then the result should echo Opened. Hope i explained well. Please ask if you have any doubt in my question.
You can solve thus using 24 hour format time also. But remember you can add date but virtually not from database. You can use to get the greater time
Set correct timezone and should work.
$restaurant = [
'open_time' => '11:00',
'close_time' => '22:00'
];
$timeZone = new DateTimeZone('Europe/Warsaw');
$now = new DateTime('now', $timeZone);
$open = DateTime::createFromFormat('H:i', $restaurant['open_time'], $timeZone);
$close = DateTime::createFromFormat('H:i', $restaurant['close_time'], $timeZone);
$working_now = ($now > $open && $now < $close);
if ($working_now) {
echo 'open';
} else {
echo 'closed';
}
You can play with it in sandbox - uncomment the test line to change current time.
If it's open through midnight you might need additional logic there:
if ($open > $close) {
if ($now > $close) {
$close->modify('+1 day');
} else {
$open->modify('-1 day');
}
}
$working_now = ...

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

Display Open/Closed based on day and time and location

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.

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