UNIX_TIMESTAMP() repeated more than once in MySQL request - mysql

I need to get current date (and time 00:00:00) epoch timestamp in MySQL request. I want to do this with math expression: (UNIX_TIMESTAMP() - (UNIX_TIMESTAMP() % 86400)).
But this calls UNIX_TIMESTAMP() more than once; so the question is - is there a possibility that two UNIX_TIMESTAMP() functions return different time? What is the workaround in this case?
Or maybe MySQL executes UNIX_TIMESTAMP() once, and replaces all other calls with current timestamp and no workaround needed?

You could use UNIX_TIMESTAMP(NOW()), because NOW() returns the timestamp when the statement began to execute, so it would behave consistently across multiple calls in the same statement.
NOW() returns a constant time that indicates the time at which the
statement began to execute. (Within a stored function or trigger,
NOW() returns the time at which the function or triggering statement
began to execute.)

SELECT #ut:=UNIX_TIMESTAMP(), (#ut - (#ut % 86400)) AS ep;

You may simply use UNIX_TIMESTAMP(), which will return the start time of the current query.
This isn't explicitly documented — the docs make general reference to the stability of "Functions that return the current date or time ..." — but it is so.

Related

Is the SQL NOW() function dynamic or static when updating large tables from a single query?

If i write a single SQL statement that updates a date field on a very large MySQL database table is the SQL NOW() function's output dynamic in that it changes with the time while it runs or does it stay the same for every data field and uses its start time?
IE; will:
UPDATE `table` SET `date` = NOW()
always result in the same result (eg. 2016-10-17 15:33:10 ) in all field regardless if it takes < 1 second or 1 hour to process?
If it is dynamic. I would like a little bit of help to create a statement where it's not.
It does stay same for every data field and uses the execution start time. Head over to check it out.
http://www.mysqltutorial.org/tryit/query/mysql-now/#3
If you run the code you will notice that the time remain same with 5s sleep time.
There is another function SYSDATE() which is dynamic and always return the current time. This link might help you more.

How to make MySQL() NOW() function use client's timezone?

I am using the NOW() function to store date and time, but the server timezone ( which is my own ) will obviously not work for the whole world.
What I want is for now() always to use the CLIENT timezone, whichever it may be.
How can this be achieved?
NOW() executes on current execution timezone (DB Server Timezone). You can use CONVERT_TZ(dt,from_tz,to_tz) function along with NOW() to get a different timezone representation like
SELECT CONVERT_TZ(NOW(),'GMT','EST');
Either way, unless you determine the TZ info of client; at DB end, your DB server has no way determining that.

Get unix timestamp from mysql database with offset applied

I have the offset in seconds to UTC, all timestamps stored on the database are in UTC, how to apply the offset during selection queries,
mysql_query("SELECT * FROM table WHERE unix_timestamp=unix_timestamp with offset applied");
mysql_query("INSERT INTO table (unix_timestamp) VALUES(UNIX_TIMESTAMP())");
I'd want to insert in UTC time to the database and retrieve in local time.
On PHP:
date_default_timezone_set('UTC');
$user_timezone_offset=-7200; // -2
Could I substract on select's runtime of mysql to the unix_timestamp field $user_timezone_offset and that would be it?
I am inserting in UTC which is what I need apparently, but for selection in user's local time I'd need to apply the offset to the timestamp stored in the database somehow.
Edit: I just came across this:
$user_timezone_offset="-2:00";
FROM_UNIXTIME(CONVERT_TZ(unix_timestamp,'+00:00','$user_timezone_offset'))
Would need to know how to apply it to a select query making the selection of unix_timestamp converted for comparison inside the select and the result also becoming modified for php's fetch_array
This seems to be the solution:
SELECT *, Unix_Timestamp(CONVERT_TZ(FROM_UNIXTIME(unix_timestamp), '+00:00', '$user_timezone_offset')) as unix_timestamp
Actually this has a problem - although on
mysql_fetch_array($result){ $row['unix_timestamp']; }
comes converted while checking on
WHERE unix_timestamp=value //assuming unix_timestamp
to be converted on the select - in there it is not converted and another
Unix_Timestamp(CONVERT_TZ(FROM_UNIXTIME(unix_timestamp), '+00:00', '$user_timezone_offset'))
has to be called for unix_timestamp to be "converted" each time a check is to be made against the converted value.
I think you may be overcomplicating the issue.
Timestamps are always UTC. When you retrieve a timestamp in PHP, it is in UTC.
When you convert a timezone using the date() function for example, it displays in whatever timezone the php.ini setting date.timezone is set to.
Therefore, if you have users with specific timezones, just call date_default_timezone_set() with the appropriate timezone prior to displaying dates in local time.
If you use the DateTime class, then you can specify the desired timezone when you construct the object.
Unless you have a very specific reason, there should be no need to perform timezone conversions when you fetch timestamps from the database. PHP handles this all for you.

