I have an issue with my loops to show the result value - php

$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 ?

Related

Get week number for given month of year for presentation on calendar

I'm creating a calendar with Sunday being the start of each week and I want to present the week number of the year before each row of dates.
This is my calendar
my calendar
How can I add week numbers like this:
This is what I need
My code:
<?php
function generate_calendar($month, $year) {
$calendar = array();
$days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$first_day_of_month = date('w', strtotime("$year-$month-01"));
$week_number = 1;
$week = array();
// Determine the week number offset
$days_from_january_1st = strtotime("$year-01-01");
$days_to_first_day_of_month = strtotime("$year-$month-01");
$week_number_offset = floor(($days_to_first_day_of_month - $days_from_january_1st) / 604800);
// Check if the last week of the previous month is full (7 days)
$last_week_of_previous_month = $week_number_offset;
if ($month > 1) {
$previous_month = $month - 1;
$previous_month_year = $year;
$previous_month_year = date("Y", strtotime("-1 month" , strtotime("$year-$month-01")));
$previous_month = date("n", strtotime("-1 month" , strtotime("$year-$month-01")));
if ($previous_month == 0) {
$previous_month = 12;
$previous_month_year = $year - 1;
}
$days_in_previous_month = cal_days_in_month(CAL_GREGORIAN, $previous_month, $previous_month_year);
$last_day_of_previous_month = date('w', strtotime("$previous_month_year-$previous_month-$days_in_previous_month"));
if ($last_day_of_previous_month == 6) {
$last_week_of_previous_month=$last_week_of_previous_month + 1;
} else {
// Check if the last week of the previous month only has a few days
$last_week_of_previous_month = $last_week_of_previous_month;
}
}
// Generate the previous month's days
for ($i = 1; $i <= $first_day_of_month; $i++) {
array_unshift($week, "");
}
// Generate the current month's days
for ($i = 1; $i <= $days_in_month; $i++) {
$week[] = $i;
if (count($week) == 7) {
$calendar[$week_number + $last_week_of_previous_month] = $week;
$week_number++;
$week = array();
}
}
// Generate the next month's days
$remaining_days = 7 - count($week);
for ($i = 1; $i <= $remaining_days; $i++) {
$week[] = '';
}
if (!empty($week)) {
$calendar[$week_number + $last_week_of_previous_month] = $week;
}
return $calendar;
}
$year = 2022;
echo "<table>\n";
echo " <tr>\n";
echo " <th colspan='3'>$year</th>\n";
echo " </tr>\n";
echo " <tr>\n";
for($i=1; $i<=12; $i++){
$month_name = date('F Y', strtotime("$year-$i-01"));
$calendar = generate_calendar($i, $year);
echo "<td>\n";
echo "<table>\n";
echo " <tr>\n";
echo " <th colspan='8'>$month_name</th>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <th>Week</th>\n";
echo " <th>Sun</th>\n";
echo " <th>Mon</th>\n";
echo " <th>Tue</th>\n";
echo " <th>Wed</th>\n";
echo " <th>Thu</th>\n";
echo " <th>Fri</th>\n";
echo " <th>Sat</th>\n";
echo " </tr>\n";
foreach ($calendar as $week_number => $week) {
echo " <tr>\n";
echo " <td>$week_number</td>\n";
foreach ($week as $day) {
if (empty($day)) {
echo " <td></td>\n";
} else {
echo " <td>$day</td>\n";
}
}
echo " </tr>\n";
}
echo "</table>\n";
echo "</td>\n";
if($i==3 || $i==6 || $i==9){
echo " </tr>\n";
echo " <tr>\n";
}
}
echo " </tr>\n";
echo "</table>\n";
?>
Trying to add week number which counts from first week of January (if last week of previous month is not full 7 days then first week of current month start from last week of previous month), but my code only count from first week of current month.
I managed to get the right result (as far as I tested) with IntlCalendar and its FIELD_WEEK_OF_YEAR constant instead of counting Sundays.
I did some refactoring of your function, but ran out of time to do a full reduction of the script (there may still be lines that can be simplified/condensed).
Code: (Demo)
function generate_calendar(int $month, int $year) {
$calendar = [];
$week_number = (IntlCalendar::fromDateTime ("$year-$month-01"))->get(IntlCalendar::FIELD_WEEK_OF_YEAR);
$month_start = new DateTime("$year-$month-01");
// Generate the previous month's days
if ($first_day = $month_start->format('w')) {
$week = array_fill(1, $first_day, '');
}
// Generate the current month's days
$days_in_month = $month_start->format('t');
for ($i = 1; $i <= $days_in_month; $i++) {
$week[] = $i;
if (count($week) == 7) {
$calendar[$week_number] = $week;
$week_number++;
$week = [];
}
}
if ($week) {
// Generate empty days for the next month
$calendar[$week_number] = array_pad($week, 7, '');
}
return $calendar;
}
I don't believe there is any way to set the start day of the week in the standard library of PHP without manual calculation, but you can do it easily with the intl library (make sure the intl PHP extension is enabled):
$cal = IntlGregorianCalendar::createInstance();
// Set start of week to Sunday
$cal->setFirstDayOfWeek(IntlGregorianCalendar::DOW_SUNDAY);
// Get week number of the year for the current date
$weekOfYear = intval(IntlDateFormatter::formatObject($cal, 'w'));
// Advance to the next week
$cal->add(IntlGregorianCalendar::FIELD_WEEK_OF_YEAR, 1);
// ect...

