I am working on a free date time slots. I am stuck on creating proper spilts array and displaying available time slots .
I want to spilt into 2 Hour slot possible from start and end time.
foreach ( $period as $dt ){
$m = [
'start'=>date('Y-m-d ',strtotime($dt->format('Y-m-d').' -1
day')).$max,
'end'=>$dt->format('Y-m-d ').$min
];
foreach($free as $k=>$f){
if($m['start']>$f['start'] && $m['start']<=$f['end']){
$free[$k]['end'] = $m['start'];
if($m['end']<$f['end'])
$free[] = ['start'=>$m['end'], 'end'=>$f['end']];
}
elseif($m['end']<$f['end'] && $m['end']>$f['start']){
$free[$k]['start'] = $m['end'];
}
}
}
So for example, the meeting times array above should produce the following array of free time:
Array
(
[0] => Array
(
[start] => 2019-05-08 07:00:00
[end] => 2019-05-08 17:00:00
)
[1] => Array
(
[start] => 2019-05-09 11:25:00
[end] => 2019-05-09 12:40:00
)
[2] => Array
(
[start] => 2019-05-09 14:15:00
[end] => 2019-05-09 14:30:00
)
[3] => Array
(
[start] => 2019-05-10 07:00:00
[end] => 2019-05-10 17:00:00
)
[4] => Array
(
[start] => 2019-05-09 07:00:00
[end] => 2019-05-09 07:40:00
)
[5] => Array
(
[start] => 2019-05-11 07:00:00
[end] => 2019-05-11 17:00:00
)
)
Expected Output :
Array
(
[0] => Array
(
[0] => Array(
[start] => 2019-05-08 07:00:00
[end] => 2019-05-08 09:00:00
)
[1] => Array(
[start] => 2019-05-08 09:00:00
[end] => 2019-05-08 11:00:00
)
[2] => Array(
[start] => 2019-05-08 11:00:00
[end] => 2019-05-08 13:00:00
)
[3] => Array(
[start] => 2019-05-08 13:00:00
[end] => 2019-05-08 15:00:00
)
[4] => Array(
[start] => 2019-05-08 15:00:00
[end] => 2019-05-08 17:00:00
)
)
[1] => Array
(
[start] => 2019-05-09 11:25:00
[end] => 2019-05-09 12:40:00
)
.. so on ...
You can approach this as
foreach($arr as $k => $v){
$diff = strtotime($v['end'])-strtotime($v['start']);
if($diff >= 7200){
for($i=strtotime($v['start']);$i<strtotime($v['end']);){
$start = date('Y-m-d H:i:s',$i);
$i = $i+7200;
$end = date('Y-m-d H:i:s',$i);
$res[$k][] = [
'start' => $start,
'end' => $end
];
}
}else{
$res[$k][] = [
'start' => date('Y-m-d H:i:s',strtotime($v['start'])),
'end' => date('Y-m-d H:i:s',strtotime($v['end']))
];
}
}
Live Demo
I would suggest using \DateTime, its quite comfortable to use
<?php
$start = new \DateTime('2019-05-08 07:00:00');
$end = new \DateTime('2019-05-08 07:30:00');
function getSlots(\DateTime $start, \DateTime $end): array
{
$slots = [];
while ($start < $end) {
$old = clone($start);
$start->modify('+2 hours');
if ($start > $end) {
echo 1;
$slots[] = [
'from' => $old,
'to' => $end
];
return $slots;
} else {
$slots[] = [
'from' => $old,
'to' => clone($start)
];
}
}
return $slots;
}
var_dump(getSlots($start, $end));
And you can try it out there https://3v4l.org/qAatj
Related
I have this nested array, it's in a variable called $dates_list
Array
(
[0] => Array
(
[0] => Array
(
[event_date] => 2020-11-19 00:00:00
[event_start_time] => 13:07:00
[event_end_time] => 17:07:00
)
[1] => Array
(
[event_date] => 2020-06-17 00:00:00
[event_start_time] => 10:07:00
[event_end_time] => 17:07:00
)
[2] => Array
(
[event_date] => 2020-03-05 00:00:00
[event_start_time] => 15:46:00
[event_end_time] => 20:46:00
)
)
[1] => Array
(
[0] => Array
(
[event_date] => 2020-07-07 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
[1] => Array
(
[event_date] => 2020-03-13 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
)
)
and I've got a variable called $now
$now = date("Y-m-d h:i:s");
// 2020-03-13 02:28:32
How do I filter out all the event_date keys that are older than $now?
If event_date is the same as $now I'd like that to be left in the array
Desired result
I'm hoping to be able to get it to look like this, notice [event_date] => 2020-03-05 00:00:00 has been removed
Array
(
[0] => Array
(
[0] => Array
(
[event_date] => 2020-11-19 00:00:00
[event_start_time] => 13:07:00
[event_end_time] => 17:07:00
)
[1] => Array
(
[event_date] => 2020-06-17 00:00:00
[event_start_time] => 10:07:00
[event_end_time] => 17:07:00
)
)
[1] => Array
(
[0] => Array
(
[event_date] => 2020-07-07 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
[1] => Array
(
[event_date] => 2020-03-13 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
)
)
You have to loop all items in Array and then compare dates:
foreach($dates_list as $key=>$item) {
foreach($item as $k=>$value) {
if (date("Y-m-d h:i:s", strtotime($value["event_date"])) < $now) {
unset($dates_list[$key][$k]);
}
}
}
You could use the array_filter_recursive() suggested in this user comment and just recurisvely filter through the arrays:
function array_filter_recursive($input, $callback = null)
{
foreach ($input as &$value) {
if (is_array($value)) {
$value = array_filter_recursive($value, $callback);
}
}
return array_filter($input, $callback);
}
$array = [
[
['event_date' => '2020-11-19 00:00:00'],
['event_date' => '2020-06-17 00:00:00'],
['event_date' => '2020-03-05 00:00:00'],
],
[
['event_date' => '2020-07-07 00:00:00'],
['event_date' => '2020-03-13 00:00:00'],
]
];
$currentTime = '2020-03-13 02:28:32'; // date and time from question
$filtered = array_filter_recursive($array, function($value) use ($currentTime) {
// do not remove the first-level arrays
if (!isset($value['event_date'])) {
return true;
}
return $value['event_date'] > $currentTime;
});
var_export($filtered);
output:
array (
0 =>
array (
0 =>
array (
'event_date' => '2020-11-19 00:00:00',
),
1 =>
array (
'event_date' => '2020-06-17 00:00:00',
),
),
1 =>
array (
0 =>
array (
'event_date' => '2020-07-07 00:00:00',
),
),
)
I'm using DateInterval and DatePeriod to generate shifts in a medical application
$begin = new DateTime('2012-08-01 08:00');
$end = new DateTime('2012-08-01 12:00');
$interval = new DateInterval('PT45M');
$daterange = new DatePeriod($begin, $interval ,$end);
Those functions allow me to generate the following array
Array
(
[0] => 08:00
[1] => 08:45
[2] => 09:30
[3] => 10:15
[4] => 11:00
[5] => 11:45
)
Which functions and how could I do so the final array gets completed and chunked as this?
Array
(
[0] => Array
(
[0] => 08:00
[1] => 08:45
)
[1] => Array
(
[0] => 08:45
[1] => 09:30
)
[2] => Array
(
[0] => 09:30
[1] => 10:15
)
[3] => Array
(
[0] => 10:15
[1] => 11:00
)
[4] => Array
(
[0] => 11:00
[1] => 11:45
)
)
Thanks
$previous = null;
$dates = array();
foreach ($period as $dt) {
$current = $dt->format("H:i");
if (!empty($previous)) {
$show = new DateTime($current);
$dates[] = array($previous, $show->format('H:i'));
}
$previous = $current;
}
After retrieve your array using DateTime function. Just Plug n Play with the code. :)
$retrieveArray = array('08:00','08:45','09:30','10:15','11:00','11:45'); // Sample Array, Assumed mentioned in Question.
$final = array();
for ($i=0; $i < count($retrieveArray)-1; $i++) {
$j = $i+1;
$final[$i] = array($retrieveArray[$i], $retrieveArray[$j]);
}
Use var_dump($final); to check array result.
Desired Output
Array
(
[0] => Array
(
[0] => 08:00
[1] => 08:45
)
[1] => Array
(
[0] => 08:45
[1] => 09:30
)
[2] => Array
(
[0] => 09:30
[1] => 10:15
)
[3] => Array
(
[0] => 10:15
[1] => 11:00
)
[4] => Array
(
[0] => 11:00
[1] => 11:45
)
)
Edit:
To Add Last Shift
#jhon is right. It skips the last boundary value if it matches exactly the length of the interval.
As you need it, I suggest to ADD +1 min to your end time. It's a tweak/fix but server the purpose.
$begin = new DateTime('2012-08-01 08:00');
$end = new DateTime('2012-08-01 10:00');
$end = $end->modify( '+1 minute' ); // Tweak, to add last shift value.
$interval = new DateInterval('PT30M');
$daterange = new DatePeriod($begin, $interval ,$end);
To Check Output
foreach ( $daterange as $dt ){
echo '<pre>';
echo $dt->format( "H:i" );
echo '</pre>';
}
It is including last boundary value if it matches exactly the length of the interval.
I have an array which each element contains a startdate and enddate formated in 'dd.mm.yy'.
Array
(
[0] =
(
[date_start] = 23.07.2014
[date_end] = 02.08.2014
)
)
Now i need to build an array that will contain every day between date_start and date_end to validate them later.
Now my question is how can i calculate every day between those dates and save it to an array ?
IF YOU JUST WANT DATE DIFFERENCE
<?php
$arr=array
(
array
(
'date_start' =>'23.07.2014',
'date_end' =>'02.08.2014'
),
array
(
'date_start' =>'15.07.2014',
'date_end' =>'02.08.2014'
)
);
foreach($arr as $key=>$val){
$diff=strtotime($val['date_end'])-strtotime($val['date_start']);
$new_arr[]=array(
'day_start'=>$val['date_start'],
'day_end'=>$val['date_end'],
'difference'=>$diff/(24*60*60)-1
);
}
print_r($new_arr);
?>
OUTPUT
Array
(
[0] => Array
(
[day_start] => 23.07.2014
[day_end] => 02.08.2014
[difference] => 9
)
[1] => Array
(
[day_start] => 15.07.2014
[day_end] => 02.08.2014
[difference] => 17
)
)
IF YOU WANT ALL DATE BETWEEN ARRAYS
<?php
$arr=array
(
array
(
'date_start' =>'23.07.2014',
'date_end' =>'02.08.2014'
),
array
(
'date_start' =>'15.07.2014',
'date_end' =>'02.08.2014'
)
);
foreach($arr as $key=>$val){
$diff=strtotime($val['date_end'])-strtotime($val['date_start']);
$day_diff=$diff/(24*60*60);
$alldiff=array();
for($i=1;$i<=$day_diff-1;$i++){
$alldiff[]=date('d.m.Y',(strtotime($val['date_start'])+$i*24*60*60));
}
$new_arr[]=array(
'day_start'=>$val['date_start'],
'day_end'=>$val['date_end'],
'difference'=>$alldiff
);
}
echo "<pre>";
print_r($new_arr);
?>
OUTPUT
Array
(
[0] => Array
(
[day_start] => 23.07.2014
[day_end] => 02.08.2014
[difference] => Array
(
[0] => 24.07.2014
[1] => 25.07.2014
[2] => 26.07.2014
[3] => 27.07.2014
[4] => 28.07.2014
[5] => 29.07.2014
[6] => 30.07.2014
[7] => 31.07.2014
[8] => 01.08.2014
)
)
[1] => Array
(
[day_start] => 15.07.2014
[day_end] => 02.08.2014
[difference] => Array
(
[0] => 16.07.2014
[1] => 17.07.2014
[2] => 18.07.2014
[3] => 19.07.2014
[4] => 20.07.2014
[5] => 21.07.2014
[6] => 22.07.2014
[7] => 23.07.2014
[8] => 24.07.2014
[9] => 25.07.2014
[10] => 26.07.2014
[11] => 27.07.2014
[12] => 28.07.2014
[13] => 29.07.2014
[14] => 30.07.2014
[15] => 31.07.2014
[16] => 01.08.2014
)
)
)
This should work:
$startDate = new DateTime('2014-05-01');
$endDate = new DateTime('2014-06-02');
// calculate diff
$diff = $startDate->diff($endDate);
$daysDiff = $diff->days;
for ($i = 0; $i < $daysDiff; $i++) {
// clone so the original date will not be changed
$currentDate = clone $startDate;
$currentDate->modify('+'.$i.' days');
echo $currentDate->format('Y-m-d H:i:s')."\n";
}
Now you only have to make this for every array entry and save it to an array
Why don't you convert dates into timestamp, then you loop from the timestamp_start until timestamp_end , by day amount of seconds, then you convert each steps into a new date to check later.
Something like this?
// Convert start and end dates to unix timestamp
$start = strptime($date_array[0]['date_start'], '%d.%m.%Y');
$end = strptime($date_array[0]['date_end'], '%d.%m.%Y');
$dates = array();
while ($start < $end){
$dates[] = date('d.m.Y', $start);
$start += 86400 // One day equals 86400 seconds
}
Try this as it is working for me
function getDates($startTime, $endTime) {
$day = 86400;
$format = 'd.m.Y';
$startTime = strtotime($startTime);
$endTime = strtotime($endTime);
$numDays = round(($endTime - $startTime) / $day);
$days = array();
for ($i = 1; $i < $numDays; $i++) {
$days[] = date($format, ($startTime + ($i * $day)));
}
return $days;
}
$days = getDates('23.07.2014', '02.08.2014');
$one = array('start' => '2012-10-12', 'stop' => '2012-11-04', 'over' => false);
$two = array('start' => '2012-10-29', 'stop' => '2012-11-14', 'over' => true);
$three = array('start' => '2012-11-12', 'stop' => '2012-12-07', 'over' => false);
$array = array($one, $two, $three);
this show me:
Array
(
[0] => Array
(
[start] => 2012-10-12
[stop] => 2012-11-04
[over] =>
)
[1] => Array
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array
(
[start] => 2012-11-12
[stop] => 2012-12-07
[over] =>
)
)
I would like make function for splitting these dates.
If in array is over = true then this date should split other dates.
For this example this should return:
Array
(
[0] => Array //this is changed
(
[start] => 2012-10-12
[stop] => 2012-10-28
[over] =>
)
[1] => Array //this is ok
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array //this is changed
(
[start] => 2012-11-15
[stop] => 2012-12-07
[over] =>
)
)
And second example:
$one = array('start' => '2012-10-12', 'stop' => '2012-12-04', 'over' => false);
$two = array('start' => '2012-10-29', 'stop' => '2012-11-14', 'over' => true);
$second = array($one, $two);
this return me:
Array
(
[0] => Array
(
[start] => 2012-10-12
[stop] => 2012-12-04
[over] =>
)
[1] => Array
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
)
and i would like receive:
Array
(
[0] => Array //this is changed - old [0] date
(
[start] => 2012-10-12
[stop] => 2012-10-28
[over] =>
)
[1] => Array //this is ok
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array //this is new - from old [0] date - next part
(
[start] => 2012-11-15
[stop] => 2012-12-04
[over] =>
)
)
http://codepad.org/tqtEYstB
http://codepad.org/6fYkYVQ8
How can I do it with PHP?
Try this.
foreach($arr as $key=>$val)
{
if(isset($arr[$key+1]) && $arr[$key+1]['over'] == true)
$arr[$key]['stop'] = date('Y-m-d', strtotime($arr[$key+1]['start'] .' -1 day'));
if(isset($arr[$key-1]) && $arr[$key-1]['over'] == true)
$arr[$key]['start'] = date('Y-m-d', strtotime($arr[$key-1]['stop'] .' +1 day'));
}
you can find the code here.
Update:
$arr1 = $arr;
foreach($arr as $key=>$val)
{
if(isset($arr[$key+1]) && $arr[$key+1]['over'] == true)
{
$arr[$key]['stop'] = date('Y-m-d', strtotime($arr[$key+1]['start'] .' -1 day'));
$arr[$key]['over'] = true;
}
if(isset($arr[$key-1]) && $arr[$key-1]['over'] == true)
{
$arr[$key]['start'] = date('Y-m-d', strtotime($arr[$key-1]['stop'] .' +1 day'));
$arr[$key]['over'] = true;
}
}
foreach($arr1 as $key=>$val)
{
$arr[$key]['over'] = $arr1[$key]['over'];
}
your updated code here.
I have two dates (start and end), for example:
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
i would like generate -4 and +4 days interval for this. So i would like receive for example array with:
$date['start'] = '2012-07-07';
$date['end'] = '2012-07-09';
$date['start'] = '2012-07-08';
$date['end'] = '2012-07-10';
$date['start'] = '2012-07-09';
$date['end'] = '2012-07-11';
$date['start'] = '2012-07-10';
$date['end'] = '2012-07-12';
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
$date['start'] = '2012-07-12';
$date['end'] = '2012-07-14';
$date['start'] = '2012-07-13';
$date['end'] = '2012-07-15';
$date['start'] = '2012-07-14';
$date['end'] = '2012-07-16';
$date['start'] = '2012-07-15';
$date['end'] = '2012-07-17';
How is the best way for this?
This code does the trick:
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
$dates=array();
for ($i=-4; $i<=4; $i++){
$startDate=strtotime($date['start'] );
$endDate=strtotime($date['end'] );
$startDate=$startDate+($i*60*60*24); //60*60*24 equal to one day
$endDate=$endDate+($i*60*60*24);
array_push($dates, array('start'=>date('Y-m-d', $startDate), 'end'=> date('Y-m-d',$endDate)));
}
print_r($dates);
Output:
Array(
[0] => Array
(
[start] => 2012-07-07
[end] => 2012-07-09
)
[1] => Array
(
[start] => 2012-07-08
[end] => 2012-07-10
)
[2] => Array
(
[start] => 2012-07-09
[end] => 2012-07-11
)
[3] => Array
(
[start] => 2012-07-10
[end] => 2012-07-12
)
[4] => Array
(
[start] => 2012-07-11
[end] => 2012-07-13
)
[5] => Array
(
[start] => 2012-07-12
[end] => 2012-07-14
)
[6] => Array
(
[start] => 2012-07-13
[end] => 2012-07-15
)
[7] => Array
(
[start] => 2012-07-14
[end] => 2012-07-16
)
[8] => Array
(
[start] => 2012-07-15
[end] => 2012-07-17
)
)
range(date('Y-m-d', strtotime('-4 days'), date('Y-m-d', strtotime('+4 days'))),
You want 9 pairs of dates starting from -4 days of the supplied range, upto +4 days?
Assuming that your dates will be after 1970:
<?php
$start=strtotime($date['start']);
$end=strtotime($date['end']);
for($loop=-4;$loop<=4;$loop++)
{
$loop_str='';
if($loop>=0) $loop_str.='+';
$loop_str.=$loop.' days';
$date['start']=strtotime($loop_str, $start);
$date['end']=strtotime($loop_str, $end);
print_r($date);
}
?>