198

I am storing the last login time in MySQL in, datetime-type filed. When users logs in, I want to get the difference between the last login time and the current time (which I get using NOW()).

How can I calculate it?

trejder
  • 17,148
  • 27
  • 124
  • 216
Devesh Agrawal
  • 8,982
  • 16
  • 82
  • 131
  • http://stackoverflow.com/questions/2546053/mysql-difference-between-two-timestamps-in-days/28451483#28451483 – Kamlesh Kumar Feb 11 '15 at 10:06
  • Does this answer your question? [How to get the difference between two timestamps in seconds](https://stackoverflow.com/questions/3528219/how-to-get-the-difference-between-two-timestamps-in-seconds) – jdhao Oct 02 '22 at 15:29

4 Answers4

357

USE TIMESTAMPDIFF MySQL function. For example, you can use:

SELECT TIMESTAMPDIFF(SECOND, '2012-06-06 13:13:55', '2012-06-06 15:20:18')

In your case, the third parameter of TIMSTAMPDIFF function would be the current login time (NOW()). Second parameter would be the last login time, which is already in the database.

trejder
  • 17,148
  • 27
  • 124
  • 216
FSP
  • 4,677
  • 2
  • 19
  • 19
  • That is to update the last login right?? what i want is like in stackoverflow your question posted 2s ago, 30s ago, 2 min ago.. etc. I want similar kind of functionality. For example there is one table say REQUESTS (id, message, timestamp). timestamp while storing will be NOW() . while i run a query, select * from requests, instead of displaying that value it should display id, message and how much time back request was posted. – Devesh Agrawal Jun 06 '12 at 03:29
  • 1
    While a am executing the query SELECT TIMESTAMPDIFF(SECOND, NOW(), 'select lastLoginTime from requests where id = '2' ').. Its returning NULL. Any idea why?? – Devesh Agrawal Jun 06 '12 at 03:49
  • what is the output of select lastLoginTime from requests where id = '2' ? – FSP Jun 06 '12 at 03:53
  • SELECT TIMESTAMPDIFF(SECOND,NOW(),'2012-06-06 08:07:36'); Try This! – FSP Jun 06 '12 at 04:08
  • YEs that is working, But i need to fetch the second parameter from table. How to achieve that. Infact i want to avoid nested query. Any Idea? – Devesh Agrawal Jun 06 '12 at 04:11
  • Try SELECT TIMESTAMPDIFF(SECOND,NOW(), TIMESTAMP(SELECT lastLoginTime from requests where id = '2') ); – FSP Jun 06 '12 at 04:21
  • Hi Kindly let me know how to pass "SELECT nid_date, FROM demo where demo_status='2' and TIMESTAMPDIFF(HOUR, 'nid_date', '2015-08-06 14:18:54') = 3" inside the function – nilesh Aug 06 '15 at 05:52
11

my two cents about logic:

syntax is "old date" - :"new date", so:

SELECT TIMESTAMPDIFF(SECOND, '2018-11-15 15:00:00', '2018-11-15 15:00:30')

gives 30,

SELECT TIMESTAMPDIFF(SECOND, '2018-11-15 15:00:55', '2018-11-15 15:00:15')

gives: -40

ingconti
  • 10,876
  • 3
  • 61
  • 48
9

If your start and end datetimes are on different days use TIMEDIFF.

SELECT TIMEDIFF(datetime1,datetime2)

if datetime1 > datetime2 then

SELECT TIMEDIFF("2019-02-20 23:46:00","2019-02-19 23:45:00")

gives: 24:01:00

and datetime1 < datetime2

SELECT TIMEDIFF("2019-02-19 23:45:00","2019-02-20 23:46:00")

gives: -24:01:00

Adi
  • 91
  • 1
  • 3
2

I don't think the accepted answer is appropriate. For example, if the difference between last login time and current time is 8 hours then getting the difference in seconds is illogical. The correct format will be in hours, minutes and seconds. I have illustrated this as follows -

Here, I create a table login_info table to store login information of users.

CREATE TABLE login_info (
    -> user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    -> last_login DATETIME NOT NULL,
    -> PRIMARY KEY (user_id)
    -> );

Then I populate the table using some random values -

INSERT INTO login_info (last_login) VALUES 
    -> ("2021-09-22 09:32:44"),
    -> ("2021-09-22 13:02:57"),
    -> ("2021-09-21 23:43:21"),
    -> ("2021-09-22 04:43:39"),
    -> ("2021-09-22 17:23:21");

Now I calculate the difference between last_login and current_time as follows:

CREATE TABLE login_dur_in_sec AS 
    -> SELECT user_id,
    -> TIMESTAMPDIFF(SECOND, last_login, NOW()) AS diff
    -> FROM login_info;
SELECT * FROM login_dur_in_sec;
+---------+-------+
| user_id | diff  |
+---------+-------+
|       1 | 28580 |
|       2 | 15967 |
|       3 | 63943 |
|       4 | 45925 |
|       5 |   343 |
+---------+-------+
CREATE TABLE hour_section AS 
    -> SELECT user_id,
    -> FLOOR (diff / 3600) AS hour_part 
    -> FROM login_dur_in_sec;
CREATE TABLE minute_section AS 
    -> SELECT user_id, 
    -> FLOOR (MOD (diff, 3600)/ 60) AS minute_part
    -> FROM login_dur_in_sec;
CREATE TABLE second_section AS
    -> SELECT user_id,
    -> MOD (MOD (diff, 3600), 60) AS second_part
    -> FROM login_dur_in_sec;
CREATE TABLE login_dur AS 
    -> SELECT h.user_id, h.hour_part, m.minute_part, s.second_part
    -> FROM hour_section AS h INNER JOIN minute_section AS m
    -> ON h.user_id = m.user_id
    -> INNER JOIN second_section AS s
    -> ON m.user_id = s.user_id;
CREATE TABLE login_dur_trunc AS 
    -> SELECT user_id,
    -> CONCAT (hour_part, ":", minute_part, ":", second_part) AS login_duration
    -> FROM login_dur;
SELECT * FROM login_dur_trunc;
+---------+----------------+
| user_id | login_duration |
+---------+----------------+
|       1 | 8:14:46        |
|       2 | 4:44:33        |
|       3 | 18:4:9         |
|       4 | 13:3:51        |
|       5 | 0:24:9         |
+---------+----------------+

Here, the answer given by @Adi won't work always as pointed out by @CaiusJard.

Payel Senapati
  • 1,134
  • 1
  • 11
  • 27