Reputation: 6131
I have a table that has a column row filled with a Javascript's, Date.now()
function.
The column name is update_time, and its sample value is 1571152209099
.
How can I make a Select for all rows that have todays date (taking into account only year, month and a day)?
I have tried something like this, but it get's me nowhere.
Select *
from program_end
where workout_rate between 0 and 1
AND FROM_UNIXTIME(update_time, '%YYYY-%MM-%DD') = CURDATE()
I also tried changing the time format:
Select *
from program_end
where FROM_UNIXTIME(update_time, '%Y-%m-%d') = CURDATE()
But no result whatsoever. Any insight is appreciated.
Upvotes: 0
Views: 82
Reputation: 108370
For insight, consider:
SELECT '1970-01-01' + INTERVAL ( 1571152209099 /1000) SECOND
returns:
_dt
--------------------------
2019-10-15 15:10:09.099000
We recognize that the 1571152209099
value from JavaScipt Date.now()
is integer milliseconds from the beginning of the era (Jan 1, 1970 midnight UTC).
Also consider:
SELECT TIMESTAMPDIFF(SECOND,'1970-01-01 00:00','2019-10-15 00:00')*1000 AS _dt_1
, TIMESTAMPDIFF(SECOND,'1970-01-01 00:00','2019-10-16 00:00')*1000 AS _dt_2
returns:
_dt_1 _dt_2
------------- --------------
1571097600000 1571184000000
The TIMESTAMPDIFF function is returning a difference in seconds; we multiply by 1000 to get milliseconds.
We recognize that any JavaScript Date.now()
milliseconds value that is greater than or equal to _dt_1
and is less than _dt_2
occurs sometime "on" the date '2109-10-15'
So, given update_time
is milliseconds since the beginning of the era...
In a query, I would compare the bare update_time
column to two literal values:
WHERE update_time >= 1571097600000
AND update_time < 1571184000000
Referencing the bare column has the advantage that MySQL can make use of an efficient range scan operation, with a suitable index available.
To derive those millisecond values from a given date value, we can do a calculation in an expression, like this:
WHERE update_time >= TIMESTAMPDIFF(SECOND,'1970-01-01', '2019-10-15' )*1000
AND update_time < TIMESTAMPDIFF(SECOND,'1970-01-01', '2019-10-15' + INTERVAL 1 DAY)*1000
^^^^^^^^^^
Those expressions on the right side get evaluated just one time at the start of the statement execution.
Note that if we wrap update_time
in a function, then that function has to be evaluated for every value of update_time
, for every row in the table (that isn't filtered out by some other predicate.)
Upvotes: 2
Reputation: 58524
Javascript's Date.now
is giving you milliseconds, whereas MySQL's FROM_UNIXTIME
expects seconds.
Unable to understand the epoch timestamp in milliseconds, FROM_UNIXTIME
is returning NULL, which is of course failing to match the current date.
mysql> SELECT FROM_UNIXTIME(1571152209099);
+------------------------------+
| FROM_UNIXTIME(1571152209099) |
+------------------------------+
| NULL | -- THIS IS YOUR PROBLEM
+------------------------------+
1 row in set (0.00 sec)
mysql> SELECT FROM_UNIXTIME(1571152209099/1000);
+-----------------------------------+
| FROM_UNIXTIME(1571152209099/1000) |
+-----------------------------------+
| 2019-10-15 10:10:09.0990 |
+-----------------------------------+
1 row in set (0.00 sec)
Try this:
FROM_UNIXTIME(FLOOR(update_time/1000), format...)
Upvotes: 1
Reputation: 222382
If you don't have dates in the future, you can simply do:
WHERE update_time >= UNIX_TIMESTAMP(CURDATE())
This will happily use an existing index on update_time
.
If you have dates in the future that you need to exclude from the resultset, then:
WHERE
update_time >= UNIX_TIMESTAMP(CURDATE())
AND update_time < UNIX_TIMESTAMP(CURDATE() + INTERVAL 1 DAY)
Upvotes: 1