Calculate time left between todays date and date in MySQL database - php

I am using PHP and MySQL for a very small CMS.
One of the functional requirements is that the system gives back the amount of days left before renewal date (For example how many days left between now and the renewal field in the database)
The process I was going to take was #3AM every morning, go through all the records (via PHP) and update the required field. The trick is that if this figure is <30 (days) then send email to ....who ever.
This seems very impracticable and as it would be in a loop maybe too intense on the database.
If I could have the database make this calculation it would be better (not sure how).
HOWEVER
I will still have to loop through all records anyway to see if there are <30 days before renewal (to send email).
If anyone has a better suggestion, i would be very grateful. Below is some presudo code I would like to do
$q = "SELECT * FROM testDB ";
$r = mysql_query($q);
while ( $a = mysql_fetch_assoc($r) ) {
$rnlDate= stripslashes($a['renewal_Date']); //get Date inserted in table
$thisId= stripslashes($a['id']); // current record id
$timeLeft=$rnlDate-date(); // get time left
if($timeLeft <=30)
{
$makeEmail= createEmail(field_ID); // not sure how to wait until this function completes
}
doUpdate($timeLeft);
function doUpdate($timeLeft)
{
"UPDATE INTO testDB WHERE 'id' =$thisId; VALUES('','$timeLeft',)";
}
obviously just passing the idea here, but any other soloutions are very welcome.
Cheers

Do this in your query. It's much easier:
$q = "SELECT *
FROM testDB
WHERE renewal_Date < CURRENT_TIMESTAMP - INTERVAL 30 DAY";

You can do this in MySQL using the TIMESTAMPDIFF() function, something like
SELECT TIMESTAMPDIFF(DAY,NOW(),column_name) AS diff
FROM table
WHERE id = 'whatever';
This will give you the number of days left, plug into a variable $days. Then
if(($days > 0) && ($days <30)) {
// do something
}

stripslashes? you really really really need to upgrade your php version. magic_quotes have been disabled by default for a long time now, and having it on is a sign of a badly misconfigured server, and/or badly out-of-date PHP install.
that being said, your query would not be "heavy" or "bad", unless you're dealing with billions of rows...
SELECT ...
FROM ...
WHERE renewal_date > (CURDATE() - INTERVAL 30 DAY) AND (renewal_date < CURDATE() )
should fetch all records where the renewal date falls within the past 30 days.

Related

Only select records between start and end time and date

I am working on a school project where I have to make a todo web app. now i have a little problem. I need to get the records that are running out of time (think 20% of the whole task left). now i'm looking for a solution in php or a sql statement with which i can retrieve only those records.
I tried many statements but i cant get one to work.
SELECT * FROM tasks
WHERE user_id='$user_id'
AND '$currentDate' BETWEEN start_date AND end_date
The above one is working with the date but not with time.
So now I need to have a statement or function that only retrieves the tasks that are almost finished. I've added a screenshot of the database and the application to clarify it a bit.
i hope someone could help me. (this is my first time using stackoverflow so sorry if i do something wrong)
First, you should not be munging your query with constants, date or otherwise. So, use now().
Second, combine the date/time into a single column
Third, you seem to want and:
WHERE user_id = ? AND
NOW() >= start_datetime AND
NOW() < end_datetime
If you want to store the date/time in separate columns, then you can combine them:
WHERE user_id = ? AND
NOW() >= ADDTIME(CAST(start_date as DATETIME), start_time) AND
NOW() < ADDTIME(CAST(end_date as DATETIME), end_time)

Only show data for a determined duration with php

I have a page that shows posts stored in a mysql database. When the post is created the user can select how long they want the post to be visible for and I'm trying to figure how to only show posts for a determined duration. Here is some of my code (that hopefully shows the logic I'm trying).
//Query database
$sql = <<<SQL
SELECT *
FROM `posts`
SQL;
if(!$result = $db_connection->query($sql)){
die('There was an error running the query [' . $db_connection->error . ']');
}
while($row = $result->fetch_assoc()){
//The date the post was made
$date_of_post = $row['date_of_post'];
//The duration of the post in days eg 7.
$duration = $row['duration'];
//Attempting to add duration to date
$newdate = strtotime($duration, $date_of_post);
//Only show posts that are still valid, eg date + duration is less than today's date
if($newdate > now()){
echo '<h2>Post Title</h2>';
echo '<p>Date of Posted:'.$date.'</p>';
}
}
You can use a where clause and a date_add function to apply this filter directly in your SQL query. Simply add the duration days to the date_of_post value, and compare it against NOW().
Note that because you're storing your duration value as a varchar instead of an int, you'll need to convert the duration value to a signed int.
Here is an example, with the date_add expanded out to make it clearer to understand what is happening.
select
*
from
posts
where
date_add
(
date_of_post,
INTERVAL convert(duration, SIGNED INT) DAY
) > NOW()
As a side note, you should always try to filter your data in your query, and not in your PHP script. Don't just select your entire table into your script - let SQL do as much work as possible. The RDBMS is far more efficient than PHP, and you'll save a lot on overhead (eg amount of data sent over the network, and how much RAM has to be used to store the results for PHP to work with, etc).

