MySQL: How many minutes ago was DB updated? - php

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.

Related

How to calculate the total time logged in the system?

I am using CodeIgniter and I am calculating the total time from the dates.
Explanation:
What I am doing is, Every login I am inserting the last_Ativity date and time in the database using below code.
$data_login= array('emp_id' =>$result->id ,'last_activity' =>date("Y-m-d H:i:s", STRTOTIME(date('h:i:sa'))));
$this->db->insert('tbl_current_login',$data_login);
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Now I have to calculate the total time of the specific user for a single day(current date).
For example- emp_id 26 logged in twice so I have to calculate the time
First-time login date and time:-2018-09-17 07:27:55
Second-time login date and time:- 2018-09-17 07:35:22
It will increase depending upon how many time the user logged in.
I am confused about the time. Am I on the right path to calculate the total hour login in the system?
Should I use an MYSQL query or PHP to calculate? I need some idea.
Would you help me out in this?
This is what I would do
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Before you update the row.
check if a row for activity exists
if it does, get the timestamps for the date and subtract the current time (the one you are changing last_activity to, from the one stored in the DB) take that number and add it to an integer column named something like elapsed time (you would have to add this to the DB)
if not then enter a row with 0 elapsed time ( depending how you put the first row in, maybe on login) this may never be an issue.
For the timestamps, you would do a select to get the current row. Take the datetime field and use either
$time = strtotime($row['last_activity']);
OR
$time = (new DateTime($row['last_activity']))->getTimestamp();
Then you simply do the same thing to the date you are going to replace that with and then subtract to get the difference in seconds.
$elapsed = time() - $time;
And then add that to the current rows value, and save it. This way you can keep track of a running total in seconds of the time they spend during that session.
Then when you need to count the total time its a simple matter of doing
SELECT SUM(elapsed_time) FROM {table} WHERE DATE(last_Ativity) = :date
If you were dealing with just two date time fields in the DB it would be easier to just get the difference of those, but sense you already have code to constantly update the last active field this would require less work in the long run IMO.
Option2
The other option is to add another Datetime field to put a start time or login time in. Then when you query you can convert them to their timestamps and subtract to get the difference.
This makes the SQL harder (when doing the SUM ), I can't really think off the top of my head how I would calculate the elapsed time on multiple rows and then sum them up. But it does simplify the PHP quite a bit. So which ever way works best for what you need. Think about if you need the utility to know when they logged in, or if you just want an easier way to calculate the time they spend.
Something like that.
Assuming that the only log happens based on user actions, and so, after 15 minutes (for example) the user is assumed logged out
And assuming you'd want daily total, the solution should be something like this:
SELECT
first.emp_id,
SUM(TIMESTAMPDIFF(MINUTE,first.last_acivity, DATE_ADD(IFNULL(last.last_acivity, first.last_acivity), INTERVAL 15 MINUTE))) as logged_minutes
FROM
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity < la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) first
LEFT JOIN
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity > la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) last
ON
first.emp_id = last.emp_id
GROUP BY
emp_id
In this query need to set the date seperately:
SET #date0 = DATE(NOW()) ;
To get the first record of the day, or the last, we need to LEFT join the table to itself, on the same emp_id BUT witn with an inequality, which will get for each emp record its ancestors or predecessors
When we add the NULL condition we bring the we get the edge case: first or last
What's left then is just calculating the minutes between the 2 tables
Since I assumed no log out record occurs, I treated the case when the first and last logins are the same, or no last login

How to datenow minus datetime MySQL with PHP in second

