Averaging a number over multiple rows, selected by day - php

I'm writing up a statistics script for a service I run. I want to work out the average number of rows per day on a last 3 days, weekly, monthly and yearly basis. My basic thought is something like this to grab the average:
<?php
function getDayNumber($day)
{
$start = strtotime("last monday");
$q = mysql_query(sprintf("SELECT COUNT(*) as count FROM mytable WHERE dayname(datetime) = "%s" AND unix_timestamp(datetime) > %s",$day,$start));
$row = mysql_fetch_assoc($q);
return $row['count'];
}
$monday = getDayNumber("Monday");
$tuesday = getDayNumber("Tuesday");
$wednesday = getDayNumber("Wednesday");
$thursday = getDayNumber("Thursday");
$friday = getDayNumber("Friday");
$average = ($monday+$tuesday+$wednesday+$thursday+$friday)/5;
?>
The above is just psuedo code written from my head. I can't think of a better method though.
Is this possible to do via nested/joined queries? I'll need to be able to do it on a daily, weekly, monthly... etc basis. I figure if I can find a way to pull all the data in MySQL, I can just add all the count(*)'s together and divide them via the number of responses.
Is this feasible?
Any help is appreciated - thanks all!

I suggest finding the date range for each data set then running your query. Hope this helps.
<?php
/**
* Get the average number of rows that were created
* during the given date range.
*
* #param string $range The date range to look for
* #return integer The average number of rows created in the given range
*/
function getAverageRows($range)
{
$date_begin = null;
$date_end = null;
switch($range)
{
case 'year':
// Calculate the beginning and end datetime of the past year
$date_begin = FIRST_DAY_OF_YEAR . ' 00:00:00';
$date_end = LAST_DAY_OF_YEAR . ' 23:59:59';
break;
case 'month':
// Calculate the beginning and end datetime of the past month
$date_begin = FIRST_DAY_OF_MONTH . ' 00:00:00';
$date_end = LAST_DAY_OF_MONTH . ' 23:59:59';
break;
case 'week':
// Calculate the beginning and end datetime of the past week
$date_begin = FIRST_DAY_OF_WEEK . ' 00:00:00';
$date_end = LAST_DAY_OF_WEEK . ' 23:59:59';
break;
default:
// Calculate the beginning and end datetime of the past three days
$date_begin = SEVENTY_SIX_HOURS_AGO;
$date_end = now();
break;
}
$query = "SELECT COUNT(*) FROM mytable WHERE datetime >= '{$date_begin}' AND datetime <= '{$date_end}'";
// Get and return query results
}
echo "Average Rows:<br/>";
echo "Past three days: " . getAverageRows() . "<br/>";
echo "Past week: " . getAverageRows('week') . "<br/>";
echo "Past Month: " . getAverageRows('month') . "<br/>";
echo "Past Year: " . getAverageRows('year') . "<br/>";

Related

How can I get the duration beetwen an empty date timestamp and an other determined?

I am coding to calculate a duration between an empty timestamp date and an other, non-empty, Please help me.
I would like to calculate this duration to set a confirmation's code expires when a participant in the forum comes back too late or doesn't come back over 2 days as a maximum delay
This code works fine except when the come back date is empty:
$date_participation= strtotime($row['date_participation']);
$date_come_back= strtotime($row['date_come_back']);
$expiration_delay = 2;
$days = $expiration_delay * 86400;
echo "<br> duration in seconds is: " . $date_come_back-
$date_participation;
if (($date_come_back- $date_participation) >= $days){
$sql_set_expired = "UPDATE `winners` SET `confirmation_status` = 'expired' WHERE id_recharge_winner ='$i'";
$set_expired_result = mysqli_query($conn, $sql_set_expired);
}
the `$i` is the participant's row in table winners
This is how I result my problem whiout worry if there is an Empty date:
I maked my one fuction
Difference_between_timestampdate()
than I specify one day like an expiration duration. It works fine, Thanks to those who helped me.
function Difference_between_timestampdate($first_date, $last_date){
$first_date = strtotime($first_date );
$last_date = strtotime($last_date);
$days = $expiration_delay * 82800;
if(empty($last_date)){
$duration = time() - $first_date;
}else{
$duration = $last_date - $first_date;
}
return $duration;
}
$date_participation = $row['date_participation'];
$date_come_back = $row['date_come_back'];
$expiration_delay = 1; //One day
if ((Difference_between_timestampdate($date_participation, $date_come_back)/82800 )
>= $expiration_delay){echo 'Expired duration';}else{echo 'Valid duration';}

Calculating number of hours from multiple dateTimes php