Get missing date values from array in php dynamically

We are creating a system where employees need to update their daily status report. The fundamental purpose of the system is to note the missing dates on which they did not update the status report.
I have found a way to do that by checking the day difference between the 2 array values and then counting & displaying the days. However, I am not sure how to do this dynamically between the 2 array values.
Here's the code I have used along with the output:
//id of the person updating the DSR
$userid = $_id;
// Array to fetch all the DSR by specific user
$fine = getDSRbyUserIdOrderDate($userid);
$today = date('d-m-Y');
$tomorrow = date("d-m-Y", strtotime($today . " +1 day"));
$ok = count($fine) - 1;
//Array to get dates
$d1 = $fine[0]['date'];
$d2 = $fine[1]['date'];
$d3 = $fine[2]['date'];
// Function call to find date difference
$dateDiff = dateDiffInDays($d1, $d2);
$dateDiff1 = dateDiffInDays($d2, $d3);
echo "<h4 style='color:red'>You have missed the DSR on the following dates.</h4>";
for($p = 1; $p < $dateDiff; $p++){
$missingdate = date("d-m-Y", strtotime($d1 . " +$p day"));
echo "<span style='color:red'>$missingdate</span>";
echo "<br />";
}
for($p = 1; $p < $dateDiff1; $p++){
$missingdate = date("d-m-Y", strtotime($d2 . " +$p day"));
echo "<span style='color:red'>$missingdate</span>";
echo "<br />";
}
if($d2 != $today){
echo "<span style='color:red'>$today <i>- Kindly update DSR before midnight</i></span> ";
echo "<br />";
}
Output:
I would create first a list of entries by date and then "paint" it accordingly.
$starting_date = new DateTime('2019-11-23');
$num_days = 10
$from_db_by_date = [];
foreach ($fine as $entry) {
$from_db_by_date[$entry['date']] = $entry;
}
$all_by_date = [];
for ($i = 0; $i < $num_days; $i++) {
$date_str = $starting_date->format('d-m-Y');
$all_by_date[$date_str] = $from_db_by_date[$date_str] ?: null;
$starting_date->modify('+1 day');
}
Now you can loop through $all_by_date, check if the entry is null and act accordingly.

Amortization Script

