Calculeted time adding together in php (H:i:s) - php

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

Related

Why can't get the value of weekend in php

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

Foreach loop "Group By" Key in PHP Array

I am so close to figuring this out, this is using Wordpress and Gravity Forms Plugin:
<?php
$form_id = '1'; // The registration form's ID
$entries = GFAPI::get_entries( $form_id ); // Get all entries
$html = "<table class='ent'>"; // Create an HTML table
$html .= "<tr><th>Name</th><th>Organization</th><th>Event</th><th>Date</th><th>Number Attending</th></tr>";
$list = array(); // Array to store the original fields
$used = array(); // Array to stored the "used" fields
// Loop through array of entries,each element
foreach($entries as $entry){
// Get datepart from datetime of event and today's date
$date = date_format(new DateTime($entry['8']), 'Y-m-d');
$today = date("Y-m-d");
// Compare event's date with current date
if ( $date >= $today ) {
$list[] = $entry;
if (!empty($used[$entry['6']])) // If used[event name] not null then sum associated numattend
{
$used[$entry['6']] += $entry['5'];
}
else // return associated numattend
{
$used[$entry['6']] = $entry['5'];
}
}
}
unset($entry);
foreach ($used as $key => $value) {
foreach ($list as $key1 => $value1) {
$html .= "<tr><td>" . $value1['1'] . " " . $value1['2'] . "</td><td>" . $value1['93'] . "</td><td>" . $value1['6'] . "</td><td>" . $value1['8'] . "</td><td>" . $value1['5'] . "</td></tr>";
}
$html .= "<tr class='ent_sum_rw'><td>" . " " . "</td><td>" . " " . "</td><td>" . " " . "</td><td class='ent_sum'>" . "Total Attending:" . "</td><td>" . $value . "</td></tr>";
}
unset($value);
$html .= "</table>";
return $html;
?>
Result:
I want the loop to end the entry list on the corresponding "Event Name", Like "Test Event 22" should not show up on the top entry list.
The trick is to populate an Array that meets your demands and after that convert it to html. I haven't tested the code, but it should be clear how it works.
$aEventList = Array();
foreach($entries as $entry){
if (!isset($aEventList[$entry['7']])){ //7 is id of event
//if this event is not made, create it and add name and the date, enter the right numeral
$aEventList[$entry['7']]['name'] = $entry['6'];
$aEventList[$entry['7']]['date'] = $entry['90'];
$aEventList[$entry['7']]['users'] = Array();
}
$aEventList[$entry['7']]['users'][] = Array('name' => $entry['1'] . ' '. $entry['2'],
'org' => $entry['93'],
'num' => $entry['5']);
}
//now you've populated every event and you can loop through it on your desired way:
foreach ($aEventList as $iEvent => $aEvent){
echo $aEvent['name']; //event name
echo $aEvent['date']; // event date
foreach ($aEvent['users'] as $aEventUser){
echo $aEventUser['name']; // user name
echo $aEventUser['org']; // user organisation
echo $aEventUser['num']; // num attendees
}
}

php next occurring date with relative day time