I am retrieving records from a database which have separate date and time field and combining them into date time objects so that I can get the difference between start and finish date/time. I also want to calculate to total number of hours that have passed for the number of records returned.
My current code is like this
$temp_total = date_create("00:00");
while($row = mysqli_fetch_assoc($result))
{
$startDate = $row['StartDate'];
$startTime = $row['StartTime'];
$start = $startDate . " " . $startTime;
$start = new DateTime($start);
$finishDate = $row['FinishDate'];
$finishTime = $row['FinishTime'];
$finish = $finishDate . " " . $finishTime;
$finish = new DateTime($finish);
$duration = $start->diff($finish);
$temp_total->add($duration);
}
This just ends up with the times wrapping around i.e. 8hr, 12hr and 12 hrs gives me a total of 8 hours which I assume is because I am missing the added day somewhere.
Am I going about this in the right way or is there a better way of doing it?

Having trouble comparing a range of dates entered in a form with records in a mySQL database

I have a table called schedule and a column called Date where the column type is date. In that column I have a range of dates, which is currently from 2012-11-01 to 2012-11-30. I have a small form where the user can enter a range of dates (input names from and to) and I want to be able to compare the range of dates with the dates currently in the database.
This is what I have:
////////////////////////////////////////////////////////
//////First set the date range that we want to use//////
////////////////////////////////////////////////////////
if(isset($_POST['from']) && ($_POST['from'] != NULL))
{
$startDate = $_POST['from'];
}
else
{
//Default date is Today
$startDate = date("Y-m-d");
}
if(isset($_POST['to']) && ($_POST['to'] != NULL))
{
$endDate = $_POST['to'];
}
else
{
//Default day is one month from today
$endDate = date("Y-m-d", strtotime("+1 month"));
}
//////////////////////////////////////////////////////////////////////////////////////
//////Next calculate the total amount of days selected above to use as a limiter//////
//////////////////////////////////////////////////////////////////////////////////////
$dayStart = strtotime($startDate);
$dayEnd = strtotime($endDate);
$total_days = abs($dayEnd - $dayStart) / 86400 +1;
echo "Start Date: " . $startDate . "<br>End Date: " . $endDate . "<br>";
echo "Day Start: " . $dayStart . "<br>Day End: " . $dayEnd . "<br>";
echo "Total Days: " . $total_days . "<br>";
////////////////////////////////////////////////////////////////////////////////////
//////Then we're going to see if the dates selected are in the schedule table//////
////////////////////////////////////////////////////////////////////////////////////
//Select all of the dates currently in the schedule table between the range selected.
$sql = ("SELECT Date FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' LIMIT $total_days");
//Run a check on the query to make sure it worked. If it failed then print the error.
if(!$result_date_query = $mysqli->query($sql))
{
die('There was an error getting the dates from the schedule table [' . $mysqli->error . ']');
}
//Set the dates to an array for future use.
// $current_dates = $result_date_query->fetch_assoc();
//Loop through the results while a result is being returned.
while($row = $result_date_query->fetch_assoc())
{
echo "Row: " . $row['Date'] . "<br>";
echo "Start day: " . date('Y-m-d', $dayStart) . "<br>";
//Set this loop to add 1 day to the Start Date until it reaches the End Date
for($i = $dayStart; $i <= $dayEnd; $i = strtotime('+1 day', $i))
{
$date = date('Y-m-d',$i);
echo "Loop Start day: " . date('Y-m-d', $dayStart) . "<br>";
//Run a check to see if any of the dates selected are in the schedule table.
if($row['Date'] != $date)
{
echo "Current Date: " . $row['Date'] . "<br>";
echo "Date: " . $date . "<br>";
echo "It appears as though you've selected some dates that are not in the schedule database.<br>Please correct the issue and try again.";
return;
}
}
}
//Free the result so something else can use it.
$result_date_query->free();
As you can see I've added in some echo statements so I can see what is being produced. From what I can see it looks like my $row['Date'] is not incrementing and staying at the same date. I originally had it set to a variable (currently commented out) but I thought that could be causing problems.
I have created the table with dates ranging from 2012-11-01 to 2012-11-15 for testing and entered all of this php code onto phpfiddle.org but I can't get the username provided to connect.
Here is the link: PHP Fiddle
I'll be reading through the documentation to try and figure out the user connection problem in the meantime, I would really appreciate any direction or advice you can give me.

Function in code I'm debugging seems to not take into account shifts to and from DST

