Part of my answer was answered by dynamic:
How to extract every Monday and every fortnightly Monday from a range of two dates in PHP?
I've added a foreach loop to print all the mondays in this example:
$start = strtotime('2016-09-05');
$end = strtotime('2016-09-30');
$mondays=array();
$tuesdays=array();
while( $start <= $end ) {
if ( date('N',$start)==1 )
$mondays[]=$start;
$start += 86400;
}
foreach ($mondays as $item) {
print date("D. Y-m-d", ($item));
print ("<br>");
}
and i get these results:
enter image description here
But how do i add an else/if statements to display the tuesdays for example
if the date begins with $start = strtotime('2016-09-06');
I want it to show:
enter image description here
Thanks.
In this code, we first find the DayOfWeek, and then find all dof in range:
// Data
$StartDate = strtotime('2016-09-06');
$EndDate = strtotime('2016-09-30');
$DayOfWeek = date("l", $StartDate); // Determine day of week
$LoopDate = $StartDate;
// Find all DayOfWeek's Between Start and End
$Result = [$StartDate];
while (true) {
$NextDayOfWeek = strtotime("next " . $DayOfWeek, $LoopDate);
if ($NextDayOfWeek > $EndDate) {
break;
}
$Result[] = $LoopDate = $NextDayOfWeek;
}
// Print Result
/**
| 2016-09-06
| 2016-09-13
| 2016-09-20
| 2016-09-27
*/
foreach( $Result as $Row ) {
echo date("Y-m-d", $Row) . '<br/>';
}
In keeping with your current approach:
$start = strtotime('2016-09-05');
$end = strtotime('2016-09-30');
while($start <= $end) {
if(date("D", $start) == "Mon"){
$mondays[] = $start;
}
elseif(date("D", $start) == "Tue"){
$tuesdays[] = $start;
}
$start += 86400;
}
foreach ($mondays as $item){
echo date("D. Y-m-d", $item);
echo "<br>";
}
echo "<br>";
foreach ($tuesdays as $item){
echo date("D. Y-m-d", $item);
echo "<br>";
}
Related
I have project built using laravel and a I have to build a function that counts all the complete quarters that are in the selected date range - the dates used are inserted via input.
Here are the quarters(i used numerical representations for the months)
01 - 03 first quarter
04 - 06 second quarter
07 - 09 third quarter
10 - 12 forth quarter
I would really appreciate your help,because I've been at it for an entire day now and basically have nothing to show for it,i thing I've been trying so hard i'm actually at the point where i'm so tired, i can t think straight.
I do have some code but it;s worthless, because it doesn't work, and any kind of idea or snippet of code is welcomed.
Thanks for your help in advance.
I managed to do this using multiple functions; basically, if this is needed for chart statistics, then a more specific approach might be the case.
I have done this in Laravel with timestamp dates as input (this code can be adapted for getting semesters also :) , it works and is already tested):
public static function getQuartersBetween($start_ts, $end_ts)
{
$quarters = [];
$months_per_year = [];
$years = self::getYearsBetween($start_ts, $end_ts);
$months = self::getMonthsBetween($start_ts, $end_ts);
foreach ($years as $year) {
foreach ($months as $month) {
if ($year->format('Y') == $month->format('Y')) {
$months_per_year[$year->format('Y')][] = $month;
}
}
}
foreach ($months_per_year as $year => $months) {
$january = new Date('01-01-' . $year);
$march = new Date('01-03-' . $year);
$april = new Date('01-04-' . $year);
$june = new Date('01-06-' . $year);
$july = new Date('01-07-' . $year);
$september = new Date('01-09-' . $year);
$october = new Date('01-10-' . $year);
$december = new Date('01-12-' . $year);
if (in_array($january, $months) && in_array($march, $months)) {
$quarter_per_year['label'] = 'T1 / ' . $year;
$quarter_per_year['start_day'] = $january->startOfMonth();
$quarter_per_year['end_day'] = $march->endOfMonth()->endOfDay();
array_push($quarters, $quarter_per_year);
}
if (in_array($april, $months) && in_array($june, $months)) {
$quarter_per_year['label'] = 'T2 / ' . $year;
$quarter_per_year['start_day'] = $april->startOfMonth();
$quarter_per_year['end_day'] = $june->endOfMonth()->endOfDay();
array_push($quarters, $quarter_per_year);
}
if (in_array($july, $months) && in_array($september, $months)) {
$quarter_per_year['label'] = 'T3 / ' . $year;
$quarter_per_year['start_day'] = $july->startOfMonth();
$quarter_per_year['end_day'] = $september->endOfMonth()->endOfDay();
array_push($quarters, $quarter_per_year);
}
if (in_array($october, $months) && in_array($december, $months)) {
$quarter_per_year['label'] = 'T4 / ' . $year;
$quarter_per_year['start_day'] = $october->startOfMonth();
$quarter_per_year['end_day'] = $december->endOfMonth()->endOfDay();
array_push($quarters, $quarter_per_year);
}
}
return $quarters;
}
and getting the years between:
public static function getYearsBetween($start_ts, $end_ts, $full_period = false)
{
$return_data = [];
$current = mktime(0, 0, 0, date('m', $start_ts), date('d', $start_ts), date('Y', $start_ts));
while ($current < $end_ts) {
$temp_date = $current;
$year = new Date($temp_date);
$return_data[] = $year;
$current = strtotime("+1 year", $current); // add a year
}
if ($full_period) {
$return_data[] = $end_ts;
}
return $return_data;
}
, also getting the months needed
public static function getMonthsBetween($start_ts, $end_ts, $full_period = false)
{
$return_data = $month_list = [];
$current = mktime(0, 0, 0, date('m', $start_ts), date('d', $start_ts), date('Y', $start_ts));
while ($current <= $end_ts) {
$temp_date = $current;
$date = new Date($temp_date);
$month_list[] = $date;
$current = strtotime("+1 month", $current); // add a month
}
$start_date_last_month = new Date(array_first($month_list));
$start_date_last_month = $start_date_last_month->startOfMonth()->format('m-d');
$temp_end_date = new Date($start_ts);
$temp_end_date = $temp_end_date->format('m-d');
if ($start_date_last_month < $temp_end_date) {
array_shift($month_list);
}
$end_date_last_month = new Date(end($month_list));
$current_day_month = $end_date_last_month->endOfMonth()->format('m-d');
$temp_end_date = new Date($end_ts);
$end_day_of_month = $temp_end_date->format('m-d');
if ($end_day_of_month < $current_day_month) {
array_pop($month_list);
}
if (count($month_list) == 0) {
$month_list[] = $end_date_last_month->subMonth();
}
$return_data = $month_list;
if ($full_period) {
$return_data[] = $end_ts;
}
return $return_data;
}
You can do something like in this example:
$February = 2;
$October = 10;
$completedQuarters = ceil($October/3) - ceil($February/3); // = 3
What about the quarter in which the date range starts, should it also count? If it should only count if it begins in the first month of a quarter you can check for it like this:
$completedQuarters = ceil($October/3) - ceil($February/3) -1; // = 2
if($February-1%3 == 0) $completedQuarters += 1;
You´re description is not very clear, let me know if that´s what you had in mind.
Not sure if the following is what you are meaning but might be useful
$date_start='2015/03/12';
$date_end='2017/11/14';
$timezone=new DateTimeZone('Europe/London');
$start=new DateTime( $date_start, $timezone );
$end=new DateTime( $date_end, $timezone );
$difference = $end->diff( $start );
$months = ( ( $difference->format('%y') * 12 ) + $difference->format('%m') );
$quarters = intval( $months / 3 );
printf( 'Quarters between %s and %s is %d covering %d months', $start->format('l, jS F Y'), $end->format('l, jS F Y'), $quarters, $months );
/*
This will output
----------------
Quarters between Thursday, 12th March 2015 and Tuesday, 14th November 2017 is 10 covering 32 months
*/
Something like this in the function and you should be set.
use Carbon\Carbon;
$first = Carbon::parse('2012-1-1'); //first param
$second = Carbon::parse('2014-9-15'); //second param
$fY = $first->year; //2012
$fQ = $first->quarter; //1
$sY = $second->year; //2014
$sQ = $second->quarter; //3
$n = 0; //the number of quarters we have counted
$i = 0; //an iterator we will use to determine if we are in the first year
for ($y=$fY; $y < $sY; $y++, $i++) { //for each year less than the second year (if any)
$s = ($i > 0) ? 1 : $fQ; //determine the starting quarter
for ($q=$s; $q <= 4; $q++) { //for each quarter
$n++; //count it
}
}
if ($sY > $fY) { //if both dates are not in the same year
$n = $n + $sQ; //total is the number of quarters we've counted plus the second quarter value
} else {
for ($q=$fQ; $q <= $sQ; $q++) { //for each quarter between the first quarter and second
$n++; //count it
}
}
print $n; //the value to return (11)
Well, I have following code : It's return next all date base on given date until do-while loop end.
$paid = 2600;
$monthly = 700;
$x=0;
do {
$monthly;
$date = date('2016'.'-'.'05'.'-d');
$time = strtotime($date);
$bill_month = date("Y-m-d", strtotime("+$x month", $time));
echo "$bill_month => $monthly <br/>";
$paid -= $monthly;
if ($paid < $monthly) {
$monthly = $paid;
}
$x++;
} while ($paid > 0);
It's return following result :
2016-05-12 => 700
2016-06-12 => 700
2016-07-12 => 700
2016-08-12 => 500
And I have another array which is bellow :
$date_array = array("2016-05-12", "2016-07-12");
Now I want to show following date using above do-while loop :
2016-06-12
2016-08-12
2016-09-12
2016-10-12
I mean :
You know above do while loop return all next date until end the loop. for example : next 4 months from given date.
But I want to show next 4 months which is not exist in $date_array. That's mean these 4 months :
2016-06-12
2016-08-12
2016-09-12
2016-10-12
Simply check if generated is not in $date_array, if it is get next month:
$found = false;
while (!$found) {
$date = date('2016'.'-'.'05'.'-d');
$time = strtotime($date);
$bill_month = date("Y-m-d", strtotime("+$x month", $time));
$found = !in_array($bill_month,$date_array);
++$x;
}
echo "$bill_month => $monthly <br/>";
and remove ++$x at and of while loop
cleaner if
$bill_month = date("Y-m-d",strtotime(($x++) . " month"),$time));
Full example:
<?php
/**
*/
$paid = 2600;
$monthly = 700;
$date_array = array("2016-05-12", "2016-07-12");
$x=0;
do {
$found = false;
while (!$found) {
$date = date('2016'.'-'.'05'.'-d');
$time = strtotime($date);
$bill_month = date("Y-m-d", strtotime( ($x++)." month", $time));
$found = !in_array($bill_month,$date_array);
}
echo "$bill_month => $monthly <br/>\n";
$paid -= $monthly;
if ($paid < $monthly) {
$monthly = $paid;
}
} while ($paid > 0);
I have a date like this
$start = strtotime('2010-01-01'); $end = strtotime('2010-01-25');
My question:
How can I calculate or count weekend from $start & $end date range..??
A more modern approach is using php's DateTime class. Below, you get an array with week numbers as keys. I added the counts of weeks and weekend days.
<?php
$begin = new DateTime('2010-01-01');
$end = new DateTime('2010-01-25');
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval, $end);
$weekends = [];
foreach($daterange as $date) {
if (in_array($date->format('N'), [6,7])) {
$weekends[$date->format('W')][] = $date->format('Y-m-d');
}
}
print_r($weekends);
echo 'Number of weeks: ' . count($weekends);
echo 'Number of weekend days: ' . (count($weekends, COUNT_RECURSIVE) - count($weekends));
Note: if you're using PHP 5.3, use array() instead of block arrays [].
May be this code snippet will help:
<?php
//get current month for example
$beginday = date("Y-m-01");
$lastday = date("Y-m-t");
$nr_work_days = getWorkingDays($beginday, $lastday);
echo $nr_work_days;
function getWorkingDays($startDate, $endDate)
{
$begin = strtotime($startDate);
$end = strtotime($endDate);
if ($begin > $end) {
echo "startdate is in the future! <br />";
return 0;
} else {
$no_days = 0;
$weekends = 0;
while ($begin <= $end) {
$no_days++; // no of days in the given interval
$what_day = date("N", $begin);
if ($what_day > 5) { // 6 and 7 are weekend days
$weekends++;
};
$begin += 86400; // +1 day
};
$working_days = $no_days - $weekends;
return $working_days;
}
}
Another solution can be: (Get date range between two dates excluding weekends)
This might help maybe:
$start = strtotime('2010-01-01');
$end = strtotime('2010-01-25');
$differ = $end-$start;
$min = $differ/60;
$hrs = $min/60;
$days = $hrs/24;
$weeks = $days/7;
if(is_int($weeks))
$weeks++;
echo '<pre>';
print_r(ceil($weeks));
echo '</pre>';
I am working on a "cut-off" date and I need to set it on every month. Say, I set the cut-off date to August 25 for this year, then it should be September 25, October 25 and so on till the year ends.
Here's the code I have:
$now = "2015-08-25";
$nextDate = getCutoffDate($now);
echo $nextDate;
function getCutoffDate($start_date)
{
$date_array = explode("-",$start_date); // split the array
// var_dump($date_array);
$year = $date_array[0];
$month = $date_array[1];
$day = $date_array[2];
/*if (date('n', $now)==12)
{
return date("Y-m-d",strtotime(date("Y-m-d", $start_date) . "+1 month"));
}*/
if (date("d") <= $day) {
$billMonth = date_format(date_create(), 'm');
}
else{
$billMonth = date_format(date_modify(date_create(), 'first day of next month'), 'm');
}
// echo date("d").' '. $billMonth.'<br>';
$billMonthDays = cal_days_in_month(CAL_GREGORIAN, ($billMonth), date("Y"));
// echo $billMonthDays.'<br>';
if ($billMonthDays > $day) {
$billDay = $day;
} else {
$billDay = $billMonthDays;
}
}
I got this from here: http://www.midwesternmac.com/blogs/jeff-geerling/php-calculating-monthly
It returns the same date for the next month only, but how do I get the specific date of EACH month of the current year? Kindly leave your thoughts. Still a newbie here, sorry.
In that case, this should be enough:
<?php
for($i=8; $i<=12; $i++) {
echo sprintf('25-%02d-2015', $i) . '<br>';
}
but if you need more flexible way:
<?php
$date = new DateTime('25-08-2015');
function getCutoffDate($date) {
$days = cal_days_in_month(CAL_GREGORIAN, $date->format('n'), $date->format('Y'));
$date->add(new DateInterval('P' . $days .'D'));
return $date;
}
for($i = 0; $i < 5; $i++) {
$date = getCutoffDate($date);
echo $date->format('d-m-Y') . '<br>';
}
This should print:
25-09-2015
25-10-2015
25-11-2015
25-12-2015
25-01-2016
$array_of_time = array ();
$start_time = strtotime ("$app_date 07:00");
$end_time = strtotime ("$app_date 22:00");
$mins = 04 * 60;
while ($start_time <= $end_time)
{
$array_of_time[] = date ('h:i a', $start_time);
$start_time += $mins;
}
echo "<div style='width:700px' class='time_slot_div'>";
echo "<p class='time_slot_p'> Time Slot :</p>";
foreach($array_of_time as $key=>$value)
{
for($i = 0; $i < count($app_data); $i++)
{
$book_time=$app_data[$i]["appointment_time"];
if($value==$book_time)
{
echo "<a class='time_slot_a_book'>$value</a> ";
} else {
echo "<a href='#' onclick='get_time_value(\"$value\");' class='time_slot_a'>$value</a> ";
}
}
}
echo "</div>";
Here foreach loop can run as many time as it can as well as for loop also, but i want to show the links that are not matched with the foreach value and for loop value.
The foreach loop values like 7:20 am not from database but the for loop value like 7:20 am is from database so if 7:20 am==7:20 am then the if statement it run it is working fine, but the issue is that it is running 2 time if i get 2 value in for loop. It should run my div only once.
If took a tour of your site, I revise the copy:
$array_of_time = array ();
$start_time = strtotime ("$app_date 07:00");
$end_time = strtotime ("$app_date 22:00");
$mins = 04 * 60;
while ($start_time <= $end_time)
{
$array_of_time[] = date ('h:i a', $start_time);
$start_time += $mins;
}
echo "<div style='width:700px' class='time_slot_div'>";
echo "<p class='time_slot_p'> Time Slot :</p>";
foreach($array_of_time as $key=>$value)
{
//
// get the appointing state:
//
$bAppointed = false;
for($i = 0; $i < count($app_data); $i++)
{
$book_time = $app_data[$i]["appointment_time"];
$bAppointed = $value == $book_time;
if($bAppointed)
{
break;
}
}
//
// print the time slot:
//
if($bAppointed)
{
echo "<a class='time_slot_a_book'>$value</a> ";
} else {
echo "<a href='#' onclick='get_time_value(\"$value\");' class='time_slot_a'>$value</a> ";
}
}
echo "</div>";
?
Is it better ?