I am wondering if there is a simpler / better way to handle this. Basically someone has a schedule from 9:00 AM to 5:00 PM and request an absence from 11:00 - 1:00 PM.
It would be split into:
[
['start'=> '9:00 AM', 'end' => '11:00 AM'],
['start'=> '11:00 AM', 'end' => '1:00 PM'],
['start'=> '1:00 PM', 'end' => '5:00 PM'],
]
My approach seems wrong, as I would be manually creating scenarios for each case.
Here is an example of what I am trying.
function splitTimesByStartAndEndTime( $days, $requested_start_time, $requested_end_time) {
$retval = [];
foreach ( $days as $day ) {
if ( strtotime( $day[ 'start_time' ] ) <= $requested_start_time && strtotime( $day[ 'end_time' ] ) >= $requested_end_time ) {
$retval[$day['start_date']][] = [
'start_time' => $day['start_time'],
'end_time' => $requested_start_time,
];
$retval[$day['start_date']][] = [
'start_time' => $requested_end_time,
'end_time' => $requested_start_time,
];
$retval[$day['start_date']][] = [
'start_time' => $requested_end_time,
'end_time' => $day['end_time'],
];
}
return $retval;
}
And need to handle scenarios where the request is not just in the middle. Such at goes from start to middle of shift, or middle of shift to end. Then also edge case where request is before start of shift etc, so bounds checking.
Related
I want to display the start date and end date of the week. I have One date and a string like 1W4 and,in 1W4 consider 4 weeks and 1 visit so, my string like this 2W4,1W2,3W3,1W1,2W4.
I want to make start date and end date of week array according to string and week start from Sunday to Saturday.
Please post me if anyone has solution.Please ignoring if mistake in asking Question.
Thank you.
Try my php code:
From php.net datetime.format:
W: ISO-8601 week number of year, weeks starting on Monday.
The first calendar week of a year is that one which includes the first Thursday of that year.
So I have to rest one day to the start week date.
I assumed that the weeks correspond to the current year.
Input string:
$weeksString = "2W4,1W2,3W3,1W1,2W4";
Code:
<?php
$weeksArray = explode(",", $weeksString);
$result = array();
foreach($weeksArray as $visitsWeek) {
list($visits, $week) = explode("W", $visitsWeek);
$startDate = date("Y-m-d", strtotime(date("Y") . "W" . str_pad($week, 2, "0", STR_PAD_LEFT) . " -1 days"));
$endDate = date("Y-m-d", strtotime($startDate . " +6 days"));
$result[] = array("week" => $week, "startDate" => $startDate, "endDate" => $endDate);
}
?>
Output array $result:
array ( 0 => array ( 'week' => '4', 'startDate' => '2021-01-24', 'endDate' => '2021-01-30', ), 1 => array ( 'week' => '2', 'startDate' => '2021-01-10', 'endDate' => '2021-01-16', ), 2 => array ( 'week' => '3', 'startDate' => '2021-01-17', 'endDate' => '2021-01-23', ), 3 => array ( 'week' => '1', 'startDate' => '2021-01-03', 'endDate' => '2021-01-09', ), 4 => array ( 'week' => '4', 'startDate' => '2021-01-24', 'endDate' => '2021-01-30', ), )
I am trying to output the count of total registrations today, registrations in the last 7 days, last 30 days.
All the other counts are output as expected. Except for registrations today.
$registration_summery = [
'Registrations today' => '+0 days',
'Registrations in the last 7 Days' => '-7 days',
'Registrations in the last 15 Days' => '-15 days',
'Registrations in the last 30 Days' => '-30 days',
'Registrations in the last 6 month' => '-6 months',
'Registrations in the last 1 year' => '-1 Years'
];
$toReturn['registration_summery'][] = ['name' => 'Total Learners', 'value' => \DB::table('users')->where('users.role', 'student')->count()];
foreach ($registration_summery as $key => $value) {
$tmp = \DB::table('users')->where('role', 'student')
->where('createdAt', '>=', strtotime("tomorrow", strtotime($value)) - 1)
->where('createdAt', '<=', strtotime("midnight"))
->count();
$toReturn['registration_summery'][] = ['name' => $key, 'value' => $tmp];
}
No Errors, but the count shows 0
You can achieve that by substracting 23 hours more like this.
$registration_summery = [
'Registrations today' => '+0 days -23Hours',
// rest data.....
Fixed this.
Changed line 2 to -1 days.
$registration_summery = ['Registrations today' => '-1 days', 'Registrations in the last 7 Days' => '-7 days',
and changed "midnight" to "tomorrow"
->where('createdAt', '<=', strtotime("tomorrow"))
Thank you #rahul for your help
Let's assume we have a "big" date and time range, like
$big = [
'start' => '2018-09-01 00:00:00',
'stop' => '2018-09-01 23:59:59'
]
I have to create an array with all ranges not included in another array, like the following:
$exclude = [
[
'start' => '2018-09-01 12:00:00',
'stop' => '2018-09-01 14:59:59'
],
[
'start' => '2018-09-01 18:00:00',
'stop' => '2018-09-01 19:59:59'
]
]
so that the resulting structure would be something like this:
$results = [
[
'start' => '2018-09-01 00:00:00',
'stop' => '2018-09-01 11:59:59'
],
[
'start' => '2018-09-01 15:00:00',
'stop' => '2018-09-01 17:59:59'
],
[
'start' => '2018-09-01 20:00:00',
'stop' => '2018-09-01 23:59:59'
]
]
tl;dr
I have a big date time range (like the ones wrote above) and I have to create a resulting one by removing one or more ranges coming from another structure. Something like extracting the work breaks from the day, thus keeping only the real working hours.
I'm using Carbon and Laravel, any native solution to this or should I parse the whole structure and make the holes on my own? I don't like to reinvent the wheel.
I don't know a lot on carbon but I know that Carbon extends the native DateTime class so the following code can be adapted to achieve your purpose:
$result=[['start'=>$big['start'],'stop'=>''],['start'=>'','stop'=>''],['start'=>'','stop'=>$big['stop']]];//you can build this with a loop if you want...
foreach($result as $k =>$value){
switch($k){
case 0:
$result[$k]['stop']=(($date=date_create($exclude[0]['start']))&&$date->sub(new dateInterval('PT1S')))?$date->format('Y-m-d H:i:s'):'';
unset($date);
break;
case 1:
$result[$k]['start']=(($date=date_create($exclude[0]['stop']))&&$date->add(new dateInterval('PT1S')))?$date->format('Y-m-d H:i:s'):'';
$result[$k]['stop']=(($date=date_create($exclude[1]['start']))&&$date->sub(new dateInterval('PT1S')))?$date->format('Y-m-d H:i:s'):'';
unset($date);
break;
case 2:
$result[$k]['start']=(($date=date_create($exclude[1]['stop']))&&$date->add(new dateInterval('PT1S')))?$date->format('Y-m-d H:i:s'):'';
unset($date);
break;
default:
break;
}
}
I have multiple intervals in PHP and I want to know what is maximum end_date in continuing intervals.
Example 1 (we have 3 intervals):
start_date - end_date
2017-01-01 - 2018-01-01
2018-01-01 - 2019-01-01
2019-02-01 - 2020-02-01
Result of function is 2019-01-01, because our date continues to there. Then there is 1 month gap.
Example 2 (5 intervals):
start_date - end_date
2017-01-01 - 2017-02-01
2017-01-05 - 2017-01-10
2017-01-30 - 2017-02-05
2017-02-03 - 2017-02-04
2017-02-08 - 2017-02-12
Result here is 2017-02-05
I am not sure if there is some helpfull function for this. I was trying to search like intervals or something like that without any solution.
Thank you for any clues.
Use the date_diff() function:
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
I didn't find anything helpfull in PHP or any clue for this anywhere, so I program it myself:
<?php
$example1 = [
['start' => '2017-01-01', 'end' => '2018-01-01'],
['start' => '2018-01-01', 'end' => '2019-01-01'],
['start' => '2019-02-01', 'end' => '2020-02-01']
];
$example2 = [
['start' => '2017-01-01', 'end' => '2017-02-01'],
['start' => '2017-01-05', 'end' => '2017-01-10'],
['start' => '2017-01-30', 'end' => '2017-02-05'],
['start' => '2017-02-03', 'end' => '2017-02-04'],
['start' => '2017-02-08', 'end' => '2017-02-12']
];
// #param intervals are ordered by start date
function getMaxContinuingEndDate($intervals)
{
if (empty($intervals)) return NULL;
$result = ['start' => $intervals[0]['start'], 'end' => $intervals[0]['end']];
foreach($intervals as $interval) {
if ($interval['start'] <= $result['start'] && $interval['end'] >= $result['start']) {
$result['start'] = $interval['start'];
}
if ($interval['end'] >= $result['end'] && $interval['start'] <= $result['end']) {
$result['end'] = $interval['end'];
}
}
return $result['end'];
}
echo getMaxContinuingEndDate($example1);
echo "\n";
echo getMaxContinuingEndDate($example2);
The code below would set open and closed on my website. But it is not in the right time zone. How do i set it to the Dutch time zone?
So can some one help me out.
And also i have a question about setting it in days.
So you can set on the website the shippingtime depending on day. So on monday the shipping time is: send today. Or on sunday it is send on monday.
<?php
/**
* Based on the following business hours:
* (Note : 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' => ['00:00 AM' => '00:00 AM'],
'Mon' => ['9:00 AM' => '00:00 PM'],
'Tue' => ['9:00 AM' => '05:00 PM'],
'Wed' => ['9:00 AM' => '05:00 PM'],
'Thu' => ['9:00 AM' => '05:00 PM'],
'Fri' => ['9:00 AM' => '05:30 PM'],
'Sat' => ['9:00 AM' => '04:30 PM']
];
// current OR user supplied UNIX timestamp
$timestamp = time();
// default status
$status = 'momenteel gesloten, stuur ons een mail';
// 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 = '<b>bereikbaar op: Tel: 023-5313188</b> of <b>mail</b>';
break;
}
}
echo "Onze klantenservice is $status";
?>
use this for instantiating the current DateTime Object in Dutch Timezone:
$current = new DateTime(
'now',
new DateTimeZone('Europe/Amsterdam')
);
the problem was at the DateTime comparison. Creating a DateTime object from only the time sets the date to 1970-01-01...
/**
* Based on the following business hours:
* (Note : 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' => ['00:00 AM' => '00:00 AM'],
'Mon' => ['9:00 AM' => '00:00 PM'],
'Tue' => ['9:00 AM' => '05:00 PM'],
'Wed' => ['9:00 AM' => '05:00 PM'],
'Thu' => ['9:00 AM' => '05:00 PM'],
'Fri' => ['9:00 AM' => '05:30 PM'],
'Sat' => ['9:00 AM' => '04:30 PM']
];
// current OR user supplied UNIX timestamp
$timestamp = '2015-03-12 12:00:00'; // shows it is open
//$timestamp = '2015-03-12 8:59:59'; // shows closed
//$timestamp = '2015-03-12 9:00:00'; // shows open
//$timestamp = 'now'; // shows current status
// default status
$status = 'momenteel gesloten, stuur ons een mail';
// default timezone
$timeZone = new DateTimeZone('Europe/Amsterdam');
// get current time object
$currentTime = new DateTime($timestamp, $timeZone);
// 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(
'Y-m-d h:i A',
$currentTime->format('Y-m-d') . ' ' . $startTime,
$timeZone
);
$endTime = DateTime::createFromFormat(
'Y-m-d h:i A',
$currentTime->format('Y-m-d') . ' ' . $endTime,
$timeZone
);
// check if current time is within a range
if (($startTime <= $currentTime) && ($currentTime <= $endTime)) {
$status = '<b>bereikbaar op: Tel: 023-5313188</b> of <b>mail</b>';
break;
}
}
echo "Onze klantenservice is $status";