getting number of hours until the next event - mysql

I've got a table with this data:
[ID] [event_name] [last_event]
1 stats 2011-01-01 01:47:32
last_event is a timestamp. The event occurs every 48 hours (it's a cron job). I'd like to show my users the number of hours until the event executes again.
So far I've got:
SELECT (lastFinish + INTERVAL 48 HOUR) FROM `cron_status`
which gives me the exact time and date of the next occurence: 2011-01-03 01:47:32. So I figured if I subtracted the current datetime...
SELECT ((lastFinish + INTERVAL 48 HOUR) - SYSDATE()) FROM `cron_status`
which (I think?) gives me the difference in unix time: 1980015. But if I divide that by 3600 to convert the seconds to hours...
SELECT (((lastFinish + INTERVAL 48 HOUR) - SYSDATE())/3600) FROM `cron_status`
I get numbers an order of magnitude too high: 549.99.
Where am I going wrong? The target is returning the number of hours until the next execution.
Thank you!

The result can be obtained directly, using the timediff() MySQL function:
SELECT timediff(lastFinish + INTERVAL 48 HOUR, now()) FROM cron_status;
should display the time as hh:mm:ss. Assuming lastFinish is a datetime.
In order to get the answer in hours instead,
SELECT timestampdiff(HOUR, now(), lastFinish + INTERVAL 48 HOUR) FROM cron_status;
Note that timediff does arg1 - arg2 while timestampdiff does arg2 - arg1.

Related

How sum 24 hours to time mysql?

I've got a column time type in mysql, i want to add 24 hours to this hour, i try with code below:
SELECT SUBSTRING(CAST(DATE_ADD(STR_TO_DATE('23:00', '%k:%i'), INTERVAL (TIME_TO_SEC('24:00') / 60) MINUTE) AS CHAR(8)), 1,5)
I need to return 23:00 again (because i add 24 hours but that 23:00 is of the next day) but this code return me 47:00.
Some help?
I think you're looking for ADDTIME
SELECT ADDTIME(‘23:00’,’24:00’)
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
You need to first convert the column value to a datetime, add the hours, and then convert the result back to time:
select cast(date_add(cast(time_column as datetime), interval 24 hour ) as time)
from yourtable;
Example:
select cast(date_add(cast(cast('23:00' as time) as datetime), interval 24 hour ) as time)
The TIME type allows you to store up to (but not including) 839 hours (positive and negative). That's great if you need to store duration, but not so much if you want to store time of day. If you want the latter you should consider the DATETIME type instead.

Data from current date to 30 days after current days

Why this query is not working
SELECT * FROM history WHERE DATE(date) < CURDATE() + 30
I am trying to get the data from 30 days but my query is not working.Why
What does +30 mean? Days? Years? Months? Hours? You need to use (the proper syntax) a format MySQL understands:
SELECT * FROM history WHERE DATE(date) < CURDATE() + INTERVAL 30 DAY
To get the data from today on to 30 days after current day, you've got to set an upper and an lower limit, so use:
SELECT * FROM history WHERE
date >= CURDATE()
AND
date < CURDATE() + INTERVAL 31 DAY
Please note that by not using a function on your date column you won't prohibit MySQL to use an index on this column.
The lower limit should be obvious, the upper limit means that you've got the complete day that's 30 days later than today. If you use + INTERVAL 30 DAY instead this last day is excluded from the result.
Because you're not using the right construct, try:
SELECT * FROM history WHERE DATE_ADD(date, INTERVAL 30 DAY);

Mysql time range query using extract

I'm trying to get an mysql query similar to date_trunc in psql.
Unfortunate Mysql do not have date_trunc function and I found I can use extract instead in Mysql.
What I want to do is write a script which i will run let say 10 minutes past each hour but I want to only select data from begin of an hour till end of this hour.
For example I will run script 12:10 and I want to display data from 11:00:00 till 11:59:59.
In PSQL query would look like that:
SELECT *
FROM data
WHERE time > ( date_trunc('hour',now()) - interval '1 hour' )
AND time <= ( date_trunc('hour',now()) ) ORDER BY time;
I was trying to use extract in similar fashion but I have no rows returned or error :/
Query below returns for example some narrowed data but it's like 2 hours each day from day one when database was started not last hour only:
SELECT *
FROM data
WHERE extract(hour from cr_date) between extract(hour from now()) - interval 1 hour)
AND extract(hour from now())
ORDER BY cr_date;
Any ideas how this can be achieved? or what I'm doing wrong in this query?
Hour is only an integer, so it's finding any matches between , for example, 9 and 10, regardless of the date.
I would recommend
select * FROM data
where cr_date >= date(now()) + INTERVAL hour(now())-1 HOUR
and cr_date <= date(now()) + INTERVAL hour(now()) HOUR
date(now()) returns midnight, and hour(now()) returns the number of hours since midnight
so, at 11:10 am, it should result in a results between midnight + 10 hours (10 am) and midnight + 11 hours (11 am)

MYSQL Date Time Round To Nearest Hour

