How to get all months between two dates in PHP? - php

I have 2 dates. I want to get all months with total days in each.
How can I do this in PHP?
For example
$date1 = '2013-11-13'; // yy-mm-dd format
$date2 = '2014-02-14';
Output
Months Total Days
-----------------------
11-2013 30
12-2013 31
01-2014 31
02-2014 28

Just try with:
$date1 = '2013-11-15';
$date2 = '2014-02-15';
$output = [];
$time = strtotime($date1);
$last = date('m-Y', strtotime($date2));
do {
$month = date('m-Y', $time);
$total = date('t', $time);
$output[] = [
'month' => $month,
'total' => $total,
];
$time = strtotime('+1 month', $time);
} while ($month != $last);
var_dump($output);
Output:
array (size=4)
0 =>
array (size=2)
'month' => string '11-2013' (length=7)
'total' => string '30' (length=2)
1 =>
array (size=2)
'month' => string '12-2013' (length=7)
'total' => string '31' (length=2)
2 =>
array (size=2)
'month' => string '01-2014' (length=7)
'total' => string '31' (length=2)
3 =>
array (size=2)
'month' => string '02-2014' (length=7)
'total' => string '28' (length=2)

Try the below given code :
$date1 = '2013-11-15'; // yy-mm-dd format
$date2 = '2014-02-15';
$start = new DateTime($date1);
$start->modify('first day of this month');
$end = new DateTime($date2);
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") ." " ;
echo cal_days_in_month(CAL_GREGORIAN,$dt->format("m"),$dt->format("Y")) . "<br/>";
}
Also, checkout this link for more

i used timestamp and date:
$date1 = '2013-11-15'; // yy-mm-dd format
$date2 = '2014-02-15';
$d1 = strtotime('2013-11-15');
$d2 = strtotime('2014-02-15');
while ($d1 <= $d2) {
echo date('m-d-Y', $d1)." | ";
echo cal_days_in_month(CAL_GREGORIAN, date('m', $d1), date('Y', $d1)) ."<br>";
$d1 = strtotime("+1 month", $d1);
}

This should help you, Check out,
$date1 = new DateTime('2013-11-15');
$date1->modify('first day of this month');
$date2 = new DateTime('2014-02-15');
$date2->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$value = new DatePeriod($date1, $interval, $date2);
foreach ($value as $dates) {
echo $dates->format("m- Y")."-->".cal_days_in_month(0,$dates->format("m"),$dates->format("Y"))."<br>\n";
}

This is what i came up with:
$arr_months = array();
$date1 = new DateTime('2013-11-15');
$date2 = new DateTime('2014-02-15');
$month1 = new DateTime($date1->format('Y-m')); //The first day of the month of date 1
while ($month1 < $date2) { //Check if the first day of the next month is still before date 2
$arr_months[$month1->format('Y-m')] = cal_days_in_month(CAL_GREGORIAN, $month1->format('m'), $month1->format('Y')); //Add it to the array
$month1->modify('+1 month'); //Add one month and repeat
}
print_r($arr_months);
It creates an associative array with the month as key and the number of days as value.
The array created from the example would be:
Array
(
[2013-11] => 30
[2013-12] => 31
[2014-01] => 31
[2014-02] => 28
)
With a foreach loop you will be able to scroll trough the array easily.

You can use the DateTime class along with cal_day_in_month() like this
$datetime1 = "2014-02-15";
$datetime2= "2013-03-15";
$date1 = new DateTime($datetime1);
$date2 = new DateTime($datetime2);
while (date_format($date2, 'Y-m') <= date_format($date1, 'Y-m'))
{
$date2 = $date2->add(new DateInterval('P1M'));
echo $date2->format('Y-m')." | ".cal_days_in_month(CAL_GREGORIAN, $date2->format('m'), $date2->format('Y'))."<br>";
}

Related

PHP - Date range by month

