I have a FromDate and ToDate and days interval between them.
Now i want to get all date excluding weekends
If there is any weekends between my FromDate and ToDate,then this date will be increment by 2 days saturday and sunday.
In below example, i have calculated all date between 7/27/2018 and 8/27/2018 with 5 days interval between them,
public function testdate(){
$date_from = new \DateTime("7/27/2018");
$date_to = new \DateTime("8/27/2018");
$interval = new \DateInterval("P5D");
$dates = new \DatePeriod($date_from, $interval, $date_to);
$out = array();
if (!empty($dates)) {
foreach($dates as $dt) {
$out[] = array(
'month_year' => $dt->format('d/m/Y')
);
}
}
'<pre>';
//$out = array_reverse($out);
echo print_r($out);
'</pre>';
exit;
}
Expected output
Array
(
[0] => Array
(
[month_year] => 27/07/2018
)
[1] => Array
(
[month_year] => 02/08/2018
)
[2] => Array
(
[month_year] => 08/08/2018
)
[3] => Array
(
[month_year] => 14/08/2018
)
[4] => Array
(
[month_year] => 20/08/2018
)
[5] => Array
(
[month_year] => 27/08/2018
)
)
In above example, after 20/08/2018, next date will be 26/08/2018 but 26/08/2018 is sunday, so we exclude this sunday by 1 day and next date is now
27/08/2018.
If any occurence of date after calculating interval in between saturday and sunday then skip this weekend by 1 or 2days.
$year = date('Y');
$month = date('n');
$weekend_days = array_filter($allDays[$year][$month], function($d) {
return (date('N', strtotime(date("Y-m-$d"))) >= 6);
});
$allDays[$year][$month] = array_diff($allDays[$year][$month], $weekend_days);
print_r($allDays);
Related
I seem to have a problem, understanding how to sort my array the way i want to.
At the moment my array is like this, each index represent a weekday starting from monday.
Array
(
[0] => 08:00-18:00 // monday
[1] => 08:00-18:00 // tuesday
[2] => 08:00-18:00 // wednesday
[3] => 08:00-18:00 // thursday
[4] => 08:00-18:00 // friday
[5] => 10:00-14:00 // saturday
[6] => 10:00-14:00 // sunday
)
Let's say today is saturday, I need the array to look like this
Array
(
[0] => 10:00-14:00 // saturday
[1] => 10:00-14:00 // sunday
[2] => 08:00-18:00 // monday
[3] => 08:00-18:00 // tuesday
[4] => 08:00-18:00 // wednesday
[5] => 08:00-18:00 // thursday
[6] => 08:00-18:00 // friday
)
What i want is to show the opening hour for today.
Thanks.
Following logic might sit well with what you're trying to accomplish:
<?php
$arr = ["08:00-18:00", "08:00-18:00", "08:00-18:00", "08:00-18:00", "08:00-18:00", "10:00-14:00", "10:00-14:00",
];
// rework $arr - give it days as keys
$dow = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
foreach ($arr as $key => $value) {
$arr[$dow[$key]] = $value;
unset($arr[$key]);
}
// rotate array
$day = 'saturday'; // start array with saturday
$shift = array_search($day, $dow);
$arr = array_merge(array_slice($arr, $shift, NULL, true), array_slice($arr, 0, $shift, true));
Note: the nifty one-liner that does the rotate magic is from: https://www.php.net/manual/en/ref.array.php#105907
working demo
You can use the PHP date() function, to get the current day of the week (0=Sunday, 6=Saturday). You can either adjust your current array to operate from Sunday to Saturday, or you can adjust the array element # when you get the element(s) from the array.
date("w") will return the day of the week.
For a complete explanation of the PHP date() function, see this documentation...
https://www.w3schools.com/php/func_date_date.asp
This was fun, a little inventive use of 2 for loops will do this for you
function baseOnDay($day)
{
$open = ['08:00-18:00', '08:00-18:00', '08:00-18:00', '08:00-18:00',
'08:00-18:00', '10:00-14:00', '10:00-14:00'
];
$days = ['monday','tuesday','wednesday','thursday',
'friday', 'saturday', 'sunday'
];
$day = strtolower($day);
if (!in_array($day, $days)) {
return false; // passed a silly param
}
$newOpen = [];
$start = array_search($day, $days);
for ($i=$start; $i<count($open); $i++){
$newOpen[] = $open[$i];
}
for ($i=0; $i<$start; $i++){
$newOpen[] = $open[$i];
}
return $newOpen;
}
if ( ($openTimes = baseOnDay('saturday')) !== false ){
print_r($openTimes);
} else {
echo 'Bad Parameter';
}
RESULT
Array
(
[0] => 10:00-14:00
[1] => 10:00-14:00
[2] => 08:00-18:00
[3] => 08:00-18:00
[4] => 08:00-18:00
[5] => 08:00-18:00
[6] => 08:00-18:00
)
If your array is always Monday through Sunday and indexed 0 through 6, then just extract the one you want to the end and add it to the beginning of what's left. Saturday is 5 so remove that to the end:
$result = array_merge(array_splice($array, 5), $array);
I'm having a lot of difficulty approaching a piece of code in PHP. I have an array of dates and values, for example
dates = (2014-12-01,2014-12-02,2014-12-08,2014-12-09,2014-12-10,2014-12-11)
values = (5,3,7,8,9,2)
You'll note that 12/01 is a Monday, as is 12/08. I'd like to form 4 arrays from these two arrays:
monday = (5,7)
tuesday = (3,8)
wednesday = (0,9)
thursday = (0,2)
You'll note that the arrays are formed by grabbing the values associated with the days of the week. However, in the case that a Wednesday date exists, for example, but the prior Tuesday does not, then the array should have a "0". In other words, the 4 arrays should all be the same length.
Can anyone help me write code in PHP to achieve this? Thanks in advance!
NOTE: So far, I have only determined how to find the day of the week from a date: date('l', strtotime("2014-12-08")); I really can't figure out the general algorithm to solve this.
$dates = array( '2014-12-01','2014-12-02','2014-12-08','2014-12-09',
'2014-12-10','2014-12-11' );
$values = array( 5, 3, 7, 8, 9, 2 );
$date = strtotime(min($dates));
$stop = strtotime(max($dates));
$dates = array_flip($dates);
$out = array();
while($date <= $stop)
{
$tmp = date('Y-m-d', $date);
$out[date('l', $date)][] = isset($dates[$tmp]) && isset($values[$dates[$tmp]]) ?
$values[$dates[$tmp]] : 0;
$date = strtotime('+1 day', $date);
}
print_r($out);
Result:
Array
(
[Monday] => Array
(
[0] => 5
[1] => 7
)
[Tuesday] => Array
(
[0] => 3
[1] => 8
)
[Wednesday] => Array
(
[0] => 0
[1] => 9
)
[Thursday] => Array
(
[0] => 0
[1] => 2
)
[Friday] => Array
(
[0] => 0
)
[Saturday] => Array
(
[0] => 0
)
[Sunday] => Array
(
[0] => 0
)
)
ps: how can I get the an array of all the dates included in the "dates" array associated with only all the Mondays?
Modify the code as, for example:
$tmp = date('Y-m-d', $date);
$exists = isset($dates[$tmp]) && isset($values[$dates[$tmp]]);
$out[date('l', $date)]['numbers'][] = $exists ? $values[$dates[$tmp]] : 0;
if ($exists) $out[date('l', $date)]['dates'][] = $tmp;
$date = strtotime('+1 day', $date);
You'll get an output as (example for monday)
[Monday] => Array
(
[numbers] => Array
(
[0] => 5
[1] => 7
)
[dates] => Array
(
[0] => 2014-12-01
[1] => 2014-12-08
)
)
Might be a better way to get the 0s in there without another loop but I'm headed out:
foreach($dates as $key => $val) {
$day = date('l', strtotime($val));
$result[$day][] = $values[$key];
}
foreach($result as &$val) {
if(count($val) == 1) {
array_unshift($val, 0);
}
}
print_r($result);
Controlling hours of operation on a website from a database so end users can fiddle with them, and i'm trying to display them all in a neat manner.
Easy enough if i just do every day followed by its hours, however if monday-friday are all the same, i want to display it as monday-friday!
here is my array (call it $temp)
some places will open/close twice during a day hence the hours being in another array.
Array
(
[Monday] => Array
(
[0] => Array
(
[open] => 08:00am
[close] => 08:30pm
)
)
[Tuesday] => Array
(
[0] => Array
(
[open] => 08:00am
[close] => 08:30pm
)
)
[Wednesday] => Array
(
[0] => Array
(
[open] => 08:00am
[close] => 08:30pm
)
)
[Thursday] => Array
(
[0] => Array
(
[open] => 08:00am
[close] => 08:30pm
)
)
[Friday] => Array
(
[0] => Array
(
[open] => 08:00am
[close] => 08:30pm
)
)
[Saturday] => Array
(
[0] => Array
(
[open] => 10:30am
[close] => 08:30pm
)
)
[Sunday] => Array
(
[0] => Array
(
[open] => 10:30am
[close] => 08:30pm
)
)
)
Here is the code i have scraped together to try to manipulate the above array into grouping days that are the same:
$start = current(array_keys($temp)); //The first open weekday
$end = end(array_keys($temp)); //(SHOULD) only makes the end day the very last day IF they are all the same hours. will reset later.
$last = null;
$count = 0;
foreach($temp as $day => $hours) {
if($hours == $last) {
$count++;
$end = $day; // advance the day thats going to be the end.
continue; // dont want to hit the resets at the bottom.
}
else {
if($count = 0) {
$return['reg_hours'][$yesterday] = $last; //yesterdays hours had no matches so set it alone.
}
else { //There is a string of days with the same hours, so concat them
$return['reg_hours'][$start . ' - ' . $end] = $hours; // i.e. $return['Monday - Thursday'] = '07:00am - 10:30am'
}
$start = $day; //a new string of hours is starting so reset the start to today.
}
$count = 0;
$yesterday = $day;
$last = $hours;
}
I have commented in my thought process. This works fine if every day has the same hours, however clearly unintended results if hours differ at all. Below is what its returning for the above array:
Monday - Sunday 08:00am - 08:30pm
Monday - Friday 10:30am - 08:30pm
expected results:
Monday - Friday 08:00am - 08:30pm
Saturday - Sunday 10:30am - 08:30pm
Cant really figure out why the $start and $end variables aren't resetting as i expect them to. Any guidance is appreciated.
Try this:
//$days are the array with the data
$days_new = array();
$current_day = current($days)[0];
$days_new[] = array(
"init" => key($days),
"end" => key($days),
"open" => $current_day['open'],
"close" => $current_day['close']
);
foreach($days as $key => $day){
//update end day
if( $day[0]['open'] == $current_day['open']
&& $day[0]['close'] == $current_day['close'])
{
$days_new[count($days_new) - 1]['end'] = $key;
}
//create new reg
else{
$days_new[] = array(
"init" => $key,
"end" => $key,
"open" => $current_day['open'],
"close" => $current_day['close']
);
}
$current_day = $day[0];
}
to print the result you need to do something like this:
foreach($days_new as $key => $item){
print $item['init'];
$item['init'] == $item['end'] ? print " " : print " - " . $item['end'] . " ";
print $item['open'] . " - " . $item['close'] . "\n";
}
The result is:
Monday - Friday 08:00am - 08:30pm
Saturday - Sunday 08:00am - 08:30pm
It only works if a day haves just one open/close hour (array). If any place open/close twice daily (or more) you need to change the code just a little bit.
See the code on action
I have an multi-dimensional array called shifts which contains the day (e.g. Monday) and then the shift (e.g. 12:00 - 16:00)
I'm looking to do something like:
$monday = shift from array where day equals Monday
My array currently looks like:
Array ( [0] => Array ( [day] => Saturday [shift] => Day Off! )
[1] => Array ( [day] => Sunday [shift] => Day Off! )
[2] => Array ( [day] => Monday [shift] => 11:00-19:00 )
[3] => Array ( [day] => Tuesday [shift] => 08:00-17:00 )
[4] => Array ( [day] => Wednesday [shift] => 08:00-17:00 )
[5] => Array ( [day] => Thursday [shift] => 16:00-01:00 )
[6] => Array ( [day] => Friday [shift] => 16:00-01:00 ) )
Array is built using this code:
$shifts = array();
$sql = mysql_query("SELECT day, shift FROM ps_shifts WHERE user_id = '$user_id' AND week_begin = '$week_1_begin'");
while($row = mysql_fetch_assoc($sql)) {
$shifts[] = $day;
}
/* to refine on what was said above lets take the the data as such:*/
$data = array(
array ( 'day' => 'Saturday', 'shift' => 'Day Off!' ),
array ( 'day' => 'Sunday', 'shift' => 'Day Off!' ),
array ( 'day' => 'Monday', 'shift' => '11:00-19:00' ),
/* ... */
);
/* we then take that data and transform it, that is flatten it to day=>shift. call it shifts*/
$shifts = array();
$days = array('Saturday','Sunday','Monday','Tuesday','Wednesday','Thursday', 'Friday');
foreach ($data as $i=>$s) {
$shifts[$days[$i]] = $data[$i]['shift'];
}
/* this returns an array like:
$shifts = array (
'Saturday' => 'Day Off!',
'Sunday' => 'Day Off!',
'Monday' => '11:00-19:00',
);
*/
/* then to get the shift for any day is as simple as.*/
$monday_shift = $shifts['Monday'];
print "monday shift is: $monday_shift\n";
You could use the day as the array key.
So:
while($row = mysql_fetch_assoc($sql)) {
$shifts[$day['day']] = $day;
}
Then you could get it by doing this:
$shift_time = $shifts['Monday']['shift'];
Solved based on 'jd182' anwser, however the provided code didn't work so I modified to this:
$shifts = array();
$sql = mysql_query("SELECT day, shift FROM ps_shifts WHERE user_id = '$user_id' AND week_begin = '$week_1_begin'");
while($row = mysql_fetch_assoc($sql)) {
$shifts[$row['day']] = $row['shift'];
}
echo $shifts['Monday'];
This question already has answers here:
Push rows with default values into an array containing dates so there are no gaps between dates
(4 answers)
Closed 5 months ago.
I have an array of objects in php which looks like:
Array
(
[0] => Array
(
[day] => 1/23/2013
[executions] => 1
)
[1] => Array
(
[day] => 1/24/2013
[executions] => 1
)
[2] => Array
(
[day] => 1/27/2013
[executions] => 10
)
[3] => Array
(
[day] => 1/29/2013
[executions] => 1
)
[4] => Array
(
[day] => 1/30/2013
[executions] => 3
)
[5] => Array
(
[day] => 2/8/2013
[executions] => 1
)
[6] => Array
(
[day] => 2/11/2013
[executions] => 3
)
)
I am building a graph of this data, and basically it represents the last 30 days. The problem is I don't get the missing days, i.e. when there was no executions from the query. I am looking to fill in these missing days with PHP, simple set the day to the correct date, and executions to 0. Thus the result array should contain 30 elements, assuming start is 1/18/2013 and end is today 2/17/2013.
Any idea of the best algorithm to accomplish this in PHP?
Something like:
$start = '1/18/2013';
$end = '2/17/2013';
$range = new DatePeriod(
DateTime::createFromFormat('m/d/Y', $start),
new DateInterval('P1D'),
DateTime::createFromFormat('m/d/Y', $end));
$filler = array();
foreach($range as $date)
$filler[] = array(
'day' => $date->format('m/d/Y'),
'execution' => 0,
};
$array += $filler;
Loop through each date using DateTime:
$start = new DateTime('2013-01-18');
$end = new DateTime('2013-02-17');
while ($start <= $end)
{
$current_date = $start->format('m/d/Y');
// Right here look in your array and see if that date exists
// and do whatever you need to do if it does/does not
$start->modify("+1 day");
}
You may use this:
$startDate = new DateTime ( "-30 days" );
$dateItter = new DatePeriod (
$startDate,
new DateInterval ('P1D'),
30
);
$original = array (
array (
'days' => '02/16/2013',
'executions' => 5
)
);
$result = array ();
foreach ( $dateItter as $date )
{
$executions = 0;
foreach ( $original as $item ) {
if ( $item['days'] == $date->format ( 'm/d/Y' ) )
$executions = $item['executions'];
}
$result[] = array (
"day" => $date->format ( 'm/d/Y' ),
"executions" => $executions
);
}
var_dump ( $result );
It is slow for large amount of data but for 30 items will be ok!