I have a date time field in a MySQL database and wish to output the result to the nearest hour.
e.g. 2012-04-01 00:00:01 should read 2012-04-01 00:00:00
Update: I think https://stackoverflow.com/a/21330407/480943 is a better answer.
You can do it with some date arithmetic:
SELECT some_columns,
DATE_ADD(
DATE_FORMAT(the_date, "%Y-%m-%d %H:00:00"),
INTERVAL IF(MINUTE(the_date) < 30, 0, 1) HOUR
) AS the_rounded_date
FROM your_table
Explanations:
DATE_FORMAT: DATE_FORMAT(the_date, "%Y-%m-%d %H:00:00") returns the date truncated down to the nearest hour (sets the minute and second parts to zero).
MINUTE: MINUTE(the_date) gets the minute value of the date.
IF: This is a conditional; if the value in parameter 1 is true, then it returns parameter 2, otherwise it returns parameter 3. So IF(MINUTE(the_date) < 30, 0, 1) means "If the minute value is less than 30, return 0, otherwise return 1". This is what we're going to use to round -- it's the number of hours to add back on.
DATE_ADD: This adds the number of hours for the round into the result.
Half of the hour is a 30 minutes. Simply add 30 minutes to timestamp and truncate minutes and seconds.
SELECT DATE_FORMAT(DATE_ADD(timestamp_column, INTERVAL 30 MINUTE),'%Y-%m-%d %H:00:00') FROM table
soul's first solution truncates instead of rounding and the second solution doesn't work with Daylight Savings cases such as:
select FROM_UNIXTIME(UNIX_TIMESTAMP('2012-03-11 2:14:00') - MOD(UNIX_TIMESTAMP('2012-03-11 2:14:00'),300));
Here is an alternate method (1):
DATE_ADD(
tick,
INTERVAL (IF((MINUTE(tick)*60)+SECOND(tick) < 1800, 0, 3600) - (MINUTE(tick)*60)+SECOND(tick)) SECOND
)
If you don't need to worry about seconds you can simplify it like this (2):
DATE_ADD(
tick,
INTERVAL (IF(MINUTE(tick) < 30, 0, 60) - MINUTE(tick)) MINUTE
)
Or if you prefer to truncate instead of round, here is simpler version of soul's method (3):
DATE_SUB(tick, INTERVAL MINUTE(tick)*60+SECOND(tick) SECOND)
EDIT: I profiled some of these queries on my local machine and found that for 100,000 rows the average times were as follows:
soul's UNIXTIME method: 0.0423 ms (fast, but doesn't work with DST)
My method 3: 0.1255 ms
My method 2: 0.1289 ms
Ben Lee's DATE_FORMAT method: 0.1495 ms
My method 1: 0.1506 ms
From How to round a DateTime in MySQL?:
It's a little nasty when you do it with datetime data types; a nice candidate for a stored function.
DATE_SUB(DATE_SUB(time, INTERVAL MOD(MINUTE(time),5) MINUTE ),
INTERVAL SECOND(time) SECOND)
It's easier when you use UNIXTIME timestamps but that's limited to a 1970 - 2038 date range.
FROM_UNIXTIME(UNIX_TIMESTAMP(time) - MOD(UNIX_TIMESTAMP(time),300))
Good luck.
To round down to the current hour, select:
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(column_name) / 3600) * 3600).
The value is expressed in the current time zone doc
This will return the next hour, that is '2012-01-02 18:02:30' will be converted into '2012-01-02 19:00:00'
TIMESTAMPADD(HOUR,
TIMESTAMPDIFF(HOUR,CURDATE(),timestamp_column_name),
CURDATE())
Instead of CURDATE() you can use an arbitrary date, for example '2000-01-01'
Not sure if there could be problems using CURDATE() if the system date changes between the two calls to the function, don't know if Mysql would call both at the same time.
to get the nearest hour would be:
TIMESTAMPADD(MINUTE,
ROUND(TIMESTAMPDIFF(MINUTE,CURDATE(),timestamp_column_name)/60)*60,
CURDATE())
changing 60 by 15 would get the nearest 15 minutes interval, using SECOND you can get the nearest desired second interval, etc.
To get the previous hour use TRUNCATE() or FLOOR() instead of ROUND().
Hope this helps.
If you need to round just time to next hour you may use this:
SELECT TIME_FORMAT(
ADDTIME(
TIMEDIFF('16:15', '10:00'), '00:59:00'
),
'%H:00:00'
)
I think this is the best way, since it also will use the least amount of resources-
date_add(date(date_completed), interval hour(date_completed) hour) as date_hr

MySQL "day" - how do I get an exact figure?

I am using this function to filter query results that are older than 60 days:
s.timeSubmitted >= ( CURDATE() - INTERVAL 60 DAY )
The problem is, the "60 days" part doesn't seem to be an exact figure. I want it to filter right where s.timeSubmitted is longer than 60 days, down to the exact second of s.timeSubmitted.
How do I write "60 Days" as an exact figure (down to the second)?
The problem is that CURDATE() returns a DATE type, not a DATETIME type (an instant in time). The result of subtracting an interval from a DATE is also a DATE.
Instead, try this:
s.timeSubmitted >= ( NOW() - INTERVAL 60 DAY )
This gives you what you want, because NOW() returns a DATETIME, so the result of the subtraction is also a DATETIME.
INTERVAL 60 DAY is exact - your problem is that CURDATE() isn't. It returns whole days, not the current time.
Use NOW() instead!
I usually do
now()-interval 60 day
Assuming you want the same time of day 60 days ago;
s.timeSubmitted >= ( now() - interval 60 day);
Maybe an un-necessary note in this case; 1 day ago may be 23, 24 or 25 hours ago depending on DST changes, if you want a specific number of hours as an interval, don't use a day instead of 24 hours.