PHP Get recurring week from specific start date - php

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;
}

Related

Get the dates that fall under that week number

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);

Query between two dates exclude weekends and holidays in php

Working on a small app which excludes weekends and public holidays from two set dates range. ie if user enters 2019-05-01 and 2019-05-10 it returns the range without the weekends and if there are any public holidays exclude those from results.
i get the date range with the time per day, working hours from two variables
$duration = $endTime - $startTime;
How can i use in_array to
results returned when i print date between 2019-05-01 and 2019-05-09
//date range
Array
(
[2019-05-01] => 09:30:00
[2019-05-02] => 09:30:00
[2019-05-03] => 09:30:00
[2019-05-06] => 09:30:00
[2019-05-07] => 09:30:00
[2019-05-08] => 09:30:00
[2019-05-09] => 09:30:00
)
// public holiadys
Array
(
[0] => 2019-05-08
[1] => 2019-05-09
)
$start = new DateTime('2019-05-01');
$end = new DateTime('2019-05-31');
// getting the day interval https://php.net/manual/en/class.dateinterval.php
$day = new DateInterval("P1D");
//holidays hardcoded for testing, must create database abd select dates from there
$holidays = array('2016-01-01','2016-03-25');
$days = array();
//hours set to 8 hours a daye
$startTime = new DateTime('08:00:00');
$endTime = new DateTime('17:30:00');
$duration = $startTime->diff($endTime);
$data = $endTime - $startTime;
foreach(new DatePeriod($start, $day, $end->add($day)) as $day => $k) {
$day_num = $k->format("N");
$w = $day_num;
if($w < 6) { //if its wmore than 5 its weekend
$days[$k->format("Y-m-d")] = $duration->format("%H:%I:%S");
}
}
foreach ($holidays as $value) {
$value = $value;
}
print_r($days);
print_r($holidays);
need to calculate the total time between those dates excluding weekend and public holidays
You didn't say, so I will assume that the weekend part is working. Just check the $holidays array:
foreach(new DatePeriod($start, $day, $end->add($day)) as $k) {
$dnm = $k->format("N");
$key = $k->format("Y-m-d")
if($dnm < 6 && !in_array($key, $holidays)) {
$days[$key] = $duration->format("%H:%I:%S");
}
}

how to get wednesday date between two dates in php

need to obtain all wednesday dates between two dates. For ex
start and end date=
01/07/2019 - 01/25/2019
expected result=
01/09/2019,
01/16/2019,
01/23/2019
can i use if ($startDate->format('w') == 2) {}
condition to filter wednesdays and push into array. any method to get the result?
Use DatePeriod Class. date period allows iteration over a set of dates and times, recurring at regular intervals, over a given period.
$period = new DatePeriod(
new DateTime($date1),
new DateInterval('P1D'),
new DateTime($date2)
);
$cnt = 0;
foreach ($period as $key => $value) {
if($value->format('D') == 'Wed'){
$wed[$cnt] = $value->format('m/d/Y');
$cnt++;
}
}
Output
[0] => 01/09/2019
[1] => 01/16/2019
[2] => 01/23/2019
<?php
$from_date ='01/07/2019';
$to_date ='01/25/2019';
$from_date = new DateTime($from_date);
$to_date = new DateTime($to_date);
$get_date = array();
for ($date = $from_date; $date <= $to_date; $date->modify('+1 day')) {
if($date->format('l') == 'Wednesday'){
$get_date[] = $date->format('m/d/Y');
}
}
print_r($get_date);
Out put
Array ( [0] => 01/09/2019 [1] => 01/16/2019 [2] => 01/23/2019 )
You will get the required output.
<?php
$date1 = date("01/07/2019");
$date2 = date("01/25/2019");
$day1 = date('D', strtotime($date1));
$period = new DatePeriod(New Datetime($date1),New DateInterval('P1D'),New DateTime($date2));
$cnt = 0;
foreach($period as $key => $value ){
if($value->format('D') == 'Wed'){
$wed[$cnt] = $value->format('m/d/Y');
echo $wed[$cnt];
$cnt++;
echo '<BR>';
}
}
?>
Using the base DateTime class and instead of checking every day, just keep adding 7 days to the date and check if it is still less than the end date. The only additional logic is that if the start date is a Wednesday, then use this date, otherwise get the next Wednesday...
$fromDate = new DateTime('01/02/2019');
if ( $fromDate->format('D') != 'Wed') {
$fromDate->modify("next wednesday");
}
$toDate = new DateTime('01/25/2019');
do {
echo $fromDate->format("m/d/Y").PHP_EOL;
}
while ( $fromDate->modify(""+7 day"") < $toDate );
outputs...
01/02/2019
01/09/2019
01/16/2019
01/23/2019

Split time by day of the week with an interval defined by two Zend_Date