PHP/MySQL - Calculate Total for each Reservation

I've got a Reservation application, and I'd like to calculate the total number of meals needed by reservations date span.
My database has fields:
$name - Person reserving
$chkin - Check in date (DATE yyyy-mm-dd)
$chkout - Check out date (DATE yyyy-mm-dd)
$guests - Number of people in group
$meal - Eating meals (Yes/No)
So for each reservation I have:
// Days of Stay
$days = (strtotime($chkout) - strtotime($chkin)) / (60 * 60 * 24);
What I'm not sure of is how to do the calculation for each reservation in the database.
My calculation for each reservation would be something like:
$days * $guests
I would appreciate advice on this query... I'm trying to give a snapshot of how many meals will be need to be prepared for a given month, weeekend, etc.
Thank you!
Something like this:-
SELECT SUM(guests * DATEDIFF(IF(chkin < $start_range, $start_range, chkin), IF(chkout > $end_range, $end_range, chkout)))
FROM sometable
WHERE chkin < $end_range
AND chkout > $start_range
AND meal = 'Yes'
Uses DATEDIFF() to get the number of days between the check in date (or if later the start of the date range you are interested in) and the check out date (or if earlier the end of the date range you are interested in) where meal is 'yes' and multiplies that by the number of guests, then uses SUM() to add them up for all bookings.
You can use the MYSQL date diff to achieve a count of the days, then this can be multiplied by the number of guests. Finally you will need to select a date range for this search. Below are the basics or the MYSQL needed in order to get these values. This should put you on the right track to achieving what you want.
SELECT DATEDIFF(a.chkout,a.chkin) * a.guests as meals
FROM table as a
WHERE a.chkin > '0000-00-00' AND a.chkout < '0000-00-00
I have tested this with a table of mine and it appears to be working correctly, however, without much data I can only test lightly. If you have any issues, leave a comment and I will try to help further.
http://www.w3schools.com/sql/func_datediff.asp
I'll give you a snippet as a starting point.
Let's say you want the top 10 guests with the longest stay.
SELECT DATEDIFF(chkout, chkin) AS daysstaying FROM reservations ORDER BY daysstaying DESC LIMIT 10
You can do calculations in queries and use the AS operator to create an alias for the result. I'm leaving it to you to work out the specific query you need to obtain the results you need.
I would also suggest that you investigate using views if this query needs to be used often.
http://dev.mysql.com/doc/refman/5.5/en/views.html
I was able to use Kickstart's and Erik's reply to come up with a solution! Thanks!!
// Get Current Month
$current_month = date('F');
// Current timestamp is assumed, so these find first and last day of THIS month
$start_range = date('Y-m-01'); // hard-coded '01' for first day
$end_range = date('Y-m-t');
$sql = "SELECT SUM(DATEDIFF(a.chkout,a.chkin) * a.guests) AS meals
FROM reservations AS a
WHERE a.chkin > '$start_range' AND a.chkout < '$end_range'
AND meal = 'Yes' AND confirm = 'Yes'";
No I will work towards forecasting for upcoming months as well!

Database living in the past?