I have a date range and I need it to group by month but I want to keep starting day and ending day. So far I have this:
$interval['from'] = '2017-01-02 00:00:00';
$interval['to'] = '2017-02-06 23:59:59';
$start = Carbon::createFromFormat('Y-m-d H:i:s', $interval['from'])->startOfMonth();
$end = Carbon::createFromFormat('Y-m-d H:i:s', $interval['to'])->startOfMonth()->addMonth();
$separate = CarbonInterval::month();
$period = new \DatePeriod($start, $separate, $end);
foreach ($period as $dt) {
dump($dt);
}
But as result I'm getting:
Carbon\Carbon(3) {
date => "2017-01-01 00:00:00.000000" (26)
timezone_type => 3
timezone => "Europe/Prague" (13)
}
Carbon\Carbon(3) {
date => "2017-02-01 00:00:00.000000" (26)
timezone_type => 3
timezone => "Europe/Prague" (13)
}
It is grouped by month but I need to get whole month period, I mean from
2017-01-02 00:00:00 to 2017-01-31 23:59:59
2017-02-01 00:00:00 to 2017-02-06 23:59:59.
Output:
$array = [
0 => [
'from' => '2017-01-02 00:00:00',
'to' => '2017-01-31 23:59:59'
],
1 => [
'from' => '2017-02-01 00:00:00',
'to' => '2017-02-06 23:59:59'
]
];
What is the easiest way to achive it?
Edit: Here is a little bit modified Carbon version of accepted answer, maybe somebody will need it:
$interval['from'] = '2017-01-02 00:00:00';
$interval['to'] = '2017-04-08 23:59:59';
$interval_from = Carbon::createFromFormat('Y-m-d H:i:s', $interval['from']);
$interval_to = Carbon::createFromFormat('Y-m-d H:i:s', $interval['to']);
$result = [];
foreach (range($interval_from->month, $interval_to->month) as $x) {
$to = $interval_from->copy()->endOfMonth();
if ($x == $interval_to->month) {
$result[] = ["from" => $interval_from, "to" => $interval_to];
} else {
$result[] = ["from" => $interval_from, "to" => $to];
}
$interval_from = $to->copy()->addSecond();
}
PHP code demo
Try this solution you can change from one month to another month(not year) and then check. Lengthy solution but hopefully works correctly, putting explaination.
<?php
ini_set('display_errors', 1);
$from=$interval['from'] = '2017-01-02 00:00:00';
$interval['to'] = '2017-03-07 23:59:59';
$month1=date("m", strtotime($interval['from']));
$month2=date("m", strtotime($interval['to']));
$result=array();
foreach(range($month1, $month2) as $x)
{
$dateTimeObj= new DateTime($from);
$dayDifference=($dateTimeObj->format('d')-1);
$dateTimeObj= new DateTime($from);
$dateTimeObj->add(new DateInterval("P1M"));
$dateTimeObj->sub(new DateInterval("P".$dayDifference."DT1S"));
$to= $dateTimeObj->format("Y-m-d H:i:s");
if($x==$month2)
{
$dateTimeObj= new DateTime($interval['to']);
$noOfDays=$dateTimeObj->format("d");
$dateTimeObj->sub(new DateInterval("P".($noOfDays-1)."D"));
$from=$dateTimeObj->format("Y-m-d H:i:s");
$result[]=array("from"=>$from,"to"=>$interval['to']);
}
else
{
$result[]=array("from"=>$from,"to"=>$to);
}
//adding 1 second to $to for next time to be treated as $from
$dateTimeObj= new DateTime($to);
$dateTimeObj->add(new DateInterval("PT1S"));
$from= $dateTimeObj->format("Y-m-d H:i:s");
}
print_r($result);

How To Remove Duplicate Elements from array after merging with another array in php?

