Reputation: 356
I am working on a shift based application where my workers work in 3 shifts, Morning 6am to 2pm, 2pm to 10pm and 10pm to 6am(next day). I need to calculate to total time worked in each shifts which is logged in the database.
$clientid = $_GET["clientid"];
$date = $_GET["edate"];
$shift = $_GET["shift"];
if(!empty($clientid))
{
if($shift=='a')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '6:00:00' AND '14:00:00' AND clientid= '$clientid' AND edate = '$date'",$this->db);
}
else if($shift=='b')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '14:00:00' AND '22:00:00' AND clientid= '$clientid' AND edate = '$date'",$this->db);
}
else if($shift=='c')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '22:00:00' AND '6:00:00' AND clientid= '$clientid' AND edate= '$date'",$this->db);
}
Whenever I try to access the Shift C, it fetches me data only till 11:59PM on that day as I am parsing the date too. How do I alter the sql to fetch data for the next day, till 6AM too?
Upvotes: 0
Views: 594
Reputation: 1270483
For the third one, you need to subtract hours to get the date correct:
SELECT *
FROM logusage
WHERE etime BETWEEN '22:00:00' AND '6:00:00' AND
clientid= '$clientid' AND
date(date_sub(edate, interval 6 hour)) = '$date';
Upvotes: 1
Reputation: 14269
I strongly suggest you to store EDATE and ETIME in a single column as TIMESTAMP value instead of 2 separate columns. It is also a good practice to store timestamps as GMT+00 values instead of your local time - but this only matters if your local time uses DST (day-light saving). Try the following code:
$clientid = (int)$_GET["clientid"];
$date = $_GET["edate"];
$shift = $_GET["shift"];
if($clientid != 0 AND $date != '')
{
// I suppose $date is in format YYYY-MM-DD
list($year,$month,$day) = preg_split('/-/',$date);
switch($shift)
{
case 'a':
$beg_stamp = mktime(6,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
case 'b':
$beg_stamp = mktime(14,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
case 'c':
$beg_stamp = mktime(22,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
}
if($beg_stamp != '' AND $end_stamp != '') // not strictly needed, if $shift is always valid
$sq = mysql_query('SELECT * from logusage WHERE clientid = '.$clientid.' AND TIMESTAMP(edate,etime) BETWEEN "'.date('Y-m-d H:i:s',$beg_stamp).'" AND "'.date('Y-m-d H:i:s',$end_stamp).'" ORDER BY edate,etime',$this->db);
}
You subtract 1 from the $end_stamp because the SQL predicate BETWEEN is inclusive - i.e. x BETWEEN y AND z is equivalent to x >= y AND x <= z and you do not want to catch work which belongs to the next shift.
Upvotes: 1