Calculate days between 2 dates and another criterial PHP MYSQL - php

I'm new newbie to programming and I've got an error that i wasn't able to solve after hours searching.
I'm using a form to perform a search and display in a table the data, that part was fairly easy... but I also want to calculate how many days are in the final result, not in the dates I using for the first query.
The query searches for the result in days between 2 dates and from a specified company, the problem is in the final result it calculates how many days are from my result and not from the days i searched.
Example: If i search 2 dates between February 11 and February 20 Where the company = 1
If there is only 3 days result for Company 1, I want it to calculate only 3 Days.
I know my code is Wrong in that part but i just can't get it to do what i want.
Here is a little piece of my code to explain it:
if (isset($_POST['search'])) {
$date1 = mysql_prep($_POST['date1']);
$date2 = mysql_prep($_POST['date2']);
$latte = mysql_prep($_POST['latte']);
$query = "SELECT * FROM payroll WHERE (day BETWEEN '{$date1}' AND '{$date2}') AND (company = '{$latte}') ORDER BY day ASC ";
$result = mysql_query($query, $connection);
$woof = "SELECT SUM(hours) FROM (SELECT * FROM payroll WHERE (day BETWEEN '{$date1}' AND '{$date2}') AND (company = '{$latte}') ORDER BY day ASC) AS subt ";
$raw = mysql_query($woof, $connection);
if(!$raw) { die(mysql_error());}
$meow = mysql_result($raw, 0, 0);
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24) +1);
if(!$result) {
echo "FAIL";
} else {
echo "<table>
<tr>
<th> Date </th>
<th> Hours </th>
<th> Job Title </th>
<th> Job Description </th>
<th> Paid </th>
<th> For </th>
</tr>";
while($row = mysql_fetch_array($result))
{
$company = $row['company'];
if($company == 0) {
$company = "Wilson Electric";
} if($company == 1) {
$company = "Wilson Rental";
} if ($company == 2) {
$company = "Church of Christ";
}
echo "<tr>";
echo "<td class=\"center\">" . $row['day'] . "</td>";
echo "<td class=\"center\">" . $row['hours'] . "</td>";
echo "<td style=\"padding:5px;\">" . $row['job_title'] . "</td>";
echo "<td style=\"padding:5px;\">" . $row['job_description'] . "</td>";
echo "<td class=\"center\">" . $row['paid'] . "</td>";
echo "<td style=\"padding:5px;\">" . $company . "</td>";
echo "</tr>";
}
echo "<tr>";
echo "<td class=\"center\"> Total Days: " . $days . "</td>";
echo "<td class=\"center\"> Total Hours: " . $meow . "</td>";
echo "</tr>";
}
}
Thanks for Reading it, I hope someone can give me a solution, i know must be something really simple but I just couldn't figure out.

If you want a count of distinct day values that match the specification, then you could add a simple expression to the SELECT list of the "woof" SQL statement:
SELECT SUM(hours), COUNT(DISTINCT `day`) AS cnt_days FROM ...
$meow = mysql_result($raw, 0, 0);
$days = mysql_result($raw, 0, 1);
Note that if there is more than one row that has the same day value (which satisfies all of the predicates), that day value is counted only once. If you want a count of rows that have a non-NULL day value, including any duplicates, then omit the DISTINCT keyword.)
Note that the SQL statement could be more simply written; you could omit the (unnecessary) inline view (i.e. derived table) and the unnecessary ORDER BY ...
SELECT SUM(p.hours) AS sum_hours
, COUNT(DISTINCT p.day) AS cnt_days
FROM payroll p
WHERE p.day BETWEEN '{$date1}' AND '{$date2}'
AND p.company = '{$latte}'

May be you can use DateTime::diff

Related

How do I get rows from 3 days last login and longer

