Get an array of years, months and weeks between two dates - php

I have this function that returns an array of years, months and days but I need to replace the days with weeks, so each month array will contain the weeks. Its not that easy.
$start_date = '2007-03-24';
$end_date = '2009-06-26';
year_month($start_date, $end_date);
//Returns an array containing the years, months and days between two dates
public function year_month($start_date, $end_date)
{
$begin = new DateTime( $start_date );
$end = new DateTime( $end_date);
$end->add(new DateInterval('P1D')); //Add 1 day to include the end date as a day
$interval = new DateInterval('P1D');
$period = new DatePeriod($begin, $interval, $end);
$aResult = array();
foreach ( $period as $dt )
{
$aResult[$dt->format('Y')][$dt->format('F')][$dt->format('j')] = $dt->format('D');
}
return $aResult;
}
Currently results in:
[2013] => Array
(
[October] => Array
(
[15] => Tue
[16] => Wed
[17] => Thu
[18] => Fri
[19] => Sat
[20] => Sun
[21] => Mon
[22] => Tue
[23] => Wed
[24] => Thu
[25] => Fri
[26] => Sat
[27] => Sun
[28] => Mon
[29] => Tue
[30] => Wed
[31] => Thu
)
[November] => Array
(
[1] => Fri
[2] => Sat
[3] => Sun
[4] => Mon
[5] => Tue
[6] => Wed
[7] => Thu
[8] => Fri
[9] => Sat
[10] => Sun
[11] => Mon
[12] => Tue
[13] => Wed
[14] => Thu
[15] => Fri
[16] => Sat
[17] => Sun
[18] => Mon
[19] => Tue
[20] => Wed
[21] => Thu
[22] => Fri
[23] => Sat
[24] => Sun
[25] => Mon
[26] => Tue
[27] => Wed
[28] => Thu
[29] => Fri
[30] => Sat
)
[December] => Array
(
I need something like this :
[2013] => Array
(
[October] => Array
(
[0] => week 1
[1] => week 2
[2] => week 3
[3] => week 4
[3] => week 5

Not sure if this is what you're wanting but, hey ho.
$start_date = '2007-03-24';
$end_date = '2009-06-26';
print_r(year_month($start_date, $end_date));
//Returns an array containing the years, months and week numbers between two dates
function year_month($start_date, $end_date)
{
$begin = new DateTime( $start_date );
$end = new DateTime( $end_date);
$end->add(new DateInterval('P1D')); //Add 1 day to include the end date as a day
$interval = new DateInterval('P1W'); //Add 1 week
$period = new DatePeriod($begin, $interval, $end);
$aResult = array();
foreach ( $period as $dt )
{
$aResult[$dt->format('Y')][$dt->format('F')][] = "Week ".$dt->format('W');
}
return $aResult;
}
Will return
Array
(
[2007] => Array
(
[March] => Array
(
[0] => Week 12
[1] => Week 13
)
[April] => Array
(
[0] => Week 14
[1] => Week 15
[2] => Week 16
[3] => Week 17
)
[May] => Array
(
[0] => Week 18
[1] => Week 19
[2] => Week 20
[3] => Week 21
)
[June] => Array
(
[0] => Week 22
[1] => Week 23
[2] => Week 24
[3] => Week 25
[4] => Week 26
)
[July] => Array
(
[0] => Week 27
[1] => Week 28
[2] => Week 29
[3] => Week 30
)
)
)
Full array

This function should do it, i use strtotime instead of the DateTime classes though
function year_month($start_date,$end_date){
$current_date = strtotime($start_date);
$end_date = strtotime($end_date);
$out=array();
while($current_date<=$end_date){
$out[date("Y",$current_date)][date("F",$current_date)][date("W",$current_date)][]=date("D",$current_date);
$current_date=strtotime("+1 days",$current_date);
}
return $out;
}
print_r(year_month("2007-03-24","2009-06-26"));

Related

Unset element in array nested, between a time interval

I'm trying to remove an element.
I've a reservation with:
$StartTime = "14:00"; $EndTime = "16:30";
and Array with
Array
(
[Tennis 1] => Array
(
[IntervalTime] => Array
(
[Lun] => Array
(
[0] => 10:00
[1] => 11:00
[2] => 12:00
[3] => 13:00
[4] => 14:00
[5] => 15:00
[6] => 16:00
[7] => 17:00
[8] => 18:00
[9] => 19:00
[10] => 20:00
)
[Mar] => Array
(
[0] => 12:00
[1] => 13:00
[2] => 14:00
[3] => 15:00
)
[Mer] => Array
(
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
)
[Gio] => Array
(
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
)
[Ven] => Array
(
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
)
[Sab] => Array
(
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
[5] => 14:00
[6] => 15:00
[7] => 16:00
[8] => 17:00
[9] => 18:00
)
[Sun] => Array
(
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
[5] => 14:00
[6] => 15:00
[7] => 16:00
[8] => 17:00
[9] => 18:00
)
)
)
I need to remove element between $StartTime and $EndTime
so for "Lun" array need to be removed:
[0] => 10:00
[1] => 11:00
[2] => 12:00
[3] => 13:00
[4] => 14:00 // need remove
[5] => 15:00 // need remove
[6] => 16:00 // need remove
[7] => 17:00
[8] => 18:00
[9] => 19:00
[10] => 20:00
I would to foearch the time from Start to End date, and then remove with:
unset($DisponibilitaRoom[$Nomeroom]["IntervalTime"]["Lun"][$index]);
You correct - simple unset should do it - but you need to loop on the times and remove them as:
foreach($arr['Tennis 1']['IntervalTime']['Lun'] as $k => $v) {
if ($v >= $StartTime && $v < $EndTime)
unset($arr['Tennis 1']['IntervalTime']['Lun'][$k]);
}
Live example: 3v4l
Or you can use array-filter as
$arr['Tennis 1']['IntervalTime']['Lun'] = array_filter($arr['Tennis 1']['IntervalTime']['Lun'], function ($v) use ($StartTime, $EndTime) {
return !($v >= $StartTime && $v < $EndTime);
} );
You can use array_walk_recursive with array_map and array_filter
array_walk_recursive($a['Tennis 1']['IntervalTime'], function(&$v) use ($StartTime, $EndTime){
if($v >= $StartTime && $v <= $EndTime) $v = false;
});
$f['Tennis 1']['IntervalTime'] = array_map('array_filter', $a['Tennis 1']['IntervalTime']);
print_r($f);
Working example :- https://3v4l.org/4tNEM

find missing date and then include in array

how to add $mydates (2019-04-01", "2019-04-08) include too in array ?
Give some suggestion please.
thanks
I referrer from here , but only find missing date
Find missing dates in range (php)
$myDates = array("2019-04-01", "2019-04-08");
$missingDates = array();
$dateStart = date_create("2019-04-01");
$dateEnd = date_create("2019-04-".date("t", mktime(0, 0, 0, 0, 1, 2019)));
$interval = new DateInterval('P1D');
$period = new DatePeriod($dateStart, $interval, $dateEnd);
foreach($period as $day) {
$formatted = $day->format("Y-m-d");
if(!in_array($formatted, $myDates)) $missingDates[] = $formatted;
}
echo '<pre>';print_r($missingDates);echo '</pre>';
result
Array
(
[0] => 2019-04-02
[1] => 2019-04-03
[2] => 2019-04-04
[3] => 2019-04-05
[4] => 2019-04-06
[5] => 2019-04-07
[6] => 2019-04-09
[7] => 2019-04-10
[8] => 2019-04-11
[9] => 2019-04-12
[10] => 2019-04-13
[11] => 2019-04-14
[12] => 2019-04-15
[13] => 2019-04-16
[14] => 2019-04-17
[15] => 2019-04-18
[16] => 2019-04-19
[17] => 2019-04-20
[18] => 2019-04-21
[19] => 2019-04-22
[20] => 2019-04-23
[21] => 2019-04-24
[22] => 2019-04-25
[23] => 2019-04-26
[24] => 2019-04-27
[25] => 2019-04-28
[26] => 2019-04-29
[27] => 2019-04-30
)
It's not clear exactly what you want as the output, but maybe some of these will give you some Ideas.
Like this for your code:
$missingDates = array("2019-04-01", "2019-04-08");
$dateStart = date_create("2019-04-01");
$dateEnd = date_create("2019-04-".date("t", mktime(0, 0, 0, 0, 1, 2019)));
$interval = new DateInterval('P1D');
$period = new DatePeriod($dateStart, $interval, $dateEnd);
foreach($period as $day) {
$formatted = $day->format("Y-m-d");
if(!in_array($formatted, $missingDates)) $missingDates[] = $formatted;
}
sort($missingDates);
echo '<pre>';print_r($missingDates);echo '</pre>';
Output
Array
(
[0] => 2019-04-01
[1] => 2019-04-02
[2] => 2019-04-03
[3] => 2019-04-04
[4] => 2019-04-05
[5] => 2019-04-06
[6] => 2019-04-07
[7] => 2019-04-08
[8] => 2019-04-09
[9] => 2019-04-10
[10] => 2019-04-11
[11] => 2019-04-12
[12] => 2019-04-13
[13] => 2019-04-14
[14] => 2019-04-15
[15] => 2019-04-16
[16] => 2019-04-17
[17] => 2019-04-18
[18] => 2019-04-19
[19] => 2019-04-20
[20] => 2019-04-21
[21] => 2019-04-22
[22] => 2019-04-23
[23] => 2019-04-24
[24] => 2019-04-25
[25] => 2019-04-26
[26] => 2019-04-27
[27] => 2019-04-28
[28] => 2019-04-29
[29] => 2019-04-30
)
Sandbox
One note here is this 2019 is probably going to cause you some issues in 2020
$dateEnd = date_create("2019-04-".date("t", mktime(0, 0, 0, 0, 1, 2019)));
You can't really fix this, because by the time you do it's preferable to use a date time for that, as I do below. You'll wind up turning the end date into a date time object, so you can get the year (new DateTime("2019-04-08"))->format('Y') at which point you might as well just use one of the options below. You cannot simply use the $dateStart object because the $dateEnd could be in next year depending on what you actually want.
All the days of this month
The above basically just gives you all the days of the month which you could do this way:
function getDaysOfMonth($date){
$dateStart = (new DateTime($date))->modify('first day of this month');
$dateEnd = (new DateTime($date))->modify('first day of next month');
$interval = new DateInterval('P1D');
$period = new DatePeriod($dateStart, $interval, $dateEnd);
$formatted = [];
foreach($period as $day) $formatted[] = $day->format("Y-m-d");
return $formatted;
}
print_r(getDaysOfMonth('2019-04-10'));
Output
Array
(
[0] => 2019-04-01
[1] => 2019-04-02
[2] => 2019-04-03
[3] => 2019-04-04
[4] => 2019-04-05
[5] => 2019-04-06
[6] => 2019-04-07
[7] => 2019-04-08
[8] => 2019-04-09
[9] => 2019-04-10
[10] => 2019-04-11
[11] => 2019-04-12
[12] => 2019-04-13
[13] => 2019-04-14
[14] => 2019-04-15
[15] => 2019-04-16
[16] => 2019-04-17
[17] => 2019-04-18
[18] => 2019-04-19
[19] => 2019-04-20
[20] => 2019-04-21
[21] => 2019-04-22
[22] => 2019-04-23
[23] => 2019-04-24
[24] => 2019-04-25
[25] => 2019-04-26
[26] => 2019-04-27
[27] => 2019-04-28
[28] => 2019-04-29
[29] => 2019-04-30
)
Sandbox
Remaining days of the month
Just change this line in the above:
$dateStart = (new DateTime($date))->modify('first day of this month');
To
$dateStart = new DateTime($date);
Output
Array
(
[0] => 2019-04-10
[1] => 2019-04-11
[2] => 2019-04-12
[3] => 2019-04-13
[4] => 2019-04-14
[5] => 2019-04-15
[6] => 2019-04-16
[7] => 2019-04-17
[8] => 2019-04-18
[9] => 2019-04-19
[10] => 2019-04-20
[11] => 2019-04-21
[12] => 2019-04-22
[13] => 2019-04-23
[14] => 2019-04-24
[15] => 2019-04-25
[16] => 2019-04-26
[17] => 2019-04-27
[18] => 2019-04-28
[19] => 2019-04-29
[20] => 2019-04-30
)
Sandbox
Start to End (inclusive)
This gives you all the days, but if you only want from your first to your second you can use this:
function getDays($dateStart,$dateEnd){
$dateStart = new DateTime($dateStart);
$dateEnd = (new DateTime($dateEnd))->modify('+1 day');
$interval = new DateInterval('P1D');
$period = new DatePeriod($dateStart, $interval, $dateEnd);
$formatted = [];
foreach($period as $day) $formatted[] = $day->format("Y-m-d");
return $formatted;
}
print_r(getDays('2019-04-01', '2019-04-08'));
Output
Array
(
[0] => 2019-04-01
[1] => 2019-04-02
[2] => 2019-04-03
[3] => 2019-04-04
[4] => 2019-04-05
[5] => 2019-04-06
[6] => 2019-04-07
[7] => 2019-04-08
)
Sandbox

Grouping days into months between 2 dates in PHP

Lets say we have:
$startDt="10/28/2017";
$endDt="12/2/2017";
I want to get array of days grouped into months in between these dates. Output must be like:
[
"October"=>[28, 29, 30, 31],
"November"=>[1, ..., 30],
"December"=>[1,2]
]
Can't figure out how to achieve it. Any suggestions?
You can use PHP's built-in classes DateTime, DateInterval and DatePeriod for this; e.g:
<?php
$start = new DateTime('10/28/2017');
$end = new DateTime('12/2/2017');
$interval = new DateInterval('P1D'); // 1 day
$period = new DatePeriod($start, $interval, $end);
$days = [];
foreach ($period as $dt) {
$month = $dt->format('F');
$day = $dt->format('j');
$days[$month][] = $day;
}
print_r($days);
Here is the documentation about date formatting
Note that DatePeriod goes up to but excludes the last date if the times are the same (which is the case here, so you probably want to modify the end date to address this - adding a second should do the trick; e.g:
$end = new DateTime('12/2/2017');
$end->modify('+1 second');
// or $end->setTime(0, 0, 1); H/T to #ishegg
$period = new DatePeriod($start, $interval, $end);
// etc.
This yields:
Array
(
[October] => Array
(
[0] => 28
[1] => 29
[2] => 30
[3] => 31
)
[November] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
[10] => 11
[11] => 12
[12] => 13
[13] => 14
[14] => 15
[15] => 16
[16] => 17
[17] => 18
[18] => 19
[19] => 20
[20] => 21
[21] => 22
[22] => 23
[23] => 24
[24] => 25
[25] => 26
[26] => 27
[27] => 28
[28] => 29
[29] => 30
)
[December] => Array
(
[0] => 1
)
)
Hope this helps :)

DateInterval with one month in php array

How can I get month Interval in php using DateInterval.
If I chose 05 Aug 2015 as start date and 17 Oct 2015 as end date, then my array output should be divided in 3 arrays:
1st array for 05 Aug 2015 - 31 Aug 2015
2nd array for 01 Sept 2015 - 30 Sept 2015
3rd array for 01 Oct 2015 - 17 Oct 2015
We can achieve this thing by php DateInterval function?
you can try the below code. I am not sure but you might get what you are looking for
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($d1, $interval, $d2);
foreach ($period as $dt) {
if($dt->format("Y-m") == date("Y-m", strtotime($date1))){
$date_array[$dt->format("Y-m")] = array(
'start_date' => $startDate,
'end_date' => $dt->format("Y-m-t"),
);
}else if($dt->format("Y-m") == date("Y-m", strtotime($date2))){
$date_array[$dt->format("Y-m")] = array(
'start_date' => $dt->format("Y-m-").'01',
'end_date' => $endDate,
);
}else{
$date_array[$dt->format("Y-m")] = array(
'start_date' => $dt->format("Y-m-").'01',
'end_date' => $dt->format("Y-m-t"),
);
}
}
foreach( $date_array as $d_key=>$da ){
/* your stuff */
}
This is pretty straightforward if you familiarise yourself with some of PHP's helpful built-in Date/Time classes.
You can use DateTime, DateInterval and DatePeriod to achieve your results. For example:
<?php
// create start/end dates and interval
$start = new DateTime('05 Aug 2015');
$end = new DateTime('17 Oct 2015');
$interval = new DateInterval('P1D');
// DatePeriod excludes the last day
// so bump the end date by one
$end->modify('+1 day');
// create a DatePeriod for each day in range
$period = new DatePeriod($start, $interval, $end);
$months = [];
foreach ($period as $date) {
$months[$date->format('F')][] = $date->format('m/d/Y');
}
print_r($months);
Yields:
Array
(
[August] => Array
(
[0] => 08/05/2015
[1] => 08/06/2015
[2] => 08/07/2015
[3] => 08/08/2015
[4] => 08/09/2015
[5] => 08/10/2015
[6] => 08/11/2015
[7] => 08/12/2015
[8] => 08/13/2015
[9] => 08/14/2015
[10] => 08/15/2015
[11] => 08/16/2015
[12] => 08/17/2015
[13] => 08/18/2015
[14] => 08/19/2015
[15] => 08/20/2015
[16] => 08/21/2015
[17] => 08/22/2015
[18] => 08/23/2015
[19] => 08/24/2015
[20] => 08/25/2015
[21] => 08/26/2015
[22] => 08/27/2015
[23] => 08/28/2015
[24] => 08/29/2015
[25] => 08/30/2015
[26] => 08/31/2015
)
[September] => Array
(
[0] => 09/01/2015
[1] => 09/02/2015
[2] => 09/03/2015
[3] => 09/04/2015
[4] => 09/05/2015
[5] => 09/06/2015
[6] => 09/07/2015
[7] => 09/08/2015
[8] => 09/09/2015
[9] => 09/10/2015
[10] => 09/11/2015
[11] => 09/12/2015
[12] => 09/13/2015
[13] => 09/14/2015
[14] => 09/15/2015
[15] => 09/16/2015
[16] => 09/17/2015
[17] => 09/18/2015
[18] => 09/19/2015
[19] => 09/20/2015
[20] => 09/21/2015
[21] => 09/22/2015
[22] => 09/23/2015
[23] => 09/24/2015
[24] => 09/25/2015
[25] => 09/26/2015
[26] => 09/27/2015
[27] => 09/28/2015
[28] => 09/29/2015
[29] => 09/30/2015
)
[October] => Array
(
[0] => 10/01/2015
[1] => 10/02/2015
[2] => 10/03/2015
[3] => 10/04/2015
[4] => 10/05/2015
[5] => 10/06/2015
[6] => 10/07/2015
[7] => 10/08/2015
[8] => 10/09/2015
[9] => 10/10/2015
[10] => 10/11/2015
[11] => 10/12/2015
[12] => 10/13/2015
[13] => 10/14/2015
[14] => 10/15/2015
[15] => 10/16/2015
[16] => 10/17/2015
)
)
Just to note: you specified that you wanted to break the result into three separate arrays. I assume the results will be dynamic - in which the number of months could vary - so I think you are better generating a multidimensional array of results.
In the example above I used the month names as keys. $date->format('F') returns a full textual representation of a month, such as January or March.
If you want to get a list of the months contained in the $months array you can just do:
print_r(array_keys($months));
Which returns the keys, and should give you enough information to access the data for your needs:
Array
(
[0] => August
[1] => September
[2] => October
)
Hope this helps :)

Find missing dates in range (php)

I would like to identify the missing dates in a PHP array
for example
this range
2013-06-12
2013-06-13
2013-06-26
2013-06-27
2013-06-29
has the following dates missing:
2013-06-14
2013-06-15
2013-06-16
...
2013-06-24
2013-06-25
2013-06-28
How can I identify the missing dates?
Here's a good way to get all missing dates in an array:
<?php
$myDates = array("2013-06-12", "2013-06-13", "2013-06-26", "2013-06-27", "2013-06-29");
$missingDates = array();
$dateStart = date_create("2013-06-01");
$dateEnd = date_create("2013-06-".date("t", mktime(0, 0, 0, 6, 1, 2013)));
$interval = new DateInterval('P1D');
$period = new DatePeriod($dateStart, $interval, $dateEnd);
foreach($period as $day) {
$formatted = $day->format("Y-m-d");
if(!in_array($formatted, $myDates)) $missingDates[] = $formatted;
}
print_r($missingDates);
?>
This will result in:
Array
(
[0] => 2013-06-01
[1] => 2013-06-02
[2] => 2013-06-03
[3] => 2013-06-04
[4] => 2013-06-05
[5] => 2013-06-06
[6] => 2013-06-07
[7] => 2013-06-08
[8] => 2013-06-09
[9] => 2013-06-10
[10] => 2013-06-11
[11] => 2013-06-14
[12] => 2013-06-15
[13] => 2013-06-16
[14] => 2013-06-17
[15] => 2013-06-18
[16] => 2013-06-19
[17] => 2013-06-20
[18] => 2013-06-21
[19] => 2013-06-22
[20] => 2013-06-23
[21] => 2013-06-24
[22] => 2013-06-25
[23] => 2013-06-28
[24] => 2013-06-30
)

Categories