I don't know what are the errors of this code because it's suddenly not accurate the showing value to the user like this:
$holidays = array();
$query_holiday = "SELECT * FROM holiday_tbl";
$result = mysqli_query($dbcon, $query_holiday);
while($row_holiday = mysqli_fetch_assoc($result))
{
array_push($row_holiday, $holidays);
}
if(strtotime(date("Y-m-d")) > strtotime($row['due_date']))
{
$currentDate = date("Y-m-d");
$days = (strtotime($currentDate) - strtotime($row['due_date'])) / 86400;
$daysTemp = $days;
for($i=1;$i<$days;$i++)
{
$currentDay = date("D", strtotime("+ ".$i." days"));
$date_loop = date("Y-m-d", strtotime("+ ".$i." days"));
if($currentDay == "Sun" || $currentDay == "Sat")
{
$daysTemp--;
}
else if(in_array($date_loop, $holidays))
{
$daysTemp--;
}
}
echo $daysTemp;
}
The current implementation is rather convoluted. In these cases I find it's always better to start over and try to simplify the logic as much as possible. Here is my take on your problem:
function calculate_days_late($due_date = '', $holidays = array(), $current_date = 'today') {
$days_late = 0;
// Get the timestamps for due date and current date
$current_date_ts = strtotime($current_date);
$due_date_ts = strtotime($due_date);
// If current date is not after due date then not late
if ($current_date_ts <= $due_date_ts) {
return $days_late;
}
$loop_date_ts = $current_date_ts;
while ($loop_date_ts > $due_date_ts) {
// If the looping date is not a weekend or holiday then count it
if ( ! in_array(date('D', $loop_date_ts), array('Sat','Sun'))
&& ! in_array(date('Y-m-d', $loop_date_ts), $holidays)) {
$days_late++;
}
$loop_date_ts = strtotime('-1 day', $loop_date_ts);
}
return $days_late;
}
// Test
echo '2017-09-05 = ' . calculate_days_late('2017-09-05', array(), '2017-09-05') . "\n";
echo '2017-09-06 = ' . calculate_days_late('2017-09-05', array(), '2017-09-06') . "\n";
echo '2017-09-07 = ' . calculate_days_late('2017-09-05', array(), '2017-09-07') . "\n";
echo '2017-09-08 = ' . calculate_days_late('2017-09-05', array(), '2017-09-08') . "\n";
echo '2017-09-09 = ' . calculate_days_late('2017-09-05', array(), '2017-09-09') . "\n";
echo '2017-09-10 = ' . calculate_days_late('2017-09-05', array(), '2017-09-10') . "\n";
echo '2017-09-11 = ' . calculate_days_late('2017-09-05', array(), '2017-09-11') . "\n";
echo '2017-09-12 = ' . calculate_days_late('2017-09-05', array(), '2017-09-12') . "\n";
echo '2017-09-13 = ' . calculate_days_late('2017-09-05', array(), '2017-09-13') . "\n";
Working example: https://eval.in/856018
Related
I have a query which returns me some data.
//I loop through the query's result and write all data out
while($row =$result->fetch_assoc()){
echo $row['place'] . '|';
echo $row['gets_busy'] . '|';
echo $row['gets_empty '] . '|';
echo $row['time_between'] . '|';
echo "<br>";
}
ROOM01|2021-03-05 12:02:56|2021-03-05 12:04:02|00:01:06|
ROOM01|2021-03-05 12:05:42|2021-03-05 12:07:48|00:02:06|
ROOM01|2021-03-05 12:07:48|2021-03-05 12:12:54|00:05:06|
ROOM02|2021-03-05 12:15:54|2021-03-05 12:17:00|00:01:06|
ROOM02|2021-03-05 12:17:01|2021-03-05 12:23:17|00:05:16|
ROOM02|2021-03-05 12:23:59|2021-03-05 12:25:45|00:01:46|
I want something to write for the user like:
ROOM01 was busy for -> 00:08:18 during 2021-03-05
ROOM02 was busy for -> 00:08:08 during 2021-03-05
Can this be accomplished by PHP?
You can group into another array, by using the places and date as keys.
while($row = $result->fetch_assoc())
{
$place = $row['place']; // shortcut
$start = strtotime($row['gets_busy']); // start timestamp
$stop = strtotime($row['gets_empty']); // end timestamp
$time = $stop - $start; // duration in seconds
$date = date('Y-m-d', $start); // date for grouping
// group by place and date
if (!isset($data[$place][$date])) {
$data[$place][$date] = 0; // init with 0
}
$data[$place][$date] += $time; // add time.
}
// now, display data :
foreach ($data as $place => $dates) {
echo $place . ':<br>';
foreach ($dates as $date => $duration) {
$interval = new DateInterval('PT'.$duration.'S');
echo ' -> ' . $date . ' : ' . $interval->format('%h:%i:%s') . '<br>';
}
}
Question:
Is there something weird about date-time that would affect the assignment of a variable?
The situation:
From Controller I'm passing a variable $startDate and on the view assigning it to different variables $day1, $day2, etc etc. I go through a loop on $day1 and I modify the day to increment $day1 by 1 using $day1->modify("+1 day")
$day2 the loop (in the else portion) doesn't trigger because the value of $startDate is too high. however, it's value should be the same as $day1 before modification.
the Code:
The controller
public function appointmentSearch()
{
$counselor = $this->session->userdata('idUser');
if($this->input->post('SearchAppointments'))
{
$fromDate = $_POST['fromDate'];
$fromTimeSlot = $this->Admin_model->TimeConversion($_POST['fromTime']);
$toDate = $_POST['toDate'];
$toTimeSlot = $this->Admin_model->TimeConversion($_POST['toTime']);
$theStart = new DateTime($fromDate);
$theEnd = new DateTime($toDate);
$difference = $theEnd->diff($theStart);
$dayCount = $difference->d;
$timeCount = (int)$toTimeSlot-(int)$fromTimeSlot;
$data['schedule'] = true;
$data['days'] = $dayCount;
$data['slots'] = $timeCount;
$data['dayStart'] = $theStart;
$data['dayEnd'] = $theEnd;
$data['slotStart'] = $fromTimeSlot;
$data['slotEnd'] = $toTimeSlot;
$data['r1Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,1);
$data['r2Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,2);
$data['r3Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,3);
$data['r4Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,4);
$data['r5Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,5);
$data['r6Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,6);
$data['r7Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,7);
$data['r8Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,8);
$data['r9Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,9);
$data['r10Data'] = $this->Admin_model->GetOpenApptTimes($fromDate,$fromTimeSlot,$toDate,$toTimeSlot,10);
$this->load->view('admin/scheduler',$data);
}
}
The View:
<?php
if($schedule == true)
{ //if false we have search results
//classes for the form
$attributes = array('class' => 'row');
//normal attributtes for the time slots if they are blacked out
$subAttUnav = array('class' => 'btn btn-secondary btn-sm');
// if the used time slot is someone they can ask to move
$subAttMove = array('class' => 'btn btn-secondary btn-sm', 'style' => 'background:darkgrey;');
// it's wide open
$subAttOpen = array('class' => 'btn btn-secondary btn-sm');
if(count($r1Data) >= 1)
{ //room 1 has appoints scheduled during the time frame queried
echo '<div class="row" style="width:70%;margin:0 auto;"><h3 class="highlight">Room 1</h3>';
$day1 = $dayStart;
while($day1 <= $dayEnd)
{
$day1format = $day1->format('Y-m-d-H-i-s');
$dayArray = explode('-',$day1format);
for($i = 0;$i <= $slots; $i++)
{
$timeslot = $slotStart + $i;
$label = 'Book: ' . $timeslot . ':00 on ' . $dayArray[1] . '/' . $dayArray[2] . ' ';
foreach($r1Data as $index)
{
$row = explode('-',$index);
//var_dump($row);
$thisDay = $dayArray[0] . '/' . $dayArray[1] . '/' . $dayArray[2];
//echo '$thisDay =' . $thisDay . '</br>';
$apptDay = $row[6] . '/' . $row[7] . '/' . $row[8];
//echo '$apptDay =' . $apptDay . '</br>';
//echo '$timeslot =' . $timeslot . '</br>';
//echo '$row[9] =' . $row[9] . '</br>';
if($thisDay == $apptDay && $timeslot == (int)$row[9])
{ // the appointment date and timeslot matches current slide
echo '<div class="btn btn-secondary btn-sm m-1" style="background:black;" title="Time unavailable">' . $label . '</div>';
}
else
{
echo form_open('AdminForms/booking/' . $dayArray[0] . '/' . $dayArray[1] . '/' . $dayArray[2] . '/' . $timeslot . '/1', $attributes);
echo form_submit("Book",$label,$subAttOpen);
echo form_close();
}
}
}
$placeholder = $day1->modify('+1 day');
$day1 = $placeholder;
}
echo '</div><!-- End of Room 1 data -->';
}
else
{ // no results on query the time frame is wide open
echo '<div class="row" style="width:70%;margin:0 auto;"><h3 class="highlight">Room 1</h3>';
$day1 = $dayStart;
while($day1 <= $dayEnd)
{
$day1format = $day1->format('Y-m-d-H-i-s');
$dayArray = explode('-',$day1format);
for($i = 0;$i <= $slots; $i++)
{
$timeslot = $slotStart + $i;
$label = 'Book: ' . $timeslot . ':00 on ' . $dayArray[1] . '/' . $dayArray[2] . ' ';
echo form_open('AdminForms/booking/' . $dayArray[0] . '/' . $dayArray[1] . '/' . $dayArray[2] . '/' . $timeslot . '/1', $attributes);
echo form_submit("Book",$label,$subAttOpen);
echo form_close();
}
$placeholder = $day1->modify('+1 day');
$day1 = $placeholder;
}
echo '</div><!-- End of Room 1 data -->';
var_dump($dayStart);
}
if(count($r2Data) >= 1)
{ //room 1 has appoints scheduled during the time frame queried
echo '<div class="row" style="width:70%;margin:0 auto;"><h3 class="highlight">Room 2</h3>';
$day2 = $dayStart;
while($day2 <= $dayEnd)
{
$day2format = $day2->format('Y-m-d-H-i-s');
$day2Array = explode('-',$day2format);
for($i = 0;$i <= $slots; $i++)
{
$timeslot = $slotStart + $i;
$label = 'Book: ' . $timeslot . ':00 on ' . $day2Array[1] . '/' . $day2Array[2] . ' ';
foreach($r2Data as $index)
{
$row = explode('-',$index);
//var_dump($row);
$thisDay = $day2Array[0] . '/' . $day2Array[1] . '/' . $day2Array[2];
//echo '$thisDay =' . $thisDay . '</br>';
$apptDay = $row[6] . '/' . $row[7] . '/' . $row[8];
//echo '$apptDay =' . $apptDay . '</br>';
//echo '$timeslot =' . $timeslot . '</br>';
//echo '$row[9] =' . $row[9] . '</br>';
if($thisDay == $apptDay && $timeslot == (int)$row[9])
{ // the appointment date and timeslot matches current slide
echo '<div class="btn btn-secondary btn-sm m-1" style="background:black;" title="Time unavailable">' . $label . '</div>';
}
else
{
echo form_open('AdminForms/booking/' . $day2Array[0] . '/' . $day2Array[1] . '/' . $day2Array[2] . '/' . $timeslot . '/1', $attributes);
echo form_submit("Book",$label,$subAttOpen);
echo form_close();
}
}
}
$placeholder2 = $day2->modify('+1 day');
$day2 = $placeholder2;
}
echo '</div<!-- End of Room 2 data -->';
}
else
{ // no results on query the time frame is wide open
echo '<div class="row" style="width:70%;margin:0 auto;"><h3 class="highlight">Room 2</h3>';
$day2 = $startDate;
while($day2 <= $dayEnd)
{
$day2format = $day2->format('Y-m-d-H-i-s');
$day2Array = explode('-',$day2format);
for($i = 0;$i <= $slots; $i++)
{
$timeslot = $slotStart + $i;
$label = 'Book: ' . $timeslot . ':00 on ' . $day2Array[1] . '/' . $day2Array[2] . ' ';
echo form_open('AdminForms/booking/' . $day2Array[0] . '/' . $day2Array[1] . '/' . $day2Array[2] . '/' . $timeslot . '/1', $attributes);
echo form_submit("Book",$label,$subAttOpen);
echo form_close();
}
$placeholder2 = $day2->modify('+1 day');
$day2 = $placeholder2;
}
echo '</div><!-- End of Room 2 data -->';
}
So what i am trying to do is for the function to return a string like this
January 19-20, 2018
the variables all i have are the initial date and the number of nights. Too bad there's no way to getDate or getYear like js. Thanks for the help
You can use this custom function:
function showDates($startDate, $nights) {
$d1=new DateTime($startDate);
$d2 = new DateTime($startDate);
$d2->add(new DateInterval("P10D"));
if ($d2->format('Y') == $d1->format('Y')) {
$year = $d1->format('Y');
} else {
$year = $d1->format('Y') . '-' . $d2->format('Y');
}
if ($d2->format('m') == $d1->format('m')) {
$month = $d1->format('F');
} else {
$month = $d1->format('F') . '-' . $d2->format('F');
}
if ($d2->format('d') == $d1->format('d')) {
$day = $d1->format('d');
} else {
$day = $d1->format('d') . '-' . $d2->format('d');
}
return $month . ' ' . $day . ' ' . $year;
}
echo showDates("2017-10-05 12:00:00", 3);
I am using XMLReader to import huge xml file by elements to MySQL database. Xml contains 1 547 772 tags (element) named 'RECORD'.
XML example
<?xml version="1.0" encoding="utf-8"?>
<RECORD><NAME>ДОШКІЛЬНИЙ НАВЧАЛЬНИЙ ЗАКЛАД №1 ЗАГАЛЬНОГО РОЗВИТКУ УЖГОРОДСЬКОЇ МІСЬКОЇ РАДИ ЗАКАРПАТСЬКОЇ ОБЛАСТІ</NAME><SHORT_NAME>ДНЗ №1</SHORT_NAME><EDRPOU>34888585</EDRPOU><ADDRESS>88000, Закарпатська обл., місто Ужгород, ВУЛИЦЯ М.ВОВЧКА, будинок 47, "А"</ADDRESS><BOSS>НАКОНЕЧНА ОЛЕНА АНАТОЛІЇВНА</BOSS><KVED>85.10 Дошкільна освіта</KVED><STAN>зареєстровано</STAN><FOUNDERS><FOUNDER>УПРАВЛІННЯ ОСВІТИ УЖГОРОДСЬКОЇ МІСЬКОЇ РАДИ, розмір внеску до статутного фонду - 0.00 грн.</FOUNDER>...</FOUNDERS></RECORD>...
For MySQL connection use
function connectBase(){
include __DIR__ . '/../../settings/sql.set.php';
$mysql = mysqli_connect($_sqlhost, $_sqluser, $_sqlpass, $_sqldb);
mysqli_query($mysql, "Set charset utf8");
mysqli_query($mysql, "Set character_set_client = utf8");
mysqli_query($mysql, "Set character_set_connection = utf8");
mysqli_query($mysql, "Set character_set_results = utf8");
mysqli_query($mysql, "Set collation_connection = utf8_general_ci");
return $mysql;
}
Main function for parsing
function XMLReaderToDB($setting = false)
{
$mysql = connectBase();
$dir = __DIR__ . '/../../tmp/';
$xmlURL = $dir . $setting['file'];
$xml = new XMLReader();
$xml->open($xmlURL);
$start_time = time();
$start = $setting['start'];
$limit = $setting['limit'];
$stop = $start + $limit;
$i = 0;
$count = 0;
$result = 1;
while($xml->read())
{
if ($xml->nodeType == XMLReader::ELEMENT && $xml->name == $setting['tag']) {
$item[] = "('items', '" . mysqli_real_escape_string($mysql, $xml->readOuterXML()) . "')";
}
if ($xml->nodeType == XMLReader::END_ELEMENT && $xml->name == $setting['tag']) {
$i++;
$count++;
if ($count >= 500) {
insertXMLtoDB($mysql, $item);
$item = array();
$count = 0;
}
}
if($i == $stop){
break;
}
}
$xml->close();
insertXMLtoDB($mysql, $item);
$mysql->close();
$end_time = time();
$time_elapsed_secs = $end_time - $start_time;
echo '<br/>Items: ' . $i . '<br/>';
echo 'Start: ' . date('H:i:s', $start_time) . '<br/>';
echo 'End: ' . date('H:i:s', $end_time) . '<br/>';
echo $time_elapsed_secs . ' sec. (' . ($time_elapsed_secs /60) . ' min.)';
die;
}
And for MySQL insert
function insertXMLtoDB($mysql, $data = false){
mysqli_query($mysql,"INSERT INTO _parse_tmp (parse_key, parse_value) VALUES " . implode(", ", $data));
$data = array();
// echo 'Success';
}
But, MySQL requests don't stop after 1 547 772 inserts and "while" continues to run. I notice if uncommenting echo 'Success'; in insertXMLtoDB function, "while" is stopping at 1 547 772 inserts and finishing correctly.
What is wrong in my functions?
I've never personally used XMLReader however, I'd assume you could try to add another condition to your statement such as while($xml->read() && $i != $stop) opposed to having it within your loop directly. Ah also just noticed after your usage of the function insertXMLtoDB you re-declare $data although you'll notice you set it to NULL every time your call the function, therefore setting it to an array is pointless.
I can't understand why the script doesn't work fine. That's why I decided to change it.
function XMLReaderToDB($setting = false)
{
$mysql = connectBase();
$dir = __DIR__ . '/../../tmp/';
$xmlURL = $dir . $setting['file'];
$xml = new XMLReader();
$xml->open($xmlURL);
$start_time = time();
$start = $setting['start'];
$limit = $setting['limit'];
$stop = $start + $limit;
$i = 0;
$count = 0;
while (($valid = $xml->read()) && $xml->name !== $setting['tag']) ;
while ($valid) {
$i++;
$count++;
$item[] = "('" . $setting['type'] . "', '" . mysqli_real_escape_string($mysql, $xml->readOuterXML()) . "')";
if ($count == 500) {
insertXMLtoDB($mysql, $item);
$item = array();
$count = 0;
}
$valid = $xml->next($setting['tag']);
}
$xml->close();
insertXMLtoDB($mysql, $item);
$mysql->close();
$end_time = time();
$time_elapsed_secs = $end_time - $start_time;
echo '<br/>Items: ' . $i . '<br/>';
echo 'Start: ' . date('H:i:s', $start_time) . '<br/>';
echo 'End: ' . date('H:i:s', $end_time) . '<br/>';
echo $time_elapsed_secs . ' sec. (' . ($time_elapsed_secs /60) . ' min.)';
return;
}
The code works perfect, but since I'm repeating myself (which I like to avoid while programming), I was wondering if this could be written any shorter/better?
$start = getLocaleDate($item[0]['start_day']);
$start = $start['day_int'] . ' ' . $start['month_string'];
if ($item[0]['start_houre'] !== '00:00:00') {
$houre = stripLeadingZero(substr($item[0]['start_houre'], 0, 2));
$minute = substr($item[0]['start_houre'], 3, 2);
$start .= ' at' . $houre . 'u' . $minute;
}
$end = getLocaleDate($item[0]['end_day']);
$end = $end['day_int'] . ' ' . $end['month_string'];
if ($item[0]['end_houre'] !== '00:00:00') {
$houre = stripLeadingZero(substr($item[0]['end_houre'], 0, 2));
$minute = substr($item[0]['end_houre'], 3, 2);
$end .= ' at' . $houre . 'u' . $minute;
}
Without changing any of the functionality, you could make it into a function:
function getTime($item, $which) {
$time = getLocaleDate($item[0][$which . '_day']);
$time = $time['day_int'] . ' ' . $time['month_string'];
if ($item[0][$which . '_houre'] !== '00:00:00') {
$houre = stripLeadingZero(substr($item[0][$which . '_houre'], 0, 2));
$minute = substr($item[0][$which . '_houre'], 3, 2);
$time .= ' at' . $houre . 'u' . $minute;
}
return $time;
}
$start = getTime($item, 'start');
$end = getTime($item, 'end');
* It should be noted that this code doesn't do any error checking/prevention though, so if there is no index 0 in the $item, you will have an error (same goes for $item[0]['start_day'], $item[0]['end_day'], etc). To handle a simple-case, you could add if (!isset($item[0])) return ''; to the beginning of the function, if it's a concern.
sure could you can write a function where you pass in your item and the key to use
function your_function($item, $key) {
$h = $item[$key.'_houre'];
$time = getLocaleDate($item[$key. '_day']);
$time = $end['day_int'] . ' ' . $end['month_string'];
if ($h !== '00:00:00') {
$houre = stripLeadingZero(substr($h , 0, 2));
$minute = substr($h , 3, 2);
$time .= ' at' . $houre . 'u' . $minute;
return $time;
}
}
your_function($item[0], 'end');
your_function($item[0], 'start');