I'm trying to code a feature for my service that I have and I'm sort of struggling to get it to work..
I basically want to code a function where it logs where people haven't logged in for 3 or more days, but it just won't work.
I currently have:
$findActivity = mysqli_query($conn, "SELECT * FROM users WHERE 'last_active' < CURRENT_TIMESTAMP - 3 DAY");
while($activeRow = mysqli_fetch_assoc($findActivity)){
$usr = $activeRow['username'];;
$la = $activeRow['last_active'];
echo "<tr class='row100 body'>";
echo "<td class='cell100 column3'>$usr</td>";
echo "<td class='cell100 column3'>$inactivefor</td>";
echo "<td class='cell100 column3'>$msg</td>";
echo "</tr>";
}
I basically want it to output results where it will display accounts that have not logged in for 3 or more days.
Try this:
$findActivity = mysqli_query($conn, "SELECT * FROM users WHERE last_active <
CURRENT_TIMESTAMP - INTERVAL 3 DAY");
while ($activeRow = mysqli_fetch_assoc($findActivity)) {
$usr = $activeRow['username'];
$la = $activeRow['last_active'];
echo "<tr class='row100 body'>";
echo "<td class='cell100 column3'>$usr</td>";
echo "<td class='cell100 column3'>$la</td>";
echo "</tr>";
}

I want to show column status ex.if day left has 30 days status it danger

I want status to have a relation with day_left, e.g. if day_left has 30 days status should be danger. This is homework
<?php
$con2= mysqli_connect("localhost","root","root","database") or die("Error: " . mysqli_error($con2));
$query2 = "SELECT *,datediff (mainexpire,now()) as day_left from contact";
$result2 = mysqli_query($con2, $query2);
echo "<table border='1' align='center' width='1000'>";
echo "<tr bgcolor='#FFFACD'><td><p><center><b>no</center></td></p></b><td><p><center><b>maintenance items
</center></td></p></b><td><p><center><b>owner
</td></p></center></b>
<td><p><center><b>detail
</center></td></p></b><td><p><center><b>expire_date
</center></td></p></b><td><p><center><b>Days Left
</center></td></p></b><td><p><center><b>Status
</center></td></p></b>
</tr>";
while($row2 = mysqli_fetch_array($result2)) {
echo "<tr>";
echo "<td><center><p>" .$row2["no"] . "</center></td></p> ";
echo "<td><center><p>" .$row2["mainitem"] . "</center></td></p> ";
echo "<td><center><p>" .$row2["mainowner"] . "</center></td></p> ";
echo "<td><center><p>" .$row2["maindetail"] . "</center></td></p> ";
echo "<td><center><p>" .$row2["mainexpire"] . "</center></td></p> ";
echo "<td><center><p>" .$row2["day_left"] . "</center></td></p> ";
}
?>
</body>
Well you are doing good with that homework (if you did that of your own, of course). Just need to add a if else condition for the status. Some thing like this after the last line of your while loop.
if( $row2["day_left"] > 30 ) {
echo "<td><center><p>All OK</center></td></p> ";
} else {
echo "<td><center><p>Danger</center></td></p> ";
}
function day_left($day){ //$day will be the target date
$target_date= strtotime($day); //this convert the target day to second
$today = strtotime("today"); //this convert the current day to second
$day_sec = $target_date- $today; //so target day minus current day second
$total_day_left = $day_sec / 86400; //divide it to 86400 thats equivalent to one day
return $total_day_left; //the total day left
}

Display data from database vertically in table

<?php
echo "<table class=\"table table-hover table-bordered\">";
echo "<thead>";
echo "<tr>";
$result=mysqli_query($con,"SELECT day FROM time_slot ORDER BY day;");
while($row=mysqli_fetch_array($result))
{
$days = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
$day = $row['day']-1;
$day = $days[$day];
echo '<th>';
echo $day;
echo '</th>';
}
echo "</tr>";
echo "</thead>";
require('../includes/connection.php');
$result=mysqli_query($con,"SELECT * FROM time_slot ORDER BY day DESC;");
while($row=mysqli_fetch_array($result))
{
echo "<tbody>";
echo "<tr>";
This portion of data should be display vertically in table with respect to Day
//This code to split time into intervals
$starttime = $row['start_time']; // your start time
$endtime = $row['end_time']; // End time
$duration = $row['slot_time'];
$array_of_time = array ();
$start_time = strtotime ($starttime); //change to strtotime
$end_time = strtotime ($endtime); //change to strtotime
$add_mins = $duration * 60;
while ($start_time <= $end_time) // loop between time
{
echo '<td>';
echo "<div align=\"center\">";
print_r(date ("h:i", $start_time) ."-". date("h:i", $start_time += $add_mins));
//
echo "</br><input type=\"radio\" name=\"texi\" value=\"1\" ></input>";
echo '</td>' ;
echo '</div>';
}
echo "</tr>";
echo "</tbody>";
}
mysqli_close($con);
echo "</table>
</div>
<input type=\"submit\" value=\"Book Slot\" class=\"button_drop\">
</form>";
?>
I want to show time slots vertically with respect to day in table.
This is the output of this code:
But I want to display time which is showing horizontally that should be shown vertically. Eg. 1-3, 3-5, 5-7 of first row should be shown below Monday, then next row should be shown below Tuesday and so on.
Try using a query like this:
SELECT day FROM time_slot ORDER BY time_slot, day;
That should get the data in an easier order to process. I can't see your exact data structure but it looks like you should get 7x 01:00-03:00, then 7x 03:00-05:00 etc. Each set should be in order by day. Then you can just write out your <td>s in the order the data comes from the DB. Keep track of when the day value changes (or just count up to 7) and start a new <tr> at that time.

How to work out specific days and times within a date range

I have a database with a table of login and logoff times for staff.
Im looking for which staff clocked on or off between Sunday 6am and Thursday 4am or Saturday 6:30am and Saturday 3pm.
I want the end user to be able to select any date range from a web interface (ie 1/1/14 start and 12/1/14 end) and from this work out who worked during the day and time ranges.
I want to be able to display a list of workers and their login and logoff time.
thus far I have worked out how to check if a user has logged by using Determine Whether Two Date Ranges Overlap
But im stumped with the pseudo code for how to work out the daterangeB
so far I have:
start at datefrom,
check if datefrom = dateto, if true end loop,
find out day name,
check if saturday, if saturday add timestamps to array (start and finish),
increment datefrom by 1 day, start loop again.
this will give me an array of the saturday daterangeB's between the dates selected by the user.
However the bigger date range is an issue, because its possible that the first day is say a Tuesday, and if i'm checking for Sundays and Thursday, say i find a Thursday, i won't have a start day as sunday, I will need to make the Tuesday at 00:00:00. And similarly the opposite could happen, i could find a Sunday, and the last day that the user selects could be a Monday and therefore I need to make that the end date for daterangeB
start at datefrom,
check if datefrom = dateto, if true end loop,
find out day name,
check if Sunday, if Sunday add timestamp to array (start),
increment datefrom by 1 day, start loop again.
and
start at datefrom,
check if datefrom = dateto, if true end loop,
find out day name,
check if Thursday, if Thursday add timestamps to array (start and finish),
increment datefrom by 1 day, start loop again.
So for all those that are interested, here is a dumbed down verson of what i ended up doing:
$stcars = array();
// Create connection
try {
$db = new PDO('mysql:host=localhost;dbname=Reports;charset=utf8', 'XXX', 'XXX');
$db->query('hi'); //invalid query!
} catch(PDOException $ex) {
echo "An Error occured!" . $ex->getMessage(); //user friendly message
}
$stmt = $db->prepare('SELECT CarNumber FROM STcars WHERE CarNumber > 0');
if ($stmt->execute()){
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
array_push($stcars, $row[CarNumber]);
}// end while
}// end if
$DateFrom = $_POST["DateFrom"];
$DateTo = $_POST["DateTo"];
$DateToArray = date('m/d/Y', strtotime($DateTo . ' + 1 day'));
$period = new DatePeriod(
new DateTime($DateFrom),
new DateInterval('P1D'),
new DateTime($DateToArray)
);
foreach($period as $date)
{
$daterange[] = $date->format('m/d/Y');
}
// MS SQL Server with PDO_DBLIB
$DBH = new PDO("dblib:host=$myServer;dbname=$myDB", $myUser, $myPass);
for ($i = 0; $i < count($stcars); ++$i) {
$CarNumber = $stcars[$i];
$STH3 = $DBH->query("SELECT dbo.Driver.DriverNumber, dbo.Driver.DriverName, dbo.DriverLogon.LogonTime, dbo.DriverLogon.LogoffTime, dbo.Vehicle.RegistrationNumber, dbo.OwnerOperator.OOName FROM dbo.Driver INNER JOIN dbo.DriverLogon ON dbo.Driver.DriverID = dbo.DriverLogon.DriverID INNER JOIN dbo.Vehicle ON dbo.DriverLogon.VehicleID = dbo.Vehicle.VehicleID INNER JOIN dbo.OwnerOperator ON dbo.Vehicle.OperatorID = dbo.OwnerOperator.OwnerOperatorID WHERE dbo.Vehicle.CarNumber = '$CarNumber' AND dbo.DriverLogon.LogonTime >= '$DateFrom $Beginning' AND dbo.DriverLogon.LogoffTime <= '$DateTo $End' AND dbo.Driver.DriverNumber != '7777' AND dbo.Driver.DriverNumber != '83890';");
$STH3->setFetchMode(PDO::FETCH_OBJ);
while($row3 = $STH3->fetch()) {
$logonday = date("D", strtotime($row3->LogonTime));
$chkStartTime = strtotime($row3->LogonTime);
$chkEndTime = strtotime($row3->LogoffTime);
$Tplate = $row3->RegistrationNumber;
$Operator = $row3->OOName;
$logontime = gmdate("D d/m/Y H:i:s", strtotime($row3->LogonTime));
$logofftime = gmdate("D d/m/Y H:i:s", strtotime($row3->LogoffTime));
for ($e = 0; $e < count($daterange); ++$e) {
$Date = $daterange[$e];
$day = date("D", strtotime($Date));
if(strpos( $day, $Mon ) !== FALSE){
$startTime = strtotime($Date . " " . $Beginning);
$endTime = strtotime($Date . " " . $End);
if($chkStartTime >= $endTime || $chkEndTime <= $startTime){}else
{
echo "<tr>" ;
echo "<td>" . $day . "</td> ";
echo "<td>" . $row3->DriverNumber . "</td> ";
echo "<td>" . $row3->DriverName . "</td> ";
echo "<td>" . $Operator . "</td> ";
echo "<td>" . $CarNumber . "</td> ";
echo "<td>" . $Tplate . "</td> ";
echo "<td>" . $logontime . "</td> ";
echo "<td>" . $logofftime . "</td> ";
//echo "<td>" . "Logon after Time End or Logoff before Time Start" . "</td> ";
//echo "<td>" . gmdate("D d/m/Y G:i:s", strtotime($Date . " " . $Beginning)) . "</td> ";
//echo "<td>" . gmdate("D d/m/Y G:i:s", strtotime($Date . " " . $End)) . "</td> ";
echo "</tr>" ;
$list1 ="$day, $row3->DriverNumber, $row3->DriverName, $Operator, $CarNumber, $Tplate, $logontime, $logofftime " . "\n";
fwrite($handle, $list1);
}

PHP grouping by "bi weekly"

I have a report that calculates employee working hours by retrieving date, punch in and punch out and calculate duration, this data is saved into an array to be displayed based on the payroll period, here is the code that calculates payments based on a weekly period (looping within array)
foreach($punch_sets as $val){
if ($currentmonth==""){
echo "<tr><td>" . date("W",strtotime($val['in_date'])) . "</td>";
}
if ($currentmonth1 == date("F",strtotime($val['in_date'])) || $currentmonth1 ==""){
if ($currentmonth == date("W",strtotime($val['in_date'])) || $currentmonth==""){
$total_time += $minSec + $hours*3600;
$currentmonth = date("W",strtotime($val['in_date']));
}
else
{
echo "<td>" . sec2hm($total_time) . "</td>";
echo "<td>" . (sec2hm($total_time) * $ratepaid) . "</td></tr></tr>";
$currentmonth ="";
$total_time = $minSec + $hours*3600;
}
}
else {
$total_time = $minSec + $hours*3600;
}
$currentmonth1 = date("F",strtotime($val['in_date']));
}
The question here how do I adjust this logic to get bi weekly calculation instead of weekly.
Instead of using:
date("W",strtotime($val['in_date']))
To group by, group by:
floor(date("W",strtotime($val['in_date']))/2);
You might want to change $currentmonth to $currentperiod to reflect the change from the original script from monthly to weekly to now bi-weekly.

Categories