mysql now() function

What's the SQL way of doing this:
$now = date('Y-m-d H:i:s', time())
SELECT * FROM table WHERE '$now' > time
Is it:
SELECT * FROM table WHERE now() > time
Your second example is the correct pure SQL method of doing it.
SELECT * FROM table WHERE NOW() > `time`
Although I find it more readable to reverse them, as it seems to make better logical sense to think the value of time is before now`. This really makes no difference though, and is based on my preference.
SELECT * FROM table WHERE `time` < NOW()
There are many more native MySQL date functions you can use in your queries, described in the MySQL documentation.
For example, to compare against 5 minutes ago, use DATE_SUB()
SELECT * FROM table WHERE `time` < DATE_SUB(NOW(), INTERVAL 5 MINUTE)
I don't understand question - first example is calculating date according to your php backend, second using mysql server's builtin function. essentialy effect is the same.
And if you ever considered, now() function in mysql is deterministic (it will replicate correctly to slaves), so even in master-slave environment both snippets of code have no difference, as long as php backend and sql server have synchronized clocks.
just to clarify: of course if your php backend and mysql clocks are not synchronized there will be differences between both snippets of code, but in normal environment this should not happen, at least be irrelevant.

Implicit cast from now() to a date field

I have an issue with MySQL 5.1. A datetime data type isn't implicitly casted to match a date column.
SELECT * FROM my_table WHERE my_date_field = NOW()
This request doesn't return any rows using MySQL 5.1, but works well with version 5.0.
If we use CURDATE() instead of NOW() it works both in MySQL 5.0 and MySQL 5.1.
If the cast is explicit (CAST(NOW() AS DATE)), it also works both in MySQL 5.0 and MySQL 5.1.
The problem only appears with implicit cast from datetime to date. Doesn't anyone already encountered this issue or has a clue about how to solve this problem?
I know it's not the best to use NOW() instead of CURTIME(), but this isn't the question here. It is currently used in an application and the purpose is to avoid rewriting everything.
Thanks!
This was fixed in MySQL 5.1.17 to allow CURDATE() to evaluate to less than NOW() when stored in a DATE column.
Now, when comparing a DATE to a DATETIME, they are compared as DATETIME. When a DATE is cast to a DATETIME, it has a zero hour.
If my_date_field is '2010-01-01' AND NOW() is '2010-01-01 05:01:01', when they are compared, my_date_field is promoted to '2010-01-01 00:00:00', which is obviously less than '2010-01-01 05:01:01'.
Originally, when the left side was a column, the promotion from DATE to DATETIME didn't occur. However, apparently they thought it was more consistent to always promote it.
Sorry, but you just got lucky that it worked before. A date that has a zero hour should evaluate to less than the same date with a non-zero hour.
Unfortunately, there is no way to turn off this "bug fix". Your only solution is to change NOW() to CURDATE() or roll back to a prior version.
Actually, you could compile your own version and either undo the "bug fix" or override the NOW() function.
The behaviour makes sense because NOW() is of the type DATETIME, and CURDATE() of the type DATE.
As for why the variables are cast in one server version, and not in the other - this sounds more like a difference in server modes, i.e. the one instance where the cast fails being more strict than the other.
An interesting point from that document (not sure whether this is your problem but it could be): ALLOW_INVALID_DATES:
This mode is implemented in MySQL 5.0.2. Before 5.0.2, this was the default MySQL date-handling mode. As of 5.0.2, the server requires that month and day values be legal, and not merely in the range 1 to 12 and 1 to 31, respectively. With strict mode disabled, invalid dates such as '2004-04-31' are converted to '0000-00-00' and a warning is generated. With strict mode enabled, invalid dates generate an error. To allow such dates, enable ALLOW_INVALID_DATES.
Anyway, I'm not sure whether it makes sense digging through changelogs trying to find out what changed when. I would tend to make the behaviour work in both situations (i.e., if I understand you correctly, use CURDATE()) and be done with it.
only compare the date part of your datetime column:
SELECT * FROM my_table WHERE DATE(my_date_field) = DATE(NOW())