I have two Zend_Date that represent an interval :
$start = new Zend_Date($punch->getStart());
$end = new Zend_Date($punch->getEnd());
$nbHours = $start->sub($end , Zend_Date::HOUR);
$nbMinutes = $start->sub($end , Zend_Date::MINUTE);
$hoursTotal = $nbHours->get(Zend_Date::HOUR);
$minutesTotal = $nbMinutes->get(Zend_Date::MINUTE);
Is there an simple way to split the interval by day of the week with Zend_Date when the interval > 24 hours?
For example, if I have an interval from Monday 8am to Tuesday 4:30pm, I would like to have an array containing monday = 16h and tuesday = 16:30.
You don't need to use Zend_Date for this, in fact it is probably better not to. You should use the date/time classes in PHP instead.
If I understand your question correctly you want an array of days and the hours worked for those days.
I first created a mock class to reflect your code example, I have assumed it is returning timestamps:-
class Punch
{
public function getStart()
{
return time();
}
public function getEnd()
{
return strtotime('+36 hours 45 minutes');
}
}
Then we set up the DateTime objects-
$Punch = new Punch();
$start = new DateTime();
$start->setTimestamp($Punch->getStart());
$end = new DateTime();
$end->setTimestamp($Punch->getEnd());
Then we use a DateInterval object to generate our iterable DatePeriod:-
$interval = new DateInterval('PT1M');
$minutes = new DatePeriod($start, $interval, $end);
Then we simply iterate over it counting the minutes worked in each day:-
$format = 'l';
foreach($minutes as $minute){
if(!isset($result[$minute->format($format)])) $result[$minute->format($format)] = 0;
$result[$minute->format($format)]++;
}
See the manual page for acceptable formats.
We now have the number of minutes worked in each day, converting them to hours is trivial:-
foreach($result as $key => $r){
$result[$key] = $r/60;
}
var_dump($result);
Output (Obviously, you will get a different result running it at a different time) :-
array
'Monday' => float 17.483333333333
'Tuesday' => float 19.266666666667
So on Monday 17.48 hours were worked and 19.27 on Tuesday.
Alternatively:-
foreach($result as $key => $r){
$result[$key] = floor($r/60) . ':' . $r % 60;
}
Would give the following output if that is closer to what you want:-
array
'Monday' => string "17:29"
'Tuesday' => string "19:16"
That's the simplest way I can think of doing it.

Add missing dates to an array

I have the following array:
Array ( [2010-10-30] => 1 [2010-11-11] => 1 [2010-11-13] => 11 )
I am trying to fill in the array with all the missing dates between the first and last elements. I was attempting using the following but got nowhere:
foreach($users_by_date as $key => $value){
$real_next_day = date($key, time()+86400);
$array_next_day = key(next($users_by_date));
if($real_next_day != $array_next_day){
$users_by_date[$real_next_day] = $value;
}
}
The DateTime, DateInterval and DatePeriod classes can really help out here.
$begin=date_create('2010-10-30');
$end=date_create('2010-11-13');
$i = new DateInterval('P1D');
$period=new DatePeriod($begin,$i,$end);
foreach ($period as $d){
$day=$d->format('Y-m-d');
$usercount= isset($users_by_date[$day]) ? $users_by_date[$day] :0;
echo "$day $usercount";
}
I have been waiting for a chance to try out DateTime and DateInterval objects in PHP 5.3, your question was the perfect opportunity to do just that. Note that this code will not work with PHP versions earlier than 5.3
<?php
$dates = array('2010-10-30' => 1, '2010-11-01' => 1, '2010-11-13' => 1);
// get start and end out of array
reset($dates);
$start = new DateTime(key($dates));
end($dates);
$end = new DateTime(key($dates));
foreach (new DatePeriod($start, new DateInterval('P1D'), $end) as $date) {
$dateKey = $date->format('Y-m-d'); // get properly formatted date out of DateTime object
if (!isset($dates[$dateKey])) {
$dates[$dateKey] = 1;
}
}
print_r($dates);
The functions you are looking for (but not using in your example) are strtotime & diff
You would get the day range between your two dates $numdiff, and simply do something in a loop that would do:
for ($i=1; $i<=$numdiff; $i++) {
echo date("Y-m-d", strtotime("2010-10-30 +".$i." day"));
}
Result should be something like:
2010-10-31
2010-11-01
2010-11-02...
You could then pop that into your array as needed. Hope that gets you started in the right direction.
For indexes using timestamps, you can generate your array easily using the range function.
$startStamp = ...
$endStamp = ...
$oneDay = 60*60*24;
$timeIndexes = range($startStamp, $endStamp, $oneDay);
$filler = array_fill(0, count($timeIndexes), null);
$timeArray = array_combine($timeIndexes, $filler);
I am not sure what values you want in the array, but hopefully it is relatively straight-forward from here.
If you are going to be converting every timestamp to a formatted date string anyhow and would just prefer to use date strings in the first place, consider this modification.
$dateStringIndexes = array_map(
function ($t) {
return date('Y-m-d', $t);
},
$timeIndexes
);
Of course, since you are on PHP 5.2, you will likely have to compromise with a foreach loop instead of the closure.
This is the PHP 5.2 capable function I came up with that works.
Thanks guys
reset($users_by_date);
$date = key($users_by_date);
end($users_by_date);
$end = key($users_by_date);
while(strtotime($date) <= strtotime($end)){
$datearray[] = date("Y-m-d", strtotime($date));
$date = date("Y-m-d", strtotime("+1 day", strtotime($date)));
}
foreach($datearray as $key => $value){
if(!isset($users_by_date[$value])){
$users_by_date[$value] = 0;
}
}
ksort($users_by_date);

Categories