CURRENT_TIMESTAMP 以毫秒为单位
Posted
技术标签:
【中文标题】CURRENT_TIMESTAMP 以毫秒为单位【英文标题】:CURRENT_TIMESTAMP in milliseconds 【发布时间】:2012-03-26 07:50:56 【问题描述】:有什么方法可以从 mysql
或 PostgreSql
(或其他出于好奇的其他人)的时间戳中获取毫秒数?
SELECT CURRENT_TIMESTAMP
--> 2012-03-08 20:12:06.032572
有没有这样的:
SELECT CURRENT_MILLISEC
--> 1331255526000
或者唯一的选择是使用era
中的DATEDIFF
?
【问题讨论】:
FROM_UNIXTIME(UNIX_TIMESTAMP(CONCAT(DATE(NOW()), ' ', CURTIME(3))); 将创建一个以毫秒为单位的时间戳。调整 curtime 中的参数以更改小数位数。 @user1119648 - 哪个数据库?CURTIME(3)
的任何数据库都不支持NOW(3)
吗?所以CONCAT(DATE(NOW()), ' ', CURTIME(3))
可能只是NOW(3)
,至少在MySQL 5.6.4+ 中,FROM_UNIXTIME
和UNIX_TIMESTAMP
是相反的,所以FROM_UNIXTIME( UNIX_TIMESTAMP( whatever ) )
的结果是whatever
。你的长表达不是和NOW(3)
一样吗?
【参考方案1】:
对于 MySQL (5.6+),您可以这样做:
SELECT ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)
哪个会返回(例如):
1420998416685 --milliseconds
【讨论】:
在 DST 时区不可靠! (每年错一个小时)【参考方案2】:在 MySQL 中获取 Unix 时间戳以秒为单位:
select UNIX_TIMESTAMP();
详情:http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_unix-timestamp
未测试过 PostgreSQL,但根据此站点,它应该可以工作:http://www.raditha.com/postgres/timestamp.php
select round( date_part( 'epoch', now() ) );
【讨论】:
这不是精确到秒吗? 这是第二个。我误读了我认为的问题。我不认为 MySQL 返回毫秒,但如果你提供它们应该能够处理它们:***.com/questions/2572209/… 在 postgreSQL 中测试,可以工作,但它返回以秒为单位的舍入值,而不是像 bigint 那样的毫秒精确值。请参阅我对 postgreSQL 中的解决方案的回答:***.com/a/28760763/3197383【参考方案3】:在mysql中,可以使用uuid函数提取毫秒数。
select conv(
concat(
substring(uid,16,3),
substring(uid,10,4),
substring(uid,1,8))
,16,10)
div 10000
- (141427 * 24 * 60 * 60 * 1000) as current_mills
from (select uuid() uid) as alias;
结果:
+---------------+
| current_mills |
+---------------+
| 1410954031133 |
+---------------+
它也适用于旧的 mysql 版本!
感谢您访问此页面:http://rpbouman.blogspot.com.es/2014/06/mysql-extracting-timstamp-and-mac.html
【讨论】:
起初我笑了,但这是迄今为止我发现的唯一方法来获得 MySQL 5.5 中的确切时间......所以这就是解决方案 :) 干杯。 哇——太棒了!我希望他们永远不会修复这种行为。 如果您只需要MICROSECONDS,那么您可以使用:SELECT SUBSTR( CONV( CONCAT( SUBSTR(uid,16,3), SUBSTR(uid,10,4), SUBSTR(uid,1,8)), 16, 10) DIV 10, -6) FROM (SELECT UUID() AS uid) AS alias;
【参考方案4】:
MySQL 对时间戳的主要误解是默认情况下,MySQL 既返回也存储没有小数部分的时间戳。
SELECT current_timestamp() => 2018-01-18 12:05:34
可以转换为秒时间戳为
SELECT UNIX_TIMESTAMP(current_timestamp()) => 1516272429
添加小数部分:
SELECT current_timestamp(3) => 2018-01-18 12:05:58.983
可以转换为微秒时间戳
SELECT CAST( 1000*UNIX_TIMESTAMP(current_timestamp(3)) AS UNSIGNED INTEGER) ts => 1516272274786
在表格中存储有一些技巧。如果你的表是这样创建的
CREATE TABLE `ts_test_table` (
`id` int(1) NOT NULL,
`not_fractional_timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
MySQL 不会在其中存储小数部分:
id, not_fractional_timestamp
1, 2018-01-18 11:35:12
如果要在表格中添加小数部分,则需要以另一种方式创建表格:
CREATE TABLE `ts_test_table2` (
`id` int(1) NOT NULL,
`some_data` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`fractional_timestamp` timestamp(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
导致所需结果:
id, some_data, fractional_timestamp
1, 8, 2018-01-18 11:45:40.811
current_timestamp() 函数允许接收高达 6 的值,但我发现(至少在我在 Windows 上安装的 MySQL 5.7.11 版本中)小数精度 6 导致相同的 3 位数常量值尾巴,在我的例子中是 688
id, some_data, fractional_timestamp
1, 2, 2018-01-18 12:01:54.167688
2, 4, 2018-01-18 12:01:58.893688
这意味着 MySQL 真正可用的时间戳精度取决于平台:
在 Windows 上:3 在 Linux 上:6【讨论】:
【参考方案5】:在Mysql 5.7+可以执行
select current_timestamp(6)
更多详情
https://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html
【讨论】:
注意:这在 Mysql 5.6.4 中也可用:dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html 此外,current_timestamp
是 now
的同义词,因此 now(6)
是获取该值的更短的方法。
这实际上在 v 5.7.26 中不起作用。它会运行,但会返回类似 ''2019-06-24 12:05:50.931222"【参考方案6】:
Poster 要求 自 Epoch 以来 MS 的整数值,而不是自 Epoch 以来的时间或 S。
为此,您需要使用NOW(3)
,它将时间以小数秒为单位,精确到小数点后 3 位(即 MS 精度):2020-02-13 16:30:18.236
然后UNIX_TIMESTAMP(NOW(3))
获取自 epoc 以来的小数秒时间:
1581611418.236
最后,FLOOR(UNIX_TIMESTAMP(NOW(3))*1000)
将它变成一个漂亮的整数,对于自 epoc 以来的 ms:
1581611418236
使其成为 MySQL 函数:
CREATE FUNCTION UNIX_MS() RETURN BIGINT DETERMINISTIC
BEGIN
RETURN FLOOR(UNIX_TIMESTAMP(NOW(3))*1000);
END
现在运行SELECT UNIX_MS();
注意:本文都是手工抄的,如有错误欢迎指正;)
【讨论】:
不会 UNIX_TIMESTAMP()*1000 也能正常工作,因为 UNIX_TIMESTAMP() 以秒为单位? 你可以这样做,但你会失去最后 3 位数的粒度。您的建议只是在时间戳末尾添加 3 个 0。 啊,当然可以!这将使它一开始就和秒一样有用。 这应该是实际问题的正确答案。【参考方案7】:根据current documentation从PostgreSQL上的时间戳值中提取毫秒的正确方法是:
SELECT date_part('milliseconds', current_timestamp);
--OR
SELECT EXTRACT(MILLISECONDS FROM current_timestamp);
with return:秒字段,包括小数部分,乘以 1000。请注意,这包括完整的秒数。
【讨论】:
感谢 Falco,抱歉我不清楚,但我实际上需要当前时间戳(以毫秒为单位)。请参阅示例 您的解决方案返回从一天开始的毫秒数,而不是从 1970/01/17 开始。请参阅我对 postgreSQL 中的解决方案的回答:***.com/a/28760763/3197383【参考方案8】:用途:
Select curtime(4);
这会给你几毫秒。
【讨论】:
还要确保 DATETIME 列的长度为 6,用于存储它。您还需要 MySQL 5.6.x 以毫秒为单位工作。 给出 '11:08:31.1845' 所以不包括日期 @malhal 是正确的,没有给出所要求的问题的毫秒数。 在 MySQL > 5.6 中使用 - SELECT NOW(4);【参考方案9】:我发现在 MySql 中以毫秒为单位接收当前时间的最简单方法:
SELECT (UNIX_TIMESTAMP(NOW(3)) * 1000)
自 MySql 5.6.
【讨论】:
投了反对票的人,这个答案有什么问题?据我所知,它的工作原理是,请注意它返回一个以.000
结尾的十进制数而不是整数。
在夏令时结束时给出不正确的结果,如果在 DST 时区!【参考方案10】:
这些响应都没有真正解决 postgreSQL 中的问题,即:
获取日期字段的unix时间戳以毫秒为单位
我遇到了同样的问题,并测试了以前的不同响应,但没有令人满意的结果。
最后,我找到了一个非常简单的方法,可能是最简单的:
SELECT (EXTRACT (EPOCH FROM <date_column>::timestamp)::float*1000 as unix_tms
FROM <table>
即:
我们提取 pgSQL EPOCH,即 unix timestamp in floating seconds 从我们的列中以时间戳谨慎(在一些复杂的查询中,pgSQL如果此演员表不明确,可能会引发错误。请参阅) 然后我们将其转换为浮点数并乘以 1000 得到以毫秒为单位的值【讨论】:
【参考方案11】:在 PostgreSQL 中你可以使用:
SELECT extract(epoch from now());
在 MySQL 上:
SELECT unix_timestamp(now());
【讨论】:
在 MySQL 上只精确到秒,而不是毫秒。 在 postgreSQL 中,您的解决方案以小数秒为单位返回 unix 时间戳。请参阅我的回复,以毫秒为单位获取它作为 bigint :***.com/a/28760763/3197383 切勿将 UNIX_TIMESTAMP() 与 NOW() 一起使用,因为这将作为本地时间处理,并在夏令时的最后一小时失败!【参考方案12】:这是一个适用于 MariaDB 和 MySQL >= 5.6 的表达式:
SELECT (UNIX_TIMESTAMP(NOW()) * 1000000 + MICROSECOND(NOW(6))) AS unix_now_in_microseconds;
这取决于NOW() always returns the same time throughout a query;一个普通的UNIX_TIMESTAMP()
可能也可以,我不确定based on the documentation。对于 NOW()
函数的新精度参数,它还需要 MySQL >= 5.6(MariaDB 也可以)。
【讨论】:
如果您处于 DST 时区,UNIX_TIMESTAMP(NOW())
将在夏令时结束时的一小时内不正确。只需改用UNIX_TIMESTAMP()
,答案就可以了,尽管我不能 100% 确定闰秒期间会发生什么。【参考方案13】:
Postgres:SELECT (extract(epoch from now())*1000)::bigint;
【讨论】:
【参考方案14】:在 MariaDB 中你可以使用
SELECT NOW(4);
获取毫秒。也见here。
【讨论】:
【参考方案15】:在 PostgreSQL 中我们使用这种方法:
SELECT round(EXTRACT (EPOCH FROM now())::float*1000)
【讨论】:
【参考方案16】:对于mysql:
SELECT (UNIX_TIMESTAMP() * 1000) AS unix_now_in_microseconds; --- 1600698677000
【讨论】:
【参考方案17】:我觉得有必要继续完善,所以在MySQL中:
当前时间戳,以毫秒为单位:
floor(unix_timestamp(current_timestamp(3)) * 1000)
从给定 datetime(3) 开始的以毫秒为单位的时间戳:
floor(unix_timestamp("2015-04-27 15:14:55.692") * 1000)
以毫秒为单位的时间戳转换为日期时间(3):
from_unixtime(1430146422456 / 1000)
将 datetime(3) 转换为以毫秒为单位的时间戳:
floor(unix_timestamp("2015-04-27 14:53:42.456") * 1000)
【讨论】:
在夏令时时区,您的第一个示例将是错误的(相差一个小时),每年有一个小时。最好使用UNIX_TIMESTAMP()*1000+FLOOR(MICROSECONDS(UTC_TIME(3))*0.001)
【参考方案18】:
对于这里的每个人,只要听/读Doin的cmets就很好! UNIX_TIMESTAMP()
函数将在给出数据时间字符串时,根据 MySQL 连接或服务器的时区将 本地 时间联系到 unix 时间戳。如果在不同的时区处理夏令时,每年一小时,这会出错!
例如,在荷兰,10 月的最后一个星期日,在第一次到达 02:59:59 后的一秒,时间将再次设置回 02:00:00。当使用 MySQL 中的 NOW()
、CURTIME()
或 SYSDATE()
函数并将其传递给 UNIX_TIMESTAMP()
函数时,整个时间戳都会出错。
例如,2018 年 10 月 27 日星期六,时间和时间戳是这样的:
Local time | UTC Time | Timestamp | Timestamp using MYSQL's UNIX_TIMESTAMP(NOW(4))
----------------------------------+---------------------------+--------------+-----------------------------------------------------
2018-10-27 01:59:59 CET (+02:00) | 2018-10-26 23:59:59 UTC | 1540598399 | 1540598399
2018-10-27 02:00:00 CET (+02:00) | 2018-10-27 00:00:00 UTC | 1540598400 | 1540598400 + 1 second
2018-10-27 02:59:59 CET (+02:00) | 2018-10-27 00:59:59 UTC | 1540601999 | 1540601999
2018-10-27 03:00:00 CET (+02:00) | 2018-10-27 01:00:00 UTC | 1540602000 | 1540602000 + 1 second
2018-10-27 03:59:59 CET (+02:00) | 2018-10-27 01:59:59 UTC | 1540605599 | 1540605599
2018-10-27 04:00:00 CET (+02:00) | 2018-10-27 02:00:00 UTC | 1540605600 | 1540605600 + 1 second
但在 2019 年 10 月 27 日星期日,我们将时钟调整了一小时。因为本地时间,不包含+02:00或+01:00的信息,第一次和第二次转换时间02:00:00,都给出相同的时间戳(从第二次02:00开始) :00) 使用 MYSQL 的 UNIX_TIMESTAMP(NOW(4))
函数时。因此,在检查数据库中的时间戳时,它会这样做:+1 +1 +3601 +1 +1 ... +1 +1 -3599 +1 +1 等等。
Local time | UTC Time | Timestamp | Timestamp using MYSQL's UNIX_TIMESTAMP(NOW(4))
----------------------------------+---------------------------+--------------+-----------------------------------------------------
2019-10-27 01:59:59 CET (+02:00) | 2019-10-26 23:59:59 UTC | 1572134399 | 1572134399
2019-10-27 02:00:00 CET (+02:00) | 2019-10-27 00:00:00 UTC | 1572134400 | 1572138000 + 3601 seconds
2019-10-27 02:59:59 CET (+02:00) | 2019-10-27 00:59:59 UTC | 1572137999 | 1572141599
2019-10-27 02:00:00 CET (+01:00) | 2019-10-27 01:00:00 UTC | 1572138000 | 1572138000 - 3599 seconds
2019-10-27 02:59:59 CET (+01:00) | 2019-10-27 01:59:59 UTC | 1572141599 | 1572141599
2019-10-27 03:00:00 CET (+01:00) | 2019-10-27 02:00:00 UTC | 1572141600 | 1572141600 + 1 second
不幸的是,在转换当地时间时从 MySQL 的 UNIX_TIMESTAMP() 函数上中继是非常不可靠的!我们现在不使用SELECT UNIX_TIMESTAMP(NOW(4))
,而是使用下面的代码来解决问题。
SELECT ROUND(UNIX_TIMESTAMP() + (MICROSECOND(UTC_TIME(6))*0.000001), 4)
【讨论】:
【参考方案19】:Mysql:
SELECT REPLACE(unix_timestamp(current_timestamp(3)),'.','');
【讨论】:
虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。【参考方案20】:我最近遇到了同样的问题,我创建了一个小型 github 项目,其中包含一个新的 mysql 函数 UNIX_TIMESTAMP_MS()
,它以毫秒为单位返回当前时间戳。
您还可以执行以下操作:
SELECT UNIX_TIMESTAMP_MS(NOW(3))
或 SELECT UNIX_TIMESTAMP_MS(DateTimeField)
项目位于:https://github.com/silviucpp/unix_timestamp_ms
要编译,您只需在项目根目录中运行make compile
。
那么你只需要复制/usr/lib/mysql/plugin/
中的共享库(或者你机器上的任何插件文件夹。)
之后只需打开一个 mysql 控制台并运行:
CREATE FUNCTION UNIX_TIMESTAMP_MS RETURNS INT SONAME 'unix_timestamp_ms.so';
我希望这会有所帮助, 西尔维
【讨论】:
经过一轮重构后,我成功地获得了比内置 UNIX_TIMESTAMP 函数更好的性能 鉴于您要链接到您已受版权保护的代码,请澄清许可条款。理想情况下,通过将许可证文件添加到您的 github 存储库。见github.com/blog/1530-choosing-an-open-source-license 这个工作更像 NOW() 或 SYSDATE(),即它是在语句的持续时间内固定的,还是对它的每个引用(比如插入多行时)使用 up-迄今为止的价值? 引用不存在。【参考方案21】:在毫秒内执行以下操作:
select round(date_format(CURTIME(3), "%f")/1000)
您可以通过以下方式获得微秒:
select date_format(CURTIME(6), "%f")
【讨论】:
以上是关于CURRENT_TIMESTAMP 以毫秒为单位的主要内容,如果未能解决你的问题,请参考以下文章