I have events in my MySQL database wich all have a date. When I perform a SQL query to get all the events in the future, I get an error... Although, the date of the events are in the future. When I change my SQL request to select dates in the past, I get those from the future...
The SQL statement below has worked before, but for some reason it stopped working...
I use this SQL request:
$sql = "SELECT * FROM calendar WHERE date >= CURDATE() order by `date`";
I get an empty array as result...
However if I change the query to this, I get all the events in my database:
$sql = "SELECT * FROM calendar WHERE date <= CURDATE() order by `date`";
This is my database data. In my opinion, all data are in the future...
The format of the date table is a default date-type:
When I ask my server about the time echo date("Y-m-d"); I get todays date as result...
So where do I make a mistake?
You may be checking the wrong date field. Do you have a created date as well as a scheduled date?
I could be crazy from the cold medicine I am on at the moment, but your date table can't possibly be the date of your calendar items, the id filed is only an int(2), that seems kind of small.
maybe something simplier? I notice the column name in your table is date, which also is the name of a function date() that returns the date part of a datetime value. If thats the case
$sql = "SELECT * FROM calendar c WHERE c.`date` <= CURDATE() order by `date`";
would do the trick. Even if not mysql itself, the gui app youre using (seems like phpmyadmin to me) might get confused.
(btw, you forgot the closing tick of date in the order by clause)
getting an empty set is meaning nothing is found matching. I would look at your formatting of your date. The only other thing i was thinking is that it is comparing an unmatched type so just returns an empty set.
use DATEDIFF :
DATEDIFF
WHERE DATEDIFF(date, CURDATE) > 0
Before you make your query, run this one:
SET time_zone = '-2:00'; // or whatever your time zone is.
Don't ask me how or why, but I've truncated my table and re-inserted some data and my query seems to work just fine:
$sql = "SELECT * FROM `calendar` WHERE `date` >= CURDATE() order by `date`";
So, despite the fact the problems seems to be solved by truncating my table, I would like to know the answer to the why-question... Anyone can provide me with it?

MySQL: How many minutes ago was DB updated?

I need to keep a field in a data-base and update it with a time somehow, then later I need to check that time to see if it was over 30 minutes ago or not, and if not, how minutes left until 30?
I am going to be doing this with PHP+MySql can anyone tell me the simplest way to do this?
Thanks!!
Let's assume you want to know how long ago the last update/insert in the table occurred.
You can set up a table with a timestamp field with an on update clause
CREATE TABLE foo (
id int auto_increment,
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
primary key(id),
key(ts)
)
and then query the record with the largest value in ts
SELECT
TIMEDIFF(Now()-Interval 30 Minute, ts)
FROM
foo
ORDER BY
ts DESC
LIMIT
1
edit: This also works if you want to get all records that have been inserted/modified within e.g. the last 12 hours.
SELECT
TIMEDIFF(Now()-Interval 30 Minute, ts)
FROM
foo
WHERE
ts > Now()-Interval 12 hour
ORDER BY
ts DESC
edit2: there's also an off chance you might be interested in http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html:SHOW TABLE STATUS returns the following fields:
...
Update_time
When the data file was last updated. For some storage engines, this value is NULL. For example, InnoDB stores multiple tables in its tablespace and the data file timestamp does not apply. For MyISAM, the data file timestamp is used; however, on Windows the timestamp is not updated by updates so the value is inaccurate.
I could wrap all you insert and update MySql calls in a function something like the following:
function MySqlQuery($query, $res){
$result = mysql_query($qs, $res);
if($result === false){
mysql_query("QUERY STRING TO UPDATE FIELD IN DATABASE WITH NEW TIME", $res);
}
return $result;
}
Replace the "QUERY STRING TO UPDATE FIELD IN DATABASE WITH NEW TIME" with an actual update query and you should be good to go.
What I do is, put a Time Stamp on the latest record. Pull the latest record with a MySQL Query and then use the mysql fetch array function to get the time of that last record. This goes the same for using a database that is updated with the time only.
You would be able to manipulate that time with a function that compares the current time to the time on the record. From there you can display the time since last posting, and if it is over 30 minutes you can make it echo a message.
$currenttime = /* PHP Time Formatting you wish to use. */
$query = mysql_query("SELECT time FROM database");
$row = mysql_fetch_array($query);
echo "Last Record Posted #" . $row['time'];
$timesince = $currenttime - $row['time'];
echo "Time Since Last Post:" . $time - $row['time'];
if($timesince >= "30"){
echo "Over 30 Minutes!";
}
Let me know if you have any questions. The above code should give you an idea of how it would work, but it is a rough example.
Best of Luck!!
EDIT:::
Sorry, I misread the question, You would still need to enter the time into the database. You can still use the above code to pull the time and see if it is greater than 30 minutes or not.
For the Time Stamp check out the PHP Time Manual. You will want to pick the same time format for both the MySQL Input and the code I posted above.

Categories