I'm debugging a conference room booking calendar which was put together by someone which is no longer working with me. It's been a nightmare since there were so many things wrong with it, but I'm having trouble figuring out exactly what's causing this last bug. The calendar checks to see if rooms have already been booked at certain times and they aren't having an issue showing as booked at the right time, but if someone tries to book the same room an hour or less after the room is vacated after a shift to or from DST, it shows the room as booked still.
Example:
User sees that a room is reserved for Nov. 29th from 9am-10am.
User then tries to book the room on Nov. 29th from 10:30am-12:00pm.
The calendar cancels this second request and informs the user that the room is already booked.
It should be noted that this doesn't happen any time before the shift to DST (Nov. 4th). Here's the function which determines if the room is available:
function calCheck($starttime, $endtime, $cal_name, $cat_id, $myDB, $myHost, $myUser, $myPass) {
$timezone = 'America/Denver';
date_default_timezone_set ($timezone);
$dset = new DateTime($odate, new DateTimeZone($timezone));
$dset2 = $dset->getOffset();
//$starttime = $starttime + 1;
//$endtime = $endtime - 1;
$starttime = $starttime - $dset2 + 1;
$endtime = $endtime - $dset2 - 1;
$starttime = $starttime;
$endtime = $endtime;
//echo $starttime .'</br>'. $endtime . '</br>';
$db = new myDB($myDB, $myHost, $myUser, $myPass);
$db->myDB_Connect();
//echo 'calcheck</br>';
$ck_query = 'SELECT * FROM vw_cal_chk
WHERE (stime < '. $starttime . ' AND etime > ' . $starttime . ' ) and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"
OR (stime < ' . $endtime . ' AND etime > ' . $endtime . ') and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"
OR (stime >= '. $starttime . ' AND etime < ' . $endtime .') and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"';
$ck_result = $db->myQuery($ck_query);
$num = mysql_num_rows($ck_result);
//echo $ck_query . '</br>' . $num;
if ($num >> 0){
$avail = 1;
} else {
$avail = 0;
}
return $avail;
}
All of my timestamps up to this point are in UTC and I notice the $odate variable is actually never instantiated anywhere, but I haven't been able to determine what value to pass it in order for the offsetting to work correctly. If I can find out what kind of date it wants, I should be able to work the rest out.
$odate is null which defaults to now giving you the current offset. What you want is the offset at the time that the schedule is being set not the offset right at this moment. It looks like your database dates are in Mountain time and that your startdate is utc and you are subtracting the offset to get back to mountain (I would think that you would add the offsets not subtract , so I might have this reversed, can you query your database and figure it out?)
In any event you should be computing your offset using $startdate not now(), try switching $startdate for $odate and see what happens. If this doesn't work try building a string from startdate and then generating a new date from that string. If nothing else outputting that string should give you a clear picture as to whether $startdate is UTC or mountain

mysql+php to subtract two times and display the differrence

i've to display the differences between a column(reg_time) in mysql and the present time so that the final output (after some php to display in minutes or seconds or hours or days)
be:
Registered : 8 hours ago.
is there any function to do that?
thanks
//End date is current date
//$start_date, lets say sep 05 82 : 00:00:00
$seconds_dif = mktime(date("G"),date("i"),date("s"),date("m"),date("d"),date("Y")) - mktime('00','00','00','09','05','1982');
//Difference in seconds is $seconds_dif
//Now only math calculation to figure out months/years..
echo '<br />Years Difference = '. floor($seconds_dif/365/60/60/24);
echo '<br />Months Difference = '. floor($seconds_dif/60/60/24/7/4);
echo '<br />Weeks Difference = '. floor($seconds_dif/60/60/24/7);
echo '<br />Days Difference = '. floor($seconds_dif/60/60/24);
echo '<br />Hours Difference = '. floor($seconds_dif/60/60);
echo '<br />Minutes Difference = '. floor($seconds_dif/60);
Found here: http://www.webhostingtalk.com/showthread.php?t=453668
You need to edit the 3rd line of code for your data format:
mktime('00','00','00','09','05','1982')
Also you need to wrap this code into a function for easy using it:
/**
* Return string with date time difference between two arguments
* #param $start_date integer Start date in unix time (seconds from January 1 1970), you can use strtotime('24 November 2003 13:45:54'), for example
* #param $end_date integer [optional] End date in unix time, by default it equals now
* #return string
*/
function getDateTimeDifference($start_date, $end_date = time()) {
$end_date = mktime(date("G", $end_date),date("i", $end_date),date("s", $end_date),date("m", $end_date),date("d", $end_date),date("Y", $end_date));
$difference = $end_date - mktime(date("G", $start_date),date("i", $start_date),date("s", $start_date),date("m", $start_date),date("d", $start_date),date("Y", $start_date));
$years = floor($seconds_dif/365/60/60/24);
$months = floor($seconds_dif/60/60/24/7/4);
$weeks = floor($seconds_dif/60/60/24/7);
$days = floor($seconds_dif/60/60/24);
$hours = floor($seconds_dif/60/60);
$minutes = floor($seconds_dif/60);
$ret = 'Difference: ';
if (!empty($years))
$ret .= $years . ' years, ';
if (!empty($months))
$ret .= $months . ' months, ';
if (!empty($weeks))
$ret .= $weeks . ' weeks, ';
if (!empty($days))
$ret .= $days . ' days, ';
if (!empty($hours))
$ret .= $hours . ' hours, ';
if (!empty($minutes))
$ret .= $minutes . 'minutes';
return $ret;
}
Take a look at the MySQL functions timediff() (4.1.1+) and timestampdiff() (5.0+).
And the php method DateTime::diff() (5.3+)
e.g.
SELECT Now(), TIMESTAMPDIFF(HOUR, Now(), '2009-12-12 06:15:34')
just returned
"2009-12-12 12:34:00"; "-6"
on my machine. And
$dt = new DateTime('2008-03-18 06:15:34');
echo $dt->diff(new DateTime())->format('%y %d %h');
(currently) prints
1 25 6

Categories