So I came up with a situation where I want to retrieve the dates that fall under a specific week number. I tried some methods but unfortunately, they did not work out.
So first I am getting the week number of the date that I have/selected/inputed.
$week_number = date('W', strtotime(23/08/2022)) //Will output 34
What I tried to do... But the dates that are being returned are random and not what I am expecting
$dates = array();
for($i = 1; $i <=7; $i++){
$dates[$i] = date('Y-m-d', strtotime($selected_date . ' -' . ($week_number) . ' days +' .
$i . ' days'));
}
What I am expecting:
[1] => 2022-08-22
[2] => 2022-08-23
[3] => 2022-08-24
[4] => 2022-08-25
[5] => 2022-08-26
[6] => 2022-08-27
[7] => 2022-08-28
I don't know if this is a duplicate question but I cannot find what I am looking for.
I just did something very similar not to long ago. I had to find the date of a day in a week in a certain year. My solution was:
function getDateForWeekDay($year, $weekNo, $dayOfWeekNo)
// return the exact date of this weekday, using ISO 8601
{
$date = new DateTime();
$date->setISODate($year, $weekNo, $dayOfWeekNo);
return $date->format('Y-m-d');
}
for instance, echo getDateForWeekDay(2020, 34, 1); will return 2020-08-17, see: https://3v4l.org/bkjUj
See the PHP manual: DateTime::setISODate()
You can easily expand this to generate your array.
for ($day = 1; $day <= 7; $day++) {
$dates[$day] = getDateForWeekDay(2020, 34, $day);
}
print_r($dates);
Which returns the wanted result. See: https://3v4l.org/iDKOu
You can use this to get monday and sunday of a week :
$day = 1; // 1 to 6, monday to saturday.
$dayDate = new \DateTime();
$dayDate->setISODate($date->format('Y'), $date->format('W'), $day);
Related
I have a php code as shown below in which on the 1st day of every month, I am copying 2nd JSON object array (next_month) content into 1st JSON object array (current_month).
In the 2nd JSON object array (next_month), I want to have next month dates. That will also happen on the 1st day of every month. Currently I am storing nada. Let us suppose that today is 1st day of November.
php code:
$value = json_decode(file_get_contents('../hyt/dates.json'));
if ((date('j') == 1)) {
$month = 11;
$year = date('Y');
$current_month_days = (date('t', strtotime($year . '-' . $month . '-01')));
$next_month_days = (date('t', strtotime($year . '-' . ($month + 1) . '-01')));
$value->current_month = $value->next_month; // Line Y
$value->next_month = array_fill(0, ($next_month_days), nada); // Line Z
}
The current look of JSON (dates.json) is shown below:
{"current_month": ["2020-10-01", "2020-10-02", "2020-10-03", "2020-10-04", "2020-10-05", "2020-10-06", "2020-10-07", "2020-10-08", "2020-10-09", "2020-10-10", "2020-10-10", "2020-10-12", "2020-10-13", "2020-10-14", "2020-10-15", "2020-10-16", "2020-10-17", "2020-10-18", "2020-10-19", "2020-10-20", "2020-10-21", "2020-10-22", "2020-10-23", "2020-10-24", "2020-10-25", "2020-10-26", "2020-10-27", "2020-10-28", "2020-10-29", "2020-10-30","2020-10-31"],
"next_month": ["2020-11-01", "2020-11-02", "2020-11-03", "2020-11-04", "2020-11-05", "2020-11-06", "2020-11-07", "2020-11-08", "2020-11-09", "2020-11-11", "2020-11-11", "2020-11-12", "2020-11-13", "2020-11-14", "2020-11-15", "2020-11-16", "2020-11-17", "2020-11-18", "2020-11-19", "2020-11-20", "2020-11-21", "2020-11-22", "2020-11-23", "2020-11-24", "2020-11-25", "2020-11-26", "2020-11-27", "2020-11-28", "2020-11-29", "2020-11-30"] }
Problem Statement:
I am wondering what changes I should make at Line Z so that in the second JSON object array, I am able to get next month dates. At present, I am storing nada.
The content which I want in the JSON on the 1st day of November month after successful execution of Line Y and Line Z is:
{"current_month": ["2020-11-01", "2020-11-02", "2020-11-03", "2020-11-04", "2020-11-05", "2020-11-06", "2020-11-07", "2020-11-08", "2020-11-09", "2020-11-11", "2020-11-11", "2020-11-12", "2020-11-13", "2020-11-14", "2020-11-15", "2020-11-16", "2020-11-17", "2020-11-18", "2020-11-19", "2020-11-20", "2020-11-21", "2020-11-22", "2020-11-23", "2020-11-24", "2020-11-25", "2020-11-26", "2020-11-27", "2020-11-28", "2020-11-29", "2020-11-30"],
"next_month": ["2020-12-01", "2020-12-02", "2020-12-03", "2020-12-04", "2020-12-05", "2020-12-06", "2020-12-07", "2020-12-08", "2020-12-09", "2020-12-11", "2020-12-11", "2020-12-12", "2020-12-13", "2020-12-14", "2020-12-15", "2020-12-16", "2020-12-17", "2020-12-18", "2020-12-19", "2020-12-20", "2020-12-21", "2020-12-22", "2020-12-23", "2020-12-24", "2020-12-25", "2020-12-26", "2020-12-27", "2020-12-28", "2020-12-29", "2020-12-30", "2020-12-31"] }
This is what I have tried:
This is what I have tried at Line Z but its storing only today's date in JSON object array.
$value->next_month = array_fill(0, ($next_month_days), date("Y-m-d")); // Line Z
I think you should completely recreate your JSON string. It starts on the first day of the current month. The loop always runs as long as the month remains. The whole thing then again for the following month.
$arr = $cur = [];
$date = date_create('first day of this month 00:00');
$startMonth = $month = $date->format('m');
while($startMonth == $month){
$cur[] = $date->format('Y-m-d');
$date->modify('+1 Day');
$month = $date->format('m');
}
$arr["current_month"] = $cur;
$startMonth = $month;
$cur = [];
while($startMonth == $month){
$cur[] = $date->format('Y-m-d');
$date->modify('+1 Day');
$month = $date->format('m');
}
$arr["next_month"] = $cur;
$jsonStr = json_encode($arr);
You are using array_fill, which is used to fill at least part of an array with the same value. I would recommend using a simple for loop:
$next_month_array = [];
$next_month = $month < 12 ? $month + 1 : 1;
$year = date('Y');
for($day_counter = 1; $day_counter <= $next_month_days; $day_counter++) {
$next_month_array[] = "$year-$next_month-$day_counter";
}
$value->next_month = $next_month_array;
I'm a newbie in both php and codeigniter.
I have a function which is used to label the x-axis of a chart of weekly sums of kilometers rode on a bicycle. It works (or is supposed to work) by counting back from today's date either zero Sundays or 1, 2, 3, etc as passed by an array.
I am using PHP Version 5.6.19, and this is my code:
In the Model:
public function week_start($date, $counter){
$tstring = strtotime($date);
$wknumber = ($counter + 1);
$start = strtotime("-$wknumber weeks sunday", $tstring);
return array(date('M d', $start));}
In the Controller:
$datenumbers = array(0, 1, 2, 3, 4, 5, 6, 7);
$dateResult = $this->bike_model->week_start(date("Y/m/d"), $datenumber);
In the view:
for ($i = 0; $i < 8; $i++){
echo "<text class = \"axis\" y = \"357\" x = \"";
echo 26 + ($i*70);
echo "\" dy = \".35em\">";
echo $dates_for_table[$i];}
I have had it up for few days and it has been showing Sunday July 3 as the first number on on my x-axis, as it should have. But today, it is Sunday and I expect it to now say Sunday July 10 as my most recent week. However, it is still showing last Sunday!
So my question is, is there a bug here or am I misunderstanding how '- one week Sunday' should work?
My goal is to have my function with zero as the argument return the most recent week start--either the current Sunday if it is Sunday or the past Sunday. I have found a workaround by adding an if else to the function checking if it is Sunday.
if ($tstring == strtotime('this Sunday')){
$wknumber = $counter;}
else{
$wknumber = ($counter + 1);}
However, this feels clunky and I'm looking for a more elegant way. I also want to understand what went wrong with "- one week Sunday" since I thought I had understood how it was working.
Thank you!
Here is how I did something similar using the object oriented DateTime style:
$startDate = new DateTime('NOW'); // can pass date string if not today
# reset start date to last Sunday or today if it is Sunday:
$startDate->sub(new DateInterval('P'.($startDate->format('w')).'D'));
# for debugging, output first Sunday:
echo $startDate->format('Y-m-d H:i:s') . " => full date and time (check for timezone issues) \n\n";
$weeks = 8;
for ($i = 0; $i < $weeks; $i++) {
# don't decrement first pass; sub 1 week on subsequent:
$startDate->sub(new DateInterval('P'. (($i) ? 1 : 0) .'W'));
echo $startDate->format('Y-m-d') . "\n";
};
You should be able to adapt for your purpose.
If you want to get fancy, you can also use DatePeriod instead of using sub within a loop:
$period = new DatePeriod(
$startDate,
DateInterval::createFromDateString('-1 week'),
7
);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}
I'm looking into trying to set up and array that will look something like this:
$dates = array(
[0] => "07/11/2013",
[1] => "14/11/2013",
[2] => "21/11/2013",
[3] => "28/11/2013",
[4] => "05/12/2013",
[5] => "12/12/2013");
I'm willing to use this, but as I want this to reoccur again next year I'd prefer to have PHP do this and enter it into an array for me. I know how to limit it to a specific amount that I want, but I don't know how to add a week onto the current date or specific date if I wanted to start 08/11/2013 for example.
I've had a quick look and I can't seem to find anything that does this.
I just need a script to add a week to the current date, at the moment this is every Thursday, and then add that to the array.
My only problem is I'm not sure how to specify a date, and then add a week every time. I assume a for loop would be best here.
Use DateTime class. DateInterval and DatePeriod classes were introduced in PHP 5.3.0, so the below solution works for only PHP >= 5.3.0:
$start = new DateTime('2013-11-07');
$end = new DateTime('2013-12-31');
$interval = new DateInterval('P1W'); // one week
$p = new DatePeriod($start, $interval, $end);
foreach ($p as $w) {
$weeks[] = $w->format('d-m-Y');
}
Demo!
As Glavic notes in the comments below, this can also be done in previous versions of PHP using the modify() method:
$start = new DateTime('2013-11-07');
$end = new DateTime('2013-12-31');
$weeks = array();
while ($start < $end) {
$weeks[] = $start->format('d-m-Y');
$start->modify('+1 week');
}
Demo.
You can use strtotime('+1 week', $unixTimestamp) for this:
<?php
$startDate = '2013-11-07';
$endDate = '2013-12-31';
$startDateUnix = strtotime($startDate);
$endDateUnix = strtotime($endDate);
$dates = array();
while ($startDateUnix < $endDateUnix) {
$dates[] = date('Y-m-d', $startDateUnix);
$startDateUnix = strtotime('+1 week', $startDateUnix);
}
print_r($dates);
?>
Outputs:
Array
(
[0] => 2013-11-07
[1] => 2013-11-14
[2] => 2013-11-21
[3] => 2013-11-28
[4] => 2013-12-05
[5] => 2013-12-12
[6] => 2013-12-19
[7] => 2013-12-26
)
DEMO
(format the date() call in any way you want to get the format you want).
strtotime does what you need
$nextWeek = strtotime('08/11/2013 + 1 week');
If you need that 8 times, loop it 8 times. You can make a function with $start and $numWeek to return an array with $numWeeks+1 values (the start added)
function createDateList($start, $numWeeks){
$dates = array($start);// add first date
// create a loop with $numWeeks illiterations:
for($i=1;$<=$numWeeks; $i++){
// Add the weeks, take the first value and add $i weeks to it
$time = strtotime($dates[0].' + '.$i.' week'); // get epoch value
$dates[] = date("d/M/Y", $time); // set to prefered date format
}
return $dates;
}
would the strtotime() function work here?
$nextweek = strtotime('thursday next week');
$date = date('d/m/Y', $nextweek);
To create a 5 element array containing today (or this thursday) and the next 4:
for ($a = 0; $a < 5; $a++)
{
$thur = date('d/m/Y', strtotime("thursday this week + $a weeks"));
$dates[] = $thur;
}
I'm working with an shopping site which delivers consignments through UK mail with an expected delivery time of 7 days.
So I have set the expected delivery date as:
// gives me the date 7 days into the future
$expectedDate=Date('Y:m:d', strtotime("+7 days"));
Everything was working fine until the UK mail API to which I passed the date returned the following error:
[Errors] => stdClass Object
(
[UKMWebError] => stdClass Object
(
[Code] => 8200
[Description] => Validation failed. 05/06/2012 is not a working day.
)
)
For example, 05/06/2012 was a Tuesday, but I didn't know it was a holiday. Because it was a holiday, it was rejected.
What I would like to do:
determine an expected delivery date within a range of 5-7 days
which skips weekends
and if I have list of holidays in an array then to skip those dates or give me date within the range of 5-7 days
one thing more I would like to add for example for now the holidays array that need to be skipped only contains this value can you update your answer "05/06/2012"
Is it possible? Can someone show a working example ??
$holidays = array('05/06/12');
$deliverable_days = 1;
$any_day = 1;
while($deliverable_days<=7)
{
$ts= strtotime("+{$any_day} days");
$this_date = date('d/m/Y',$ts);
$this_day = date('w',$ts);
if(!in_array($this_date,$holidays) && !in_array($this_day,array(0,6)))
{
$deliverable_days++;
}
if($deliverable_days==7)
{
break;
}
$any_day++;
}
Below Code will give you delivery date beetween 5-7 days excluding weekends
$working_day = date('N');
if($working_day < 5)
{
$delivery_date = date('Y/m/d', strtotime("+7 days"));
}
else
{
if($working_day == 6)
$delivery_date = date('Y/m/d', strtotime("+6 days"));
if($working_day == 7)
$delivery_date = date('Y/m/d', strtotime("+5 days"));
}
This won't solve your problem, but you can use it for checking a future date for weekend, holidays, or working day:
// M/d/Y
$holidays = array(
'05/06/2012',
'10/07/2012',
);
$expectedDate = strtotime("+7 days");
if (in_array(date('l', $expectedDate), array('Saturday', 'Sunday'))) {
echo 'weekend';
} else if (in_array(date('m/d/Y', $expectedDate), $holidays)) {
echo 'holiday';
} else {
echo date('Y:m:d', $expectedDate) . ' is working day!';
}
Update:
Pinaldesai's answer is very good. It can be simplified like this:
$offset = date('N') < 5 ? 7 : (5 + (7 - date('N')));
$delivery_date = date('Y/m/d', "+$offset days"));
I need to find a way to get the date of the monday of a week based on another day. So for example, if wednesday is 2011-05-11, i need to somehow tell it that monday of that week was 2011-05-09. Can anyone help?
$res looks like this:
stdClass Object
(
[link_count] => 1
[day] => 2011-05-12
[weekday] => Thu
)
$days = array(1=> 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
foreach($res as $r) {
$day = date('N', strtotime($r->day));
$r->weekday = $days[$day];
if($r->weekday == 'Mon') {
$r->weekstarting = $r->day;
} else {
// here's the problem right here, I need to find a way to tell it
// what it's starting day is
$r->weekstarting = ;
}
}
Seems like you have the weekday (like 'Thu'), so you need to get is position in your $days array.
You can get the key with $key=array_search($r->weekday, $days); (returns 4).
Now you know the difference from Monday, so you just have to create the date:
$tempArray=explode('-', $r->day);
$tempArray[2]-=$key-1;
$r->weekstarting = implode('-', $tempArray);
EDIT: Now I see that you already had the array index in $day. So you could use that value instead of the $key I had.
EDIT 2: If you don't want to lose the leading zeros in the day, you could use sprintf() on it .
$tempArray=explode('-', $r->day);
$tempArray[2]=sprintf('%02d', $tempArray[2]-($key-1));
$r->weekstarting = implode('-', $tempArray);
And finally the LAST UPDATE. I was thinking about deleting the whole post and rewriting it again, but I will leave it here for reference... somebody might learn from my mistake.
So the final code that will correctly adjust months also:
list($y, $m, $d)=explode('-', $r->day);
$timestamp=mktime(0,0,0,$m,$d-($day-1),$y);
$r->weekstarting = date('Y-m-d', $timestamp);
Actually this is what I wanted to avoid, converting to a timestamp, but I could not. The trick I'm using here is that mktime() will handle negative numbers for days and calculate the timestamp correctly.
This seems to work fine:
<?php
$dt = new DateTime("11 May 2011");
$dt->modify("last monday");
edit: I remember seeing reports that some people had problems with the "last" modifier (windows users maybe) so this should work if you have problems with that:
<?php
$dt = new DateTime("12 May 2011");
$days = (int)$dt->format('N') - 1;
$dt->modify("-{$days} days");
Please create a testfile and execute it:
<?php
$dates = array(
'11 May 2011',
'2011-04-26',
'2011-05-04',
);
foreach($dates as $date) {
$dt = new DateTime($date);
$dt->modify("last monday");
printf("For %s last monday is %s.\n", $date, $dt->format('Y-m-d'));
}
?>
it should output the following:
For 11 May 2011 last monday is 2011-05-09.
For 2011-04-26 last monday is 2011-04-25.
For 2011-05-04 last monday is 2011-05-02.
In case not, please add your output to your question above.
I'd do something like this:
$dow = date('N', strtotime($r->day)) - 1; // 0 will be Monday, 1 Tuesday, etc.
$start = mktime() - ($dow * 86400); // 86400 is one day in seconds
$startday = date('r', $start);