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);
}
?>
Related
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
Following is my code to bring all the latest dates in a month from dates array
$dates = Array
(
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19",
);
$curr_val = '';
$years = Array();
$months = Array();
foreach($dates as $d) {
list($y,$m) = explode("/",$d);
$years[$y][] = $d;
if ($m != $curr_val){
$months[$y."/".$m][] = $d;
$curr_val = $m ;
}
}
$years = array_values($years);
$months = array_values($months);
print_r($months);
Above code is printing values of first occurance date in a month. But i want the latest date from month.
Above code gives following output
Array ( [0] => Array ( [0] => 2017/03/05 ) [1] => Array ( [0] => 2017/04/01 ) [2] => Array ( [0] => 2017/06/16 ) [3] => Array ( [0] => 2017/07/07 ) [4] => Array ( [0] => 2017/08/19 ) )
But expected code is
Array ( [0] => Array ( [0] => 2017/03/06 ) [1] => Array ( [0] => 2017/04/16 ) [2] => Array ( [0] => 2017/06/19 ) [3] => Array ( [0] => 2017/07/07 ) [4] => Array ( [0] => 2017/08/19 ) )
Instead of printing first date in month, i want last date of month to be printed. how can i get that??
Your code could be reduced a lot. Here's what I could do:
$dates = Array
(
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19",
);
$array = [];
foreach($dates as $d) {
$date = \DateTime::createFromFormat('Y/m/d' , $d);
if (
!isset($array[$date->format('Y')][$date->format('m')])
|| $array[$date->format('Y')][$date->format('m')] < $date
) {
$array[$date->format('Y')][$date->format('m')] = $date;
}
}
print_r($array);
It's a simple logic that will check if the value is higher inside the same year/month and replace if it is.
Result:
Array (
[2017] => Array
(
[03] => DateTime Object
(
[date] => 2017-03-06 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[04] => DateTime Object
(
[date] => 2017-04-16 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[06] => DateTime Object
(
[date] => 2017-06-19 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[07] => DateTime Object
(
[date] => 2017-07-07 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[08] => DateTime Object
(
[date] => 2017-08-19 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
)
)
Like this:
foreach($dates as $d) {
list($y,$m) = explode("/",$d);
$years[$y][] = $d;
$months[$y."/".$m] = [$d];
}
Don't worry about keeping track of the current value. Just keep overwriting $months[$y."/".$m] as you go, and you'll end up with the last date for each month.
If you want to get the most recent date from each month, rather than just the last one in the input array, make sure $dates is sorted before you start the loop. Since they're in year/month/day format, a simple sort($dates); should work. (In the case of your example, $dates is already sorted so this won't make any difference.)
This seems simplest to me:
Code: (Demo)
$dates[
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19"
];
foreach($dates as $d){
$result[substr($d,0,7)]=$d; // extract unique key from values
}
$result=array_values($result); // reindex array
var_export($result);
Output:
array (
0 => '2017/03/06',
1 => '2017/04/16',
2 => '2017/06/19',
3 => '2017/07/07',
4 => '2017/08/19',
)
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.