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.
Related
I want to get the start date and end date of a week .
I am using
$monday = date('Y-m-d', strtotime('this monday', strtotime($model->date)));
$saturday = date('Y-m-d', strtotime('this saturday', strtotime($model->date)));
when date is 18-09-2017 then monday is 18-09-2017 and saturaday is 23-09-2017.
However, when date is 23-09-2017 then monday is 25-09-2017 and saturday is 23-09-2017.
Why is it so?
How can I adjust the code to give always moday as 18-09-2017 and saturday 23-09-2017 when the date is 18-09-2017 or 23-09-2017.
I want uniformity.
Try this date-time formatting function , convert it in ISO and get current week days
<?php
$dt = "23-09-2017";
function getDay($day,$date)
{
$days = ['Monday' => 1, 'Tuesday' => 2, 'Wednesday' => 3, 'Thursday' => 4, 'Friday' => 5, 'Saturday' => 6, 'Sunday' => 7];
$date = new \DateTime($date);
$date->setISODate((int)$date->format('o'), (int)$date->format('W'), $days[ucfirst($day)]);
return $date;
}
echo "Monday: ".getDay('Monday',$dt)->format("d-m-Y");
echo "Saturday: ".getDay('Saturday',$dt)->format("d-m-Y");
DEMO
My code is
$dayofweek = date('w', strtotime($model->date));
if($dayofweek == 6)
{
$monday = date('Y-m-d', strtotime('last monday', strtotime($model->date)));
}
else
{
$monday = date('Y-m-d', strtotime('this monday', strtotime($model->date)));
}
$saturday = date('Y-m-d', strtotime('this saturday', strtotime($model->date)));
I'd like to calculate next billing date of Recurly plan in PHP.
There are 2 types of billing cycle: yearly | monthly.
I tried to use DateTime and DateInterval classes, but didn't get expected results.
<?php
$referenceTime = new \DateTime('2016-01-31');
$oneMonthLater = $referenceTime->modify('+1 month');
var_dump($oneMonthLater);
// public 'date' => string '2016-03-02 00:00:00.000000'
Adding one month to the 31st of Januray gives me the second of March and not the 29th (or 28th) of February as I would expect.
The same for the 31st of August:
<?php
$referenceTime = new \DateTime('2016-08-31');
$oneMonthLater = $referenceTime->modify('+1 month');
var_dump($oneMonthLater);
// public 'date' => string '2016-10-01 00:00:00.000000'
If yearly, I expect Feb 29, 2016 + 1 year => Feb 28, 2017
Thanks.
Try this, if date > 28 use last day of next month else use +1 month
$get_date = strtotime("31-01-2016");
$dt = explode("-",$get_date);
$dt = $dt[0];
var_dump(($dt > 28) ? date("d-m-Y", strtotime("31-01-2016 last day of next month")) : date("d-m-Y", strtotime("31-01-2016 +1 month")));
DEMO
You can call modify with PHP's DateTime object to calculate the next date relative to the current date. The following code shows how you would do it with your specific situation.
$next_bill_date = new DateTime();
switch($plan_interval_unit) {
case "year":
$next_bill_date->modify("last day of next month");
break;
case "month":
$next_bill_date->modify("last day of this month next year");
break;
}
May be something like that:
if (date('d') !== date('d', strtotime('+1 month'))
date ('Y-m-d H:i:s', strtotime('last day of next month'));
if (date('d') !== date('d', strtotime('+1 year'))
date ('Y-m-d H:i:s', strtotime('last day of this month next year'));
You can use PHP inbuilt strtotime() function
// One month from today
$date = date('Y-m-d', strtotime('+1 month'));
// One month from a specific date
$date = date('Y-m-d', strtotime('+1 month', strtotime('2016-12-06')));
function get_next_billing_date($now, $type, $format = 'Y-m-d')
{
$date = new DateTime($now);
$y = $date->format("Y");
$m = $date->format("m");
$d = $date->format("d");
if ($type == 'year') {
$y++;
if ($m == 2 && $d == 29) {
$d = 28;
}
} else if ($type == 'month') {
if ($m == 12) {
$y++;
$m = 1;
} else {
$m++;
}
$first_date = sprintf("%04d-%02d-01", $y, $m);
$last_day_of_next_month = date('t', strtotime($first_date));
if ($d > $last_day_of_next_month) {
$d = $last_day_of_next_month;
}
} else {
// not supported
return false;
}
$date->setDate($y, $m, $d);
return $date->format($format);
}
This question already has answers here:
PHP: How to get Sunday and Saturday given a date input?
(10 answers)
Closed 9 years ago.
I need a way to get the date range of a previous Sunday to Saturday for the current date.
Example, if today is 8/15 I would want 8/4 - 8/10.
1. Current date is 8/10. Code if date range must be 8/4 - 8/10 :
$to = new DateTime('2013-08-10');
$to->modify('-' . (($w = $to->format('w')) != 6 ? $w + 1 : 0) . ' day');
$from = clone $to;
$from->modify('-6 day');
echo $from->format('m/d') . "-" . $to->format('m/d'); # 08/04-08/10
2. Current date is 8/10. Code if date range must be 7/28-8/03 :
$to = new DateTime('2013-08-10');
$to->modify('last Saturday');
$from = clone $to;
$from->modify('-6 day');
echo $from->format('m/d') . "-" . $to->format('m/d'); # 07/28-08/03
Personally I would do something like this:-
$end = (new \DateTime())->modify('last saturday');
$start = (new \DateTime())->setTimestamp($end->getTimestamp())->modify('- 6 days');
$interval = new \DateInterval('P1D');
$period = new \DatePeriod($start, $interval, $end->add($interval));
foreach($period as $day)
{
$result[] = $day->format('d-m-Y');
}
var_dump($result);
Output:-
array (size=7)
0 => string '04-08-2013' (length=10)
1 => string '05-08-2013' (length=10)
2 => string '06-08-2013' (length=10)
3 => string '07-08-2013' (length=10)
4 => string '08-08-2013' (length=10)
5 => string '09-08-2013' (length=10)
6 => string '10-08-2013' (length=10)
The DateTime classes are extremely useful.
function getPreviousSundayAndSatruday($today = NULL)
{
$today = is_null($today) ? time() : $today;
// If today is Sunday, then find last week
if(date("w", $today) == 0){
$saturdayTimeStamp = strtotime("last Saturday");
$sundayTimeStamp = strtotime("last Sunday");
}
// If it is Saturday, check from last Sunday until today
else if(date("w", $today) == 6){
$saturdayTimeStamp = strtotime("this Saturday");
$sundayTimeStamp = strtotime("last Sunday");
}
// Else it's a day of the week, so last Saturday to two Sundays before.
else{
$saturdayTimeStamp = strtotime("last Saturday");
$sundayTimeStamp = strtotime("last Sunday - 1 week");
}
return array(
'saturday' => $saturdayTimeStamp,
'sunday' => $sundayTimeStamp
);
}
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.
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');
?>