I am trying to Write Program for Calculating Next 20 dates After Specifying Start date, then from 20 dates i have Exclude Weekends & Holidays(Array holidays('2016-12-13',2016-12-24)) And Result Array which includes only Working Days Excluding Saturday & Sunday, from this Result Array after Passing Holiday array(Eg:- holidays('2016-12-13',2016-12-24))), it must be Excluded from result array. i:e;
I want Expected Output Below mentioned
.
<?php
$Date=array('2016-12-01');
echo "\n <br />Start Date:-" . $Date[0] . "";
/*Code For Generating Next 20 Dates Starts*/
//$start = strtotime($s_row['schedule_start_date']);
$start = strtotime('2016-12-01');
$dates=array();
for($i = 0; $i<20; $i++)
{
array_push($dates,date('Y-m-d', strtotime("+$i day", $start)));
}
echo "\n <br /> Array Of next 20 Days/dates of Given:-";
print_r($dates);
$start=array();
$start=$dates; /*Code For Generating Next 20 Dates Ends*/
$result=array();
$start = strtotime(array_values($Date)[0]);
//$end = strtotime(array_values($Date)[30]);
$result = array();
$begin = new DateTime( '2016-12-01' );
$end = new DateTime( '' );
//$end = $end->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date)
{
//echo $date->format("Y-m-d") . "<br>";
if (date('N', $start) <= 5) /* 'N' number days 1 (mon) to 7 (sun) */
/*5 weekday */
{
$current = date('Y-m-d', $start); //m/d/Y
$result[$current] = '';
}
$start += 86400;
//echo "Days Without Sat Sun".$result[date($date->format("Y-m-d"))];
//echo "Days Without Sat Sun".$result2[date($current->format("Y-m-d"))];
}
echo " \n <br /> Dates Without Weekends LIKE (Excluding Saturday & Sunday):-";
print_r($result);
/*For Holiday*/
$FinalArray = array();
$holidays = array(
'2016-12-13',
'2016-12-24',
);
echo " \n <br /> Given Holiday Dates Are:-";
print_r($holidays);
$a1 = $result;
$a2 = $holidays;
$array = array_diff(array_merge($a1,$a2),array_intersect($a1,$a2));
echo "\n <br /> Output:-";
print_r($array);
?>
it Gives Output as :- Array ( [2016-12-01] => [2016-12-02] => [2016-12-05] => [2016-12-06] => [2016-12-07] => [2016-12-08] => [2016-12-09] => [2016-12-12] => [2016-12-13] => [2016-12-14] => [2016-12-15] => [2016-12-16] => [2016-12-19] => [2016-12-20] => [2016-12-21] => [2016-12-22] => [2016-12-23] => [0] => 2016-12-13 [1] => 2016-12-24 )
> But I Want Expected Output:-
Array ( [2016-12-01] => [2016-12-02] => [2016-12-05] => [2016-12-06] => [2016-12-07] => [2016-12-08] => [2016-12-09] => [2016-12-12] => [2016-12-14] => [2016-12-15] => [2016-12-16] => [2016-12-19] => [2016-12-20] => [2016-12-21] => [2016-12-22] => [2016-12-23]
You Can Notice That 2016-12-13 is Not There in Above Expected Output as in '2016-12-13', 2016-12-24 is passed as Holiday via holiday array ($holidays = array( '2016-12-13', '2016-12-24', );) i:e; if i pass any date through holidays array it should not be included in result Array(). i:e 2016-12-13 is Available in Result array as well as holiday array So While while printing Final OUTPUT:- 13th date(2016-12-13) Should not be Included in final Output. Anybody Solve this will be Appreciated Thanks in Advance.
When I have to remove duplicates from a array the function that I keep going back to is
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
you can find the documentation Here
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
the output
Array
(
[a] => green
[0] => red
[1] => blue
)
I hope that this was able to help
I prefer to calculate all dates just in one pass. (You may skip filling $dates and $dates_mon_fri arrays if they doesn't used in output also.) There is yet another approach to avoid array_diff() and array_unique() functions. I've used an array_flip() to exchange keys with values in $holdidays array to use fast array_key_exists() function.
<?php
$start = strtotime('2016-12-01');
$holidays = [
'2016-12-13',
'2016-12-24',
];
$dates = [];
$dates_mon_fri = [];
$dates_working = [];
$flip_holidays = array_flip($holidays);
for ($i = 0; $i < 20; $i++) {
$timestamp = strtotime("+$i day", $start);
$date = date('Y-m-d', $timestamp);
$dates[] = $date;
$mon_fri = false;
if (date('N', $timestamp) <= 5) {
$dates_mon_fri[] = $date;
$mon_fri = true;
}
if ($mon_fri && !array_key_exists($date, $flip_holidays)) {
$dates_working[] = $date;
}
}
var_dump($dates);
var_dump($dates_mon_fri);
var_dump($dates_working);
You can avoid using explicit looping:
$begin = new DateTimeImmutable('2016-12-01');
$end = $begin->modify('+20 days');
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval, $end);
$allDates = iterator_to_array($daterange);
$datesExcludingWeekends = array_filter($allDates, function ($date) {
return (int) $date->format("N") < 6;
});
$datesExcludingWeekends = array_map(
'date_format',
$datesExcludingWeekends,
array_fill(1, count($datesExcludingWeekends), 'Y-m-d')
);
$holidays = [
'2016-12-13',
'2016-12-24',
];
$datesExcludingWeekendsIncludingHolidays = array_flip(array_merge(
$datesExcludingWeekends,
array_diff($holidays, $datesExcludingWeekends)
));
Here is working demo.
Also, take a look at the Carbon library. If you need some exhaustive working with dates this library can really ease your life.

Grouping dates into Months in php

Created the make time below to display biweekly dates
<?php
$date1 = "07/05/2013";
$date2 = date('M j, Y', strtotime($date1 . " + 14 day"));
$date3 = date('M j, Y', strtotime($date2 . " + 14 day"));
$date4 = date('M j, Y', strtotime($date3 . " + 14 day"));
$date5 = date('M j, Y', strtotime($date4 . " + 14 day"));
$date6 = date('M j, Y', strtotime($date5 . " + 14 day"));
$date7 = date('M j, Y', strtotime($date6 . " + 14 day"));
$date8 = date('M j, Y', strtotime($date7 . " + 14 day"));
$date9 = date('M j, Y', strtotime($date8 . " + 14 day"));
$date10 = date('M j, Y', strtotime($date9 . " + 14 day"));
$date11 = date('M j, Y', strtotime($date10 . " + 14 day"));
$date12 = date('M j, Y', strtotime($date11 . " + 14 day"));
$date13 = date('M j, Y', strtotime($date12 . " + 14 day"));
$date14 = date('M j, Y', strtotime($date13 . " + 14 day"));
$date15 = date('M j, Y', strtotime($date14 . " + 14 day"));
$date16 = date('M j, Y', strtotime($date15 . " + 14 day"));
$date17 = date('M j, Y', strtotime($date16 . " + 14 day"));
$date18 = date('M j, Y', strtotime($date17 . " + 14 day"));
?>
How can I get it to group together by Month? Let say I want to know how many dates land in August, or December. Also if I wanted to get how many dates till end of the year? Helping hand will be greatly appreciated.
I wasn't sure exactly what you meant about grouping by months
but this will use use an array to declare all the dates and you can change the $limit variable to increase or decrease the amount of dates.
change $dates to adjust your original date
$left is how many days are left in the array (it triggers after the first day is hit, can be changed to trigger on the last day)
and $amount is how many dates are in august
<?php
$limit = 17;
$dates = array("07-05-2013");
for ($i=1; $i<=$limit; $i++){
$dates[$i]=date('d-m-Y', strtotime($dates[$i-1] . "+ 14 days"));
}
foreach (array_keys($dates) as $key){
$value = date('m', strtotime($dates[$key]));
if ($value == "08"){
$amount = $amount + 1;
}
if ($amount == 1){
$left = $limit-$key;
}
}
print_r ($dates);
echo "<br>";
echo $amount . "<br>" . $left;
?>
Try this:
<?php
// initiate months
$month_arr = Array();
for ($i=1; $i<=12; $i++){
// no. of dates
$month_arr[$i] = 0;
}
$date_arr = Array();
$date_start = "07/05/2013";
$date_arr[] = date('M j, Y', strtotime($date_start));
for ($i=1; $i<=17; $i++){
$date_temp = date('M j, Y', strtotime($date_arr[$i-1] . " + 14 day"));
$month = date('n', strtotime($date_temp));
$month_arr[$month] += 1;
$date_arr[] = $date_temp;
}
foreach ($month_arr as $k => $v){
echo "<BR>Month: " . $k . ", No. of dates: " . $v;
}
// all dates
echo "<BR>All dates<BR>";
var_dump ($date_arr);
?>
You can extend this logic to group the actual dates by months rather than getting only the count of dates in a month. This is the solution for that:
<?php
// initiate months
$month_arr = Array(
'January' => Array('num_dates'=>0, 'dates'=>Array()) ,
'February' => Array('num_dates'=>0, 'dates'=>Array()),
'March' => Array('num_dates'=>0, 'dates'=>Array()),
'April' => Array('num_dates'=>0, 'dates'=>Array()),
'May' => Array('num_dates'=>0, 'dates'=>Array()),
'June' => Array('num_dates'=>0, 'dates'=>Array()),
'July' => Array('num_dates'=>0, 'dates'=>Array()),
'August' => Array('num_dates'=>0, 'dates'=>Array()),
'September' => Array('num_dates'=>0, 'dates'=>Array()),
'October' => Array('num_dates'=>0, 'dates'=>Array()),
'November' => Array('num_dates'=>0, 'dates'=>Array()),
'December' => Array('num_dates'=>0, 'dates'=>Array())
);
$date_arr = Array();
$date_start = "07/05/2013";
$date_arr[] = date('M j, Y', strtotime($date_start));
for ($i=1; $i<=17; $i++){
$date_temp = date('M j, Y', strtotime($date_arr[$i-1] . " + 14 day"));
$month = date('F', strtotime($date_temp));
$month_arr[$month]['dates'][] = $date_temp;
$month_arr[$month]['num_dates'] += 1;
$date_arr[] = $date_temp;
}
foreach ($month_arr as $k => $v){
if (!empty($v)){
if ($v['num_dates'] != 0){
echo "<BR><BR>Month: " . $k;
echo "<BR>No. of dates: " . $v['num_dates'];
foreach ($v['dates'] as $k1=>$v1){
echo "<BR>" . $v1;
}
}
}
}
?>
At this point, $month_arr should have everything you need.
just add an if statement and increment through all 12 months ... if the months are the same
$n=1;
$month=array();//dumpyour dates in an array
$date=array()
while($k<30){
if (date('n', strtotime($date[$k]))==date('n', strtotime($date[$k-1])){
echo $date[$k++];
$m = date('n', strtotime($date[$k]));
$month[$m]=++$n;
}
else{
.....
}
}
As I keep re-iterating on SO, PHP's DateTime classes make most datetime operations trivial.
Your question is not 100% clear, but from your comments it seems you want an array of timestamps, 14 days apart sectioned by month. I don't know if you considered that the months may cross year bondaries, but I took that into consideration in my answer.
The code below should do what you want:-
$start = \DateTime::createFromFormat('d/m/Y', '07/05/2013');
$interval = new \DateInterval('P14D');
$periods = new \DatePeriod($start, $interval, 26);
$dates = array();
foreach($periods as $day){
/** #var \DateTime $day */
$dates[$day->format('Y')][$day->format('M')][] = $day->getTimestamp();
}
var_dump($dates);
Output:-
array (size=2)
2013 =>
array (size=8)
'May' =>
array (size=2)
0 => int 1367936286
1 => int 1369145886
'Jun' =>
array (size=2)
0 => int 1370355486
1 => int 1371565086
'Jul' =>
array (size=3)
0 => int 1372774686
1 => int 1373984286
2 => int 1375193886
'Aug' =>
array (size=2)
0 => int 1376403486
1 => int 1377613086
'Sep' =>
array (size=2)
0 => int 1378822686
1 => int 1380032286
'Oct' =>
array (size=2)
0 => int 1381241886
1 => int 1382451486
'Nov' =>
array (size=2)
0 => int 1383664686
1 => int 1384874286
'Dec' =>
array (size=3)
0 => int 1386083886
1 => int 1387293486
2 => int 1388503086
2014 =>
array (size=5)
'Jan' =>
array (size=2)
0 => int 1389712686
1 => int 1390922286
'Feb' =>
array (size=2)
0 => int 1392131886
1 => int 1393341486
'Mar' =>
array (size=2)
0 => int 1394551086
1 => int 1395760686
'Apr' =>
array (size=2)
0 => int 1396966686
1 => int 1398176286
'May' =>
array (size=1)
0 => int 1399385886
I would recommend that, instead of an array of timestamps, you have an array of DateTime objects instead, then you can manipulate each one as you wish. In which case, the code would look like this:-
$start = \DateTime::createFromFormat('d/m/Y', '07/05/2013');
$interval = new \DateInterval('P14D');
$periods = new \DatePeriod($start, $interval, 26);
$dates = array();
foreach($periods as $day){
/** #var \DateTime $day */
$dates[$day->format('Y')][$day->format('M')][] = $day;
}
$months=array("1","2","3","4","5","6","7","8","9","10","11","12");
$years=array('2010','20111','2012','2013','2014','2015','2016','2017','2018');
$dates = array('2015-04-24','2015-04-28','2017-03-24', '2017-03-24', '2017-04-07', '2017-04-14', '2017-04-21', '2017-04-28');
$result=array();
foreach ($months as $mn) {
foreach ($years as $year) {
$r=array();
foreach ($dates as $month) {
if(date_parse_from_format("Y.n.j", $year)
["year"]==date_parse_from_format("Y.n.j", $month)["year"] &&
date_parse_from_format("Y.n.j", $month)["month"]==$mn){$r[]=$month;}
;}
if(empty($r)){;}else{$result[]=$r;};
;}
;};
var_dump($result);
this code should work, and it will segment according to year and month, please add more years to the $years variable as needed and your dates to the $dates array, note that duplicate values will be eliminated and if you prefer to keep duplicates just add a random letter to the end of each date when you insert it into an array as a key and then delete the extra letter when processing is finished.

CakePHP Date Array

$dts = new DateTime(AppController::getSetting('event_start'));
$dtf = new DateTime(AppController::getSetting('event_finish'));
//CONTROLLER
...
$weekdays = array(0,1,2,3,4,5,6);
$dates = array();
$today = strtotime(date("Y-m-d", $dts->getTimestamp()));
$end_date = strtotime(date("Y-m-d", $dtf->getTimestamp()));
while($today <= $end_date)
{
$weekday = date("w", $today);
if (in_array($weekday, $weekdays))
{
array_push($dates, date("Y-m-d", $today));
}
$today += 86400;
}
$this->set('dates', $dates);
...
//VIEW
...
echo $this->Form->input('date', array('options'=> $dates));
...
dts and dtf are a start and finish date I get from my database...
When I select a date from my drop box in my view, it submits ok but all i get in my database is 0000-00-00?
What am I doing wrong here?
EDIT
My array out puts this with
Debugger::dump($dates);
array(
(int) 0 => '2013-04-01',
(int) 1 => '2013-04-02',
(int) 2 => '2013-04-03',
(int) 3 => '2013-04-04',
(int) 4 => '2013-04-05',
(int) 5 => '2013-04-06',
(int) 6 => '2013-04-07'
)
EDIT
This is what my query looks like
INSERT INTO cake.tickets (first_name, last_name, email, phone, date, quantity) VALUES ('brbt', 'trbb', 'ver#fvef.com', 765657, //THIS IS THE DATE//2, 2).
It seems to only input the key?
Make your keys and your values the same. The key is what is saved, the value is what is seen by the user.
$dates = array();
$today = strtotime(date("Y-m-d", $dts->getTimestamp()));
$end_date = strtotime(date("Y-m-d", $dtf->getTimestamp()));
while($today <= $end_date)
{
$weekday = date("w", $today);
if (in_array($weekday, $weekdays))
{
$dates[date("Y-m-d", $today)] = date("Y-m-d", $today);
}
$today += 86400;
}
$this->set('dates', $dates);
Your date array should now look something like this:
array(
'2013-04-01' => '2013-04-01',
'2013-04-02' => '2013-04-02',
'2013-04-03' => '2013-04-03',
'2013-04-04' => '2013-04-04',
'2013-04-05' => '2013-04-05',
'2013-04-06' => '2013-04-06',
'2013-04-07'=> '2013-04-07'
)
Which will generate the proper select options.

php function for get all mondays within date range

Example:
$startDate is Monday 2007-02-05 and $endDate is Tuesday 2007-02-20. Then I want it to list:
Monday 2007-02-05
Monday 2007-02-12
Monday 2007-02-19
I looked at the PHP manual and found this to get all the days between two dates. But how to do it the way i want? PHP Code:
Rather than get all days and loop through them all, get the first Monday after the start date and then iterate 7 days at a time:
$endDate = strtotime($endDate);
for($i = strtotime('Monday', strtotime($startDate)); $i <= $endDate; $i = strtotime('+1 week', $i))
echo date('l Y-m-d', $i);
I needed the same and created a simple method.
public function getMondaysInRange($dateFromString, $dateToString)
{
$dateFrom = new \DateTime($dateFromString);
$dateTo = new \DateTime($dateToString);
$dates = [];
if ($dateFrom > $dateTo) {
return $dates;
}
if (1 != $dateFrom->format('N')) {
$dateFrom->modify('next monday');
}
while ($dateFrom <= $dateTo) {
$dates[] = $dateFrom->format('Y-m-d');
$dateFrom->modify('+1 week');
}
return $dates;
}
Then use it.
$dateFromString = '2007-02-05';
$dateToString = '2007-02-20';
var_dump($this->getMondaysInRange($dateFromString, $dateToString));
Result:
array (size=3)
0 => string '2007-02-05' (length=10)
1 => string '2007-02-12' (length=10)
2 => string '2007-02-19' (length=10)
Maybe it will be helpful for somebody.
You can use below function to get a array of dates between a date range of specific day.
You have to input start date, end date and day number in number.The day number is as follow.
1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday. 5 = Friday, 6 = Saturday, 7 = Sunday.
function getDateForSpecificDayBetweenDates($startDate,$endDate,$day_number){
$endDate = strtotime($endDate);
$days=array('1'=>'Monday','2' => 'Tuesday','3' => 'Wednesday','4'=>'Thursday','5' =>'Friday','6' => 'Saturday','7'=>'Sunday');
for($i = strtotime($days[$day_number], strtotime($startDate)); $i <= $endDate; $i = strtotime('+1 week', $i))
$date_array[]=date('Y-m-d',$i);
return $date_array;
}
for ($i = strtotime($startDate); $i <= strtotime($endDate); $i = strtotime('+1 day', $i)) {
if (date('N', $i) == 1) //Monday == 1
echo date('l Y-m-d', $i); //prints the date only if it's a Monday
}
i Create A class, You get All Days In range Date Group By Name of Day:
class DayHelper{
const MONDAY = 'Mon';
const TUESDAY = 'Tue';
const WEDENSDAY = 'Wed';
const THURSDAY = 'Thu';
const FRIDAY = 'Fri';
const SATURDAY = 'Sat';
const SUNDAY = 'Sun';
public function GetYeardays($dateStart, $dateend){
$period = new \DatePeriod(
new \DateTime($dateStart), new \DateInterval('P1D'), (new \DateTime($dateend))
);
$dates = iterator_to_array($period);
$arrayreturn = array();
foreach ($dates as $val) {
$date = $val->format('Y-m-d'); //format date
$get_name = date('l', strtotime($date)); //get week day
$day_name = substr($get_name, 0, 3); // Trim day name to 3 chars
switch ($day_name) {
case self::MONDAY:
$MONDAY[] = $date;
$arrayreturn[self::MONDAY] = $MONDAY;
break;
case self::TUESDAY:
$TUESDAY[] = $date;
$arrayreturn[self::TUESDAY] = $TUESDAY;
break;
case self::WEDENSDAY:
$WEDENSDAY[] = $date;
$arrayreturn[self::WEDENSDAY] = $WEDENSDAY;
break;
case self::THURSDAY:
$THURSDAY[] = $date;
$arrayreturn[self::THURSDAY] = $THURSDAY;
break;
case self::FRIDAY:
$FRIDAY[] = $date;
$arrayreturn[self::FRIDAY] = $FRIDAY;
break;
case self::SATURDAY:
$SATURDAY[] = $date;
$arrayreturn[self::SATURDAY] = $SATURDAY;
break;
case self::SUNDAY:
$SUNDAY[] = $date;
$arrayreturn[self::SUNDAY] = $SUNDAY;
break;
}
}
return $arrayreturn;
}
}
The Output will be like this
array (size=7)
'Fri' =>
array (size=5)
0 => string '2016/01/01' (length=10)
1 => string '2016/01/08' (length=10)
2 => string '2016/01/15' (length=10)
3 => string '2016/01/22' (length=10)
4 => string '2016/01/29' (length=10)
'Sat' =>
array (size=5)
0 => string '2016/01/02' (length=10)
1 => string '2016/01/09' (length=10)
2 => string '2016/01/16' (length=10)
3 => string '2016/01/23' (length=10)
4 => string '2016/01/30' (length=10)
'Sun' =>
array (size=4)
0 => string '2016/01/03' (length=10)
1 => string '2016/01/10' (length=10)
2 => string '2016/01/17' (length=10)
3 => string '2016/01/24' (length=10)
'Mon' =>
array (size=4)
0 => string '2016/01/04' (length=10)
1 => string '2016/01/11' (length=10)
2 => string '2016/01/18' (length=10)
3 => string '2016/01/25' (length=10)
'Tue' =>
array (size=4)
0 => string '2016/01/05' (length=10)
1 => string '2016/01/12' (length=10)
2 => string '2016/01/19' (length=10)
3 => string '2016/01/26' (length=10)
'Wed' =>
array (size=4)
0 => string '2016/01/06' (length=10)
1 => string '2016/01/13' (length=10)
2 => string '2016/01/20' (length=10)
3 => string '2016/01/27' (length=10)
'Thu' =>
array (size=4)
0 => string '2016/01/07' (length=10)
1 => string '2016/01/14' (length=10)
2 => string '2016/01/21' (length=10)
3 => string '2016/01/28' (length=10)
I made some changes to response https://stackoverflow.com/a/37300272/6871295
Then I can get the days between dates for any day and return format.
public function getWeekDayInRange($weekday, $dateFromString, $dateToString, $format = 'Y-m-d')
{
$dateFrom = new \DateTime($dateFromString);
$dateTo = new \DateTime($dateToString);
$dates = [];
if ($dateFrom > $dateTo) {
return $dates;
}
if (date('N', strtotime($weekday)) != $dateFrom->format('N')) {
$dateFrom->modify("next $weekday");
}
while ($dateFrom <= $dateTo) {
$dates[] = $dateFrom->format($format);
$dateFrom->modify('+1 week');
}
return $dates;
}
This is code for fetching the weekday of "$startdate" and counting the number of weekdays between two dates.
`$startdate` = '2015-03-01';
`$endate` = '2015-03-31';
`$recurringDay` = date('N', strtotime($startdate)); // recurring Day from date i.e monday = 1, Tuesday = 2 ...etc
$begin = new DateTime(`$startdate`);
$end = new DateTime(date('Y-m-d',strtotime('+1 day', strtotime($endate))));
while($begin format('Y-m-d');
$day[] = $begin->format('N');
$begin->modify('+1 day');
}
$c=0; // counter starts
foreach($day as $key=>$dt) {
if ($dt==`$recurringDay`) // compare it
{
$k[] = $key;
$c++;
}
}
`$nofDays` = $c; // number of mondays , tuesday
foreach($k as $pp) {
//adding session code
`$recurringDatetime[]` = $period[$pp]; // recurring dates
}
print_r(`$recurringDatetime`); // array of dates of monday, tuesday ..etc
$dates = array();
$dates[] = strtotime($start);
for($i = 0; $i <= 12; $i++){
$dates[] = strtotime('+1 week', $dates[$i]);
}
foreach($dates as $date){ echo date("d.m.Y", $date); }
I had similar issue and courses can start on any day. This script picks starting day and collect next days every week until the wanted amount (12 in this case).
Convert $startDate and $endDate before that to timestamps:
foreach ($date = $startDate; $date <= $endDate; $date += 60 * 60 * 24) {
if (strftime('%w', $date) == 1) {
$mondays[] = strftime('%A %Y-%m-%d', $date);
}
}
simply you can add as,
$date_from = "2007-02-05";
$date_from = strtotime($date_from);
$date_to="2007-02-20";
$date_to = strtotime($date_to);
for ($i=$date_from; $i<=$date_to; $i+=86400) {
$day = date("Y-m-d", $i);
$unixTimestamp = strtotime($day);
$dayOfWeek = date("l", $unixTimestamp);
if ($dayOfWeek == "Monday") {
echo $day ."is a". $dayOfWeek;
}
}//end for

Categories