I am trying to create an amortization calculator that calculates the declining principal
$x = 1;
$starting_pmt = 26;
$ending_pmt = 36;
$i = 0.0010316264327892;
$p = 410000;
$pmt = 916.84;
$num_pmts = $ending_pmt - $starting_pmt;
echo "<table border=\"1\" align=\"center\">";
echo "<tr><th>PMT Num</th>";
echo "<th>Balance</th>";
echo "<th>Principle</th>";
echo "<th>TTL Principle</th>";
echo "<th>Interest</th>";
echo "<th>Payment</th>";
echo "</tr>";
while ( $starting_pmt <= $ending_pmt ) {
echo "<tr><td>";
echo $starting_pmt;
echo "</td><td>";
echo $p;
echo "</td>";
echo "<td>$prin</td>";
echo "<td>$TTLprin</td>";
echo "<td>$interest</td>";
echo "<td>$TTLPmt</td> </tr>";
$starting_pmt = $starting_pmt + 1;
$p = $p -($p*$i);
$prin = $pmt - ($p * $i);
$interest = $pmt - $prin;
$TTLPmt = $prin + $interest;
//$cumTTL = $$pmt - ($p * $i);
$TTLprin = $prin + $prin;
}
echo "</table>";
?>
balance for each payment and the total principle paid between two values. I also want to calculate the interested paid for each payment and the accumulative interest paid between the two values.
This is what I am starting with.
I cannot figure out how to get the loop to do the math during each iteration............... I have been working my original code and I am getting closer. I cannot get the loop to calculate the cumulative total for principal and interest paid.
<?php
$starting_pmt = 1;
$ending_pmt = 10;
$i = 0.0010316264327892;
$p = 410000;
$pmt = 916.84;
$num_pmts = $ending_pmt - $starting_pmt;
while($x < $num_pmts) {
echo "<tr>";
echo "<td>$x</td>";
echo "<td>".$p - ($p*$i)."</td>";
echo "<td></td>";
echo "<td></td>";
echo "<tr>";
$x++;
I get the math. It's getting the while loop to do what I need. It's not calculating the cumulative total for the principle paid.
Here is a way to make an amortization script, you need to pass back what you want your rate, payment date, and all that good stuff. then I am returning an associative array with all the values for each month.
public static function amortizeLoan($principal, $rate, $term, $extra_days, $payment_date){
$payment = self::getPayment($principal,($rate*100),$term,$extra_days);
$MonthlyInterestRate = $rate / 12;
$Multiplier = 1 + $MonthlyInterestRate;
$TermRate = 1;
for($x=0;$x<$term;$x++){
$TermRate = $TermRate * $Multiplier;
}
$Days = $extra_days - 30;
$oddDayInt = $Days > 0 ? round($principal * ($rate / 365.25) * $Days,2) : 0;
$amortization = [];
$total_interest = 0;
$total_principal = 0;
$remaining_principal = $principal;
$compareDay = date('d', strtotime($payment_date));
for($x=0;$x<$term;$x++){
$this_int_paid = round((($rate)/12) * $remaining_principal,2);
if($x==0){$this_int_paid += $oddDayInt;}
$this_princ_paid = round($payment - $this_int_paid,2);
$this_rem_princ = round($remaining_principal - $this_princ_paid,2);
if($x == ($term-1)){
if($this_rem_princ < 0){
$this_princ_paid-=abs($this_rem_princ);
$payment=round($this_int_paid+$this_princ_paid,2);
}else{
$this_princ_paid+=$this_rem_princ;
$payment=round($this_int_paid+$this_princ_paid,2);
}
}
$remaining_principal -= $this_princ_paid;
$total_interest += $this_int_paid;
$total_principal += $this_princ_paid;
// *** If month days < payment date, payment date falls on the last day of that month.***
$nextMonth = strtotime("last day of next month", strtotime($payment_date));
$lastDayNextMonth = date('d', $nextMonth);
if ($compareDay >= $lastDayNextMonth) {
$payment_date_time = $x ? $nextMonth : strtotime($payment_date);
} else {
$payment_date_time = $x ? strtotime("+1 month", strtotime($payment_date)) : strtotime($payment_date);
}
if ($lastDayNextMonth > date('d', strtotime($payment_date)) && date('t', strtotime($payment_date)) < $compareDay) {
$date = date('Y-m-d', $nextMonth);
$newDate = date_create($date);
$newDate->format('Y-m-d');
$finalDate = date_date_set(
$newDate,
date_format($newDate, 'Y'),
date_format($newDate, 'm'),
$compareDay
);
$formatedDate = $finalDate->format('m/d/y');
$payment_date_time = strtotime($formatedDate);
}
$payment_date = gmdate("Y-m-d", $payment_date_time);
$amortization[] = [
"payment"=>($x+1),
"amount"=>$payment,
"principal"=>$this_princ_paid,
"interest"=>$this_int_paid,
"total_principal"=>$total_principal,
"total_interest"=>$total_interest,
"remaining_balance"=>round($remaining_principal,2),
"payment_date"=>$payment_date
];
}
return $amortization;
}

Extracting dates from date range

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>";
}