I'm trying to find the next epoch date from a relative day/time (work shift).
foreach($shift->meta_value as $shift_day) {
$start_string = $shift_day['day'] . ' ' . $shift_day['start_hour'] . ':' . $shift_day['start_min'] . $shift_day['start_meridian'];
$showStart[$shift->post_id] = date('U', strtotime($start_string));
$end_string = $shift_day['day'] . ' ' . $shift_day['end_hour'] . ':' . $shift_day['end_min'] . $shift_day['end_meridian'];
$showEnd[$shift->post_id] = date('U', strtotime($end_string));
}
asort($showEnd);
$end = array();
foreach ($showEnd as $key => $val) {
if (date("U", $val) > date("U")) {
$end[$key] = $val;
}
asort($end);
If the day/time has already passed, it needs to find the next occurrence of it. When sorting the 'end' array, it's not giving me the correct value. Any ideas?

retrieve data based on date range using mysql ,php

I am working on WPF where I have two datepickers when I try to retrieve the information on date range it displays only one record on all dates(same record displaying multiple times eg : date chosen from 01/10/2013 - 3/10/2013) where I have 3 different records on each day but my output is the first record displayed 3 times with same date and time.
function cpWhitelistStats() {
$startDate = $_POST['startDate'];
$startDateTime = "$startDate 00:00:00";
$endDate = $_POST['endDate'];
$endDateTime = "$endDate 23:59:59";
$cpId = $_POST['id'];
$cpName = etCommonCpNameById($cpId);
print "<h2 style=\"text-align: center;\">Permitted Vehicle Summary</h2>";
print "<h2 style=\"text-align: center;\">for $cpName</h2>";
$tmpDate = explode("/", $startDate);
$startYear = $tmpDate[2];
$startMonth= $tmpDate[1];
$startDay = $tmpDate[0];
$tmpDate = explode("/", $endDate);
$endYear = $tmpDate[2];
$endMonth= $tmpDate[1];
$endDay = $tmpDate[0];
$startDateTime = "$startYear-$startMonth-$startDay 00:00:00";
$endDateTime = "$endYear-$endMonth-$endDay 23:59:59";
$custId = $_SESSION['customerID'];
$realCustomerId = $_SESSION['realCustomerId'];
$maxVal = 0;
if ($custId != "") {
$conn = &newEtConn($custId);
// Get the whitelist plates
$staticWhitelistArray = etCommonMkWhitelist($conn, $cpId);
array_shift($staticWhitelistArray);
$startLoopDate = strtotime($startDateTime);
$endLoopDate = strtotime($endDateTime);
$oneDay = 60 * 60 * 24;
// Get the entries
$plateList = array_keys($staticWhitelistArray);
$plate_lookup = implode('","', $plateList);
$sql = "SELECT plate, entry_datetime, exit_datetime FROM stats WHERE plate IN (\"$plate_lookup\") AND entry_datetime > \"$startDateTime\" AND entry_datetime < \"$endDateTime\" AND carpark_id=\"$cpId\" ";
$result = $conn->Execute($sql);
if (!$result) {
print $conn->ErrorMsg();
exit;
}
$rows = $result->fields;
if ($rows != "") {
unset($myArray);
foreach($result as $values) {
$plate = $values['plate'];
$new_platelist[] = $plate;
$inDateTime = $values['entry_datetime'];
$outDateTime = $values['exit_datetime'];
$tmp = explode(' ', $inDateTime);
$inDate = $tmp[0];
$in_ts = strtotime($inDateTime);
$out_ts = strtotime($outDateTime);
$duration = $out_ts - $in_ts;
$dur_array = intToDateArray($duration);
$dur_string = '';
if ($dur_array['days'] > 0) {
$dur_string .= $dur_array['days'] . ' days ';
}
if ($dur_array['hours'] > 0) {
$dur_string .= $dur_array['hours'] . ' hours ';
}
if ($dur_array['mins'] > 0) {
$dur_string .= $dur_array['mins'] . ' minutes ';
}
if ($dur_array['secs'] > 0) {
$dur_string .= $dur_array['secs'] . ' secs ';
}
$myArray[$plate][] = array($inDateTime, $outDateTime, $inDate, $dur_string);
}
}
while ($startLoopDate < $endLoopDate) {
$dayString = strftime("%a, %d %B %Y", $startLoopDate);
$dayCheck = strftime("%Y-%m-%d", $startLoopDate);
print "<h2>$dayString</h2>";
print "<table width=\"100%\">";
print " <tr>";
print " <th>VRM</th>";
print " <th>Permit Group</th>";
print " <th>Entry Time</th>";
print " <th>Exit Time</th>";
print " <th>Duration</th>";
print " </tr>";
foreach($new_platelist as $wlPlate) {
if ($myArray[$wlPlate][0][2] == $dayCheck) {
print "<tr>";
print "<td>$wlPlate</td>";
if (isset($myArray[$wlPlate])) {
print "<td>".$staticWhitelistArray[$wlPlate]['groupname']."</td>";
print "<td>".$myArray[$wlPlate][0][0]."</td>";
print "<td>".$myArray[$wlPlate][0][1]."</td>";
print "<td>".$myArray[$wlPlate][0][3]."</td>";
}
else {
print "<td>Vehicle Not Seen</td>";
print "<td>Vehicle Not Seen</td>";
print "<td>Vehicle Not Seen</td>";
}
print "</tr>";
}
}
print "</table>";
$startLoopDate = $startLoopDate + $oneDay;
}
}
}
Can you echo this query so we can see what's actually being sent...
$sql = "
SELECT plate
, entry_datetime
, exit_datetime
FROM stats
WHERE plate IN ('$plate_lookup')
AND entry_datetime BETWEEN '$startDateTime' AND '$endDateTime'
AND carpark_id= '$cpId';
";
(This isn't an answer, but I wanted to make use of the additional formatting options)

Adding time-zones based on state and country into MYSQL table

I have a mysql table with data like (name, address, sex, city state, zip, country, timezone) When a user fills in the form to add this data, i would like the relevant time-zone to be added based on state and country, how can i do this?
Thanks,
Why not have the following select box in your form?
$list = DateTimeZone::listAbbreviations();
$idents = DateTimeZone::listIdentifiers();
$data = $offset = $added = array();
foreach ($list as $abbr => $info) {
foreach ($info as $zone) {
if ( ! empty($zone['timezone_id'])
AND
! in_array($zone['timezone_id'], $added)
AND
in_array($zone['timezone_id'], $idents)) {
$z = new DateTimeZone($zone['timezone_id']);
$c = new DateTime(null, $z);
$zone['time'] = $c->format('H:i a');
$data[] = $zone;
$offset[] = $z->getOffset($c);
$added[] = $zone['timezone_id'];
}
}
}
array_multisort($added, SORT_ASC, $data);
$options = array();
foreach ($data as $key => $row) {
$options[$row['timezone_id']] = $row['time'] . ' - '
. formatOffset($row['offset'])
. ' ' . $row['timezone_id'];
$values[$row['timezone_id']] = $row['time'] . '/'
. formatOffset($row['offset'])
. '/' . $row['timezone_id'];
}
function formatOffset($offset) {
$hours = $offset / 3600;
$remainder = $offset % 3600;
$sign = $hours > 0 ? '+' : '-';
$hour = (int) abs($hours);
$minutes = (int) abs($remainder / 60);
if ($hour == 0 AND $minutes == 0) {
$sign = ' ';
}
return 'GMT' . $sign . str_pad($hour, 2, '0', STR_PAD_LEFT)
.':'. str_pad($minutes,2, '0');
}
echo "<select name='locale'>";
foreach($options as $key=>$value){
echo "<option value='".$values[$key]."'>".$value."</option>";
}
echo "</select>";
This would handle the fact there are states with multiple timezones. When you then get the result of this form submission, you can explode the value of the field on '/', where $_POST['locale'] is the handler for the chosen select option, then you can extract timezone, country and state from a single field.
$locale=explode("/",$_POST['locale']);
// $locale[0] = timezone
// $locale[1] = country
// $locale[2-n] = state(s)

Categories