i want to minus purchase date with datenow. i have table named count_sec :
|user_id| purchasedate |second|
| 1 |2015-06-06 08:36:05| |
| 2 |2015-06-06 08:36:15| |
example time now is 2015-06-06 08:37:00
what is the code if i am want the code to update the second to:
|user_id| purchasedate |second|
| 1 |2015-06-06 08:36:05| 55 |
| 2 |2015-06-06 08:36:15| 45 |
thank you
EDIT
i have already create this php, but the code is not work, how to fix?
<?php
require 'database/db.php';
$selectprchsdate = $mysqli->query("SELECT purchasedate FROM count_sec");
$row = mysqli_fetch_assoc($selectprchsdate);
$date = date('Y-m-d H:i:s');
$result = $date - $row['purchasedate'];
$mysqli->query("UPDATE count_sec
SET second = '".$result."'");
?>
In PHP you can use
// get current date and time
$now = new DateTime();
// create DateTime object for purchase date
$purchaseDate = DateTime::createFromFormat('Y-m-d H:i:s', $row['purchasedate']);
// calculate seconds
$seconds = $now->getTimeStamp() - $purchaseDate->getTimeStamp();
But the SQL solution suits this question better.
Try with the SQL query:
SELECT UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate) as second from countsec
or this:
SELECT TO_SECONDS(NOW()) - TO_SECONDS(purchasedate) as second from countsec;
From MySQL Date and Time Functions
I am not understanding why you need to store this in a column in the table. As soon as it's stored, the value is old, and it will need to be updated again. (Don't do this.) But setting that issue aside for a moment...
As to why your code isn't "working"... your UPDATE statement is updating every row in the table. You've previously fetched one row from the table, and then calculated one value, and then the UPDATE statement doesn't have a WHERE clause to identify which row(s) you want to update, so every row gets updated with the same value. That's a big part of why your code isn't working.
And, there's no need to run a SELECT statement before you run an UPDATE. If you want to update all rows in the table, you set the column to an expression that returns the number of seconds between the current date and time and the date and time stored in purchasedate column.
One convenient way to do that is to use the UNIX_TIMESTAMP function to convert each of the DATETIME values into an integer value (number of seconds), and subtract them. For example:
UPDATE count_sec
SET `second` = UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate)
As an alternative, you could use the TIMESTAMPDIFF function for an equivalent result:
UPDATE count_sec
SET `second` = TIMESTAMPDIFF(SECOND,NOW(),purchasedate)
But back to the issue of why this is wrong. You do not want to store second column in the table.
When you run a SELECT statement to return a row from the table, the value in this column is going to old.
Instead, you could just return a calculated value, calculated as of the time the SELECT statement runs, by including one of those expressions in the SELECT list. For example:
SELECT user_id
, purchasedate
, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate) AS `calc_second`
, `second` AS `old_stored_value`
FROM count_sec
ORDER BY user_id
The point I'm trying to emphasize here... do not store the second value in the table. You'll be chasing it, and continuously updating every row in table, whether that's every five minutes or every five seconds. And the stored value is always going to be "old".
Why do you need that? If you want to find out which rows in the table have second between 60 and 120, for example, if you intend to run this query:
SELECT user_id
FROM count_sec
WHERE second > 120
AND second <= 60
You could just as easily rewrite that based on purchasedate
SELECT user_id
FROM count_sec
WHERE purchasedate > NOW() - INTERVAL 120 SECOND
AND purchasedate <= NOW() - INTERVAL 60 SECOND
And, you won't be "chasing" continuous updates of the rows in the table, generating rollbackup, recording changes in the InnoDB log, writing the UPDATE statements in the binary logs. If you are running replication slaves, those statements have to be read from the log and re-executed on the slaves. All in all, storing second is just a poor design choice.
You can use TIMESTAMPDIFF() function like below. See Documentation
SELECT TIMESTAMPDIFF(SECOND, NOW(), purchasedate)
from count_sec;
(OR) if you want to UPDATE
UPDATE count_sec SET `second` = TIMESTAMPDIFF(SECOND, NOW(), purchasedate);
Per your comment, if you want to delay for 5 minutes then either you can use
SLEEP(seconds) function
(OR)
Wrap your updation code in a stored procedure and run that in every 5 minutes (probably using some scheduler job)

UPDATE row relative to CURRENT_TIMESTAMP is not giving the correct value