I want a PHP for loop that goes to certain number and again starts from zero

I want a PHP for loop that goes to certain number say "23" and again starts from "0".
Actually I want for the listing of time in 24 hours format and suppose a case is: I have to show time from 9 AM to 2 AM (i.e 9,10,11,12,13,14,...........23,0,1,2)
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
for ($i = $start_time ; $i<= $end_time ; $i++)
{
echo $i;
}
Please suggest a way.
Since your use-case mentions time-sensitive information you might be best off learning to use the date and strtotime functions (or the DateTime classes):
$time = strtotime('2013-09-14 02:00');
$endTime = strtotime('2013-09-15 09:00');
while ($time <= $endTime) {
echo date('Y-m-d H:i:s', $time)."\n";
$time = strtotime('+1 hour', $time);
}
// 2013-09-14 02:00:00
// 2013-09-14 03:00:00
// 2013-09-14 04:00:00
// 2013-09-14 05:00:00
// etc.
$start_time = 9;
$end_time = 2;
$end_time += ($end_time < $start_time) ? 24 : 0;
for ($i = $start_time; $i<= $end_time; $i++) {
echo ($i % 24);
}
Reason, the line $end_time += ($end_time < $start_time) ? 24 : 0; checks to see if the end time is less than the start time (which we assume means the next day), and if it is, it adds 24 hours to it. The line $i %24 is the modulus operator which will divide the number and give the remainder, so if it's 25, it will give you 1 back. Note that all hours being worked with will need to be in 24 hour format to use this method.
You can use the modulo to deduct 24 from numbers when they're greater than 23.
$start_time = 9;
$end_time = 2;
for( $i = $start_time; $i % 24 != $end_time; $i++ )
{
echo $i % 24;
}
Note that you need to be careful with this; if $end_time is greater than 23 it will be stuck in an infinite loop.
Try this its working
<?php
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
$max_value=23;
if($start_time>=$end_time)
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
for($i=0; $i<=$end_time; $i++)
{
echo $i;
}
}
else
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
}
?>
Again late to Answer , Try this
<?php
$start_time = 20;
$end_time = 10;
$maxTime=23;
$minTime=0;
for ($i = $minTime ; $i<=$maxTime - abs($start_time-$end_time) ; $i++)
{
$validTime= $start_time + ($i % $maxTime);
$validTime= $validTime>$maxTime?$validTime-$maxTime:$validTime;
echo $validTime;
}
?>
Check this out. Hope this helps
$start_time = 9;
$end_time = 2;
$flag = 1;
while($flag) [
echo $start_time . "<br>";
$start_time++;
if ($start_time == 23) { $start_time = 0; }
if ($start_time == $end_time) {
$flag = 0;
}
}
Does it have to be a for loop?
You can try this
function hours($range, $recurse = true, $end = array())
{
foreach($range as $time)
{
echo $time . "\n";
}
if($recurse && sizeof($end) > 0)
{
$range = range($end['start'], $end['end']);
hours($range, false);
}
}
$range = range(9,23);
$end = array('start' => 0, 'end' => 2);
hours($range, true, $end);
Maybe better to use date:
$hours = 8;
for ($i=1; $i<=8; $i++){
echo 'TIME1 = '.date("Y-m-d H:i:s",mktime (20+$i,15,18,06,05,2013)).'<br>';
}
or better DateTime class:
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2013-06-05 20:15:18');
$hours = 8;
for ($i=0; $i<8; $i++){
$date->add(new DateInterval('PT1H'));
echo 'TIME2 = '.$date->format('Y-m-d H:i:s').'<br>';
}
Thanks everybody for your help, using your ideas I got my work done.
Here is the code that actually worked.
$start_time = some_dynamic_value;
$end_time = some_dynamic_value;
$i= $start_time;
$flag = false;
if($start_time > $end_time)
$flag = true;
while ($i <= $end_time || $flag)
{
echo $i;
if($i == 24)
{
$i= 0;
$flag = false;
}
$i++;
}

Categories