I am trying to update a MySQL table with an 'expiration date'. I've collected a timestamp value for all my rows as people have registered into the table but now I want to create an expiration date relative to that timestamp (not to relative to the current time). Here's my code:
$timestamp = $row['timestamp'];
$sql_update = "
UPDATE jobs
SET expiration_date = DATE_ADD('$timestamp',INTERVAL 56 DAY)";
$result_update = $mysqli->query($sql_update) or die($mysqli->error);
Understand that this is being run in a 'while' loop so it's running through each row of the table an updating them as it goes. The issue is that I ran it once and all it did was update the 'expiration_date' row to 56 days from NOW not 56 days from the timestamp's value. The timestamp is set on CURRENT_TIMESTAMP for when the a new entry is registered which I'm assuming is the problem. I've echoed out $timestamp to troubleshoot and it echoes out the correct value (not the current time) when I echo it but when it goes to actually update the expiration date it seems to be drawing from the fact that it's a CURRENT_TIMESTAMP. Is there a way to explicit query for the value of the timestamp?
I'm hoping to find a way that doesn't involved restructuring the database. I know I could have it so instead of a timestamp row, I could make it a datetime row and set it to the value of NOW() when database is being initially queried to add a row but I'd prefer to find a solution within the way the table is currently set up. Thanks!
Probably somehow the value in $timestamp is wrong.
Try adding the timestamp directly in the query using the column name. E.g. : DATE_ADD(timestamp,INTERVAL 56 DAY)
What you are currently doing, hardly makes any sense. You first get the timestamp from the database and assign it to the $timestamp variable, only to use it in the query again..
In situations like these, you can better directly use the column name to access the data in your query.
I wonder why are you running this query in loop ?
You can use only one sql statement. Update from select;
update jobs a set a.expiration_date = DATE_ADD(a.timestampFieldName,INTERVAL 56 DAY), a.timestampFieldName = a.timestampFieldName;
I supose that there is some "bug" (don't know) in MySQL because if you don't add a.timestampFieldName = a.timestampFieldName then this field will be set to current timestamp;

storing time to a db and comparing with current time

i have a simple question, that just needs verification, it's about how time is stored in mysql, here is how i store it:
if(isset($_SESSION['user']))
{
$u_id=$_SESSION['user'];
//insert current time to db, i set the type of time to TIME
$query="INSERT INTO time(id,u_id,time) VALUES('NULL','".$u_id."',CURTIME())";
mysql_query($query);
}
that is how i store it, now i would also need to compare it to a value, later on:
//set current time
$curr_time=time();
//set maximum time to 5min
$max=300;
//get previous time from db
$query="SELECT * FROM time";
$result=mysql_query($query);
$row=mysql_fetch_array($result);
$prev_time=$row['time'];
//get difference in time
$diff=$curr_time-$prev_time;
//if max time is surpassed
if($diff>$max)
{
echo "maximum time surpassed!";
}
that's the simple code, first of all, is the syntax for inserting the time to the table okay(the CURTIME() thing), also is the comparison fine, will the result stored in $diff yield seconds?thank you, and sorry if you think this question is a waste of time.
CURTIME() will only give you the time, you likely want NOW() which is the date and time. Then you will need to use strtotime to convert the saved value from the database to seconds since epoch.
Do it in your query:
$query = "SELECT id FROM time WHERE time + INTERVAL 5 MINUTES > NOW()";
is there are no results, time has passed.
MySQL has terrific time and date handling functions. Use them.
(I'd also add some extra parts in the WHERE clause, if you have more than one record, you'll be looking at the wrong one probably.)
Since CURTIME is only on a daily basis and I suspect you want your function to cover the span over days I'd suggest you use NOW() instead as it gives you this format instead:
2012-11-06 09:39:34
also is the comparison fine, will the result stored in $diff yield seconds?
You can't directly compare mysql CURTIME() with time() function in PHP.
For example:
In MySql:
CURTIME() will return only time.
select CURTIME();
+-----------+
| CURTIME() |
+-----------+
| 14:15:11 |
+-----------+
In PHP
time() will return current Unix timestamp.
echo time();
1352191547
Look at sberry's answer for compassion.

A not working mysql delete query. Why?

I have a table with 3 rows and one of those contains a unique time code (ex: 1308162911). There are a lot of these records but I want to delete all records which are bigger than one day (AKA 86400 seconds). I have this query but it doesn't work (nothing happens):
$db = mysql_connect($hostname, $db_user, $db_password);
mysql_select_db($database,$db)or die( "Unable to select database");
$now = time() - 86400;
$delete = ("DELETE FROM $tbl WHERE time > '$now'");
I'm not sure about MySQL, but probably you need something like that:
DELETE FROM $tbl WHERE DATEDIFF('$now', time) > INTERVAL 1 DAY
How about something like this:
$yesterday = strtotime('-1 day');
$delete = "DELETE FROM $tbl WHERE time > FROM_UNIXTIME($yesterday)";
The above query will delete all rows where the "time" value is greater than exactly 24 hours ago. This assumes that the "time" field is a TIMESTAMP, DATETIME or DATE type. If you want to delete records that are older than a day, change the > for a <.
select * from table
where now() - interval 1 day > from_unixtime(unix_timestamp_field)
if this is what you're lookin for convert the select into a delete query
This should work:
DELETE FROM $tbl
WHERE FROM_UNIXTIME(`time`) > DATE_SUB(NOW(), INTERVAL 1 DAY);
Or otherwise, in your code, I think you should remove the single-quotes around $now. However, I think it is a good idea to do it all as part of a MySQL query to avoid any time differences between PHP and MySQL if they are both running in different time-zones
Unix timestamp increases as time goes on so your query will delete all records more recent than 24 hours ago, not longer than 24 hours ago.
You should be OK to remove the single quotes around the timestamp value too.
If you're still having a problem please can you include the line of code that executes mysql_query() and the format of the database (output of SHOW CREATE TABLE myTable)

Categories