CURRENT_TIMESTAMP(以毫秒为单位)


71

有什么办法可以使时间戳记中的毫秒数变为MySqlPostgreSql(或出于好奇而使其他时间)变为毫秒数?

SELECT CURRENT_TIMESTAMP
--> 2012-03-08 20:12:06.032572

是否有这样的事情:

SELECT CURRENT_MILLISEC
--> 1331255526000

或者,唯一的选择是使用DATEDIFFera


FROM_UNIXTIME(UNIX_TIMESTAMP(CONCAT(DATE(NOW()), '',CURTIME(3)));将创建毫秒的时间戳调整在CURTIME参数来改变小数的数
user1119648

@ user1119648-哪个数据库?不CURTIME(3)支持的数据库NOW(3)吗?所以CONCAT(DATE(NOW()), ' ', CURTIME(3))可能仅仅是NOW(3),至少在MySQL 5.6.4+另外,FROM_UNIXTIMEUNIX_TIMESTAMP互为倒数,所以FROM_UNIXTIME( UNIX_TIMESTAMP( whatever ) )结果whatever。你的长表达不一样NOW(3)吗?
ToolmakerSteve

Answers:


42

在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() ) );

30
这不是精确到秒吗?
马特·埃施

1
这是第二。我误读了我认为的问题。我不认为MySQL的返回毫秒,但它应该能够处理他们,如果你为他们提供:stackoverflow.com/questions/2572209/...
比利月亮

在postgreSQL中进行了测试,可以工作,但是它返回的舍入值以秒为单位,而不是bigint的毫秒级精确值。见我的答案在PostgreSQL中的解决方案:stackoverflow.com/a/28760763/3197383
雷米Becheras


35

在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


4
起初我笑了,但这是到目前为止我发现在MySQL 5.5中获得确切时间的唯一方法……所以这就是解决方法:)干杯。
Elliot Chance

1
哇-太好了!我希望他们永远不要解决此问题。
比利·穆恩

如果您只需要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;
lsblsb

13

带有时间戳的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

12

在Mysql 5.7+中,您可以执行

select current_timestamp(6)

更多细节

https://dev.mysql.com/doc/refman/5.7/zh-CN/fractional-seconds.html


3
注意:这在Mysql 5.6.4中也可用:dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html另外,它current_timestamp是的同义词now,因此now(6)是获得该值的较短方法。
ToolmakerSteve

这在v 5.7.26中实际上不起作用。它将运行,但返回类似“ 2019-06-24 12:05:50.931222”的东西
thelastshadow

8

根据当前文档从PostgreSQL的时间戳值中提取毫秒数的正确方法是:

SELECT date_part('milliseconds', current_timestamp);

--OR

SELECT EXTRACT(MILLISECONDS FROM current_timestamp);

带返回值:秒字段(包括小数部分)乘以1000。请注意,这包括整秒。


由于法尔科,对不起,我不清楚,但我确实需要以毫秒为单位的当前时间戳..见例
Marsellus华莱士

您的解决方案从一天的开始返回毫秒数,而不是从1970/01/17开始。见我的答案在PostgreSQL中的解决方案:stackoverflow.com/a/28760763/3197383
雷米Becheras

7

采用:

Select curtime(4);

这将给您毫秒。


4
另外,请确保DATETIME列的长度为6,并在其中存储该长度。另外,您还需要MySQL 5.6.x才能使用毫秒。
TanuAD

1
给出“ 11:08:31.1845”,因此不包括日期
-malhal

@malhal是正确的,没有给出要求的毫秒数。
MCToon16年

在MySQL> 5.6中使用-SELECT NOW(4);
TanuAD '16

6

自Epoch以来, Poster要求提供一个整数的MS,而不是的时间或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以来的毫秒数: 1581611418236

使它成为MySQL函数:

CREATE FUNCTION UNIX_MS() RETURN BIGINT DETERMINISTIC
BEGIN
    RETURN FLOOR(UNIX_TIMESTAMP(NOW(3))*1000);
END

现在运行 SELECT UNIX_MS();

注意:这些都是手工复制的,因此如果有错误,请随时解决;)


UNIX_TIMESTAMP()* 1000不能以秒为单位工作吗?
Brill Pappin

您可以这样做,但是会丢失最后3位数字的粒度。您的建议仅在时间戳记末尾添加3 0。
CompEng88 '20

啊,当然可以!首先,这将使它和秒一样有用。
Brill Pappin

这应该是对实际问题的正确答案。
Brill Pappin

4

在PostgreSQL中,您可以使用:

SELECT extract(epoch from now());

在MySQL上:

SELECT unix_timestamp(now());

6
在MySQL上,仅精确到秒,而不是毫秒。
Jeffrey Van Alstine

在postgreSQL中,您的解决方案以秒为单位返回unix时间戳。见我的回应得到它以毫秒为单位BIGINT:stackoverflow.com/a/28760763/3197383
雷米Becheras

永远不要将UNIX_TIMESTAMP()与NOW()一起使用,因为这将作为本地时间处理,并且会在夏时制的最后一个小时失败!
Bazardshoxer

4

这些响应都不能真正解决postgreSQL中的问题,即:

获取日期字段的unix时间戳以毫秒为单位)

我遇到了同样的问题,并测试了以前的不同答复,但结果不令人满意。

最后,我找到了一种非常简单的方法,可能是最简单的方法:

SELECT (EXTRACT (EPOCH FROM <date_column>::timestamp)::float*1000 as unix_tms
FROM <table>

即:

  • 我们提取pgSQL EPOCH,即以秒为单位的unix时间戳从时间戳谨慎性转换的列中为(在某些复杂查询中,如果这种转换不是显式的,则pgSQL会抛出错误。)
  • 然后将其强制转换为float并乘以1000,以毫秒为单位获取该值

3

这是一个适用于MariaDB和MySQL> = 5.6的表达式:

SELECT (UNIX_TIMESTAMP(NOW()) * 1000000 + MICROSECOND(NOW(6))) AS unix_now_in_microseconds;

这依赖于以下事实:在整个查询中NOW()总是返回相同的时间基于文档UNIX_TIMESTAMP(),我不确定是否也可以使用普通格式。它还需要MySQL> = 5.6作为函数的新精度参数(MariaDB也可以使用)。NOW()


1
UNIX_TIMESTAMP(NOW())如果您处于夏令时,则夏令时结束后的一个小时内将是不正确的。只是使用UNIX_TIMESTAMP()代替,答案就可以了,尽管我不是100%知道leap秒会发生什么。
Doin

3

我发现在MySql中以毫秒为单位接收当前时间的最简单方法:

SELECT (UNIX_TIMESTAMP(NOW(3)) * 1000)

从MySql 5.6开始。


1
投票否决的人,这个答案有什么问题?据我所知,它可以正常工作,只是要知道它返回一个以十进制数字.000而不是整数结尾的事实。
本杰明

如果是夏令时,则夏令时结束时会给出错误的结果!
Doin


1

对于mysql:

SELECT (UNIX_TIMESTAMP() * 1000) AS unix_now_in_microseconds; --- 1600698677000

0

我觉得有必要继续完善,因此在MySQL中:

当前时间戳(以毫秒为单位):

floor(unix_timestamp(current_timestamp(3)) * 1000)

给定datetime(3)中的时间戳(以毫秒为单位):

floor(unix_timestamp("2015-04-27 15:14:55.692") * 1000)

将以毫秒为单位的时间戳转换为datetime(3):

from_unixtime(1430146422456 / 1000)

将datetime(3)转换为时间戳(以毫秒为单位):

floor(unix_timestamp("2015-04-27 14:53:42.456") * 1000)

1
在夏时制时区中,您的第一个示例将每年错误一个小时(一个小时)。更好地使用UNIX_TIMESTAMP()*1000+FLOOR(MICROSECONDS(UTC_TIME(3))*0.001)
Doin

0

PostgreSQL中,我们使用这种方法:

SELECT round(EXTRACT (EPOCH FROM now())::float*1000)

0

对于这里的每个人,只需收听/阅读Doin的评论就可以了!UNIX_TIMESTAMP()给定数据时间字符串时,该函数将与根据MySQL Connection或服务器的时区本地时间与unix时间戳联系。如果在不同时区处理夏令时(每年一小时),这将出错!

例如,在荷兰,10月的最后一个星期日,这是第一次到达02:59:59之后的一秒钟,时间将再次设置为02:00:00。当使用NOW()CURTIME()SYSDATE()MySQL-函数并将其传递给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)

-1

我最近遇到了同样的问题,并创建了一个包含新mysql函数的github小项目 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函数更好的性能
silviu

鉴于您正在链接到拥有版权的代码,请阐明许可条款。理想情况下,通过将许可证文件添加到github存储库中。见github.com/blog/1530-choosing-an-open-source-license
ToolmakerSteve

1
这是否更像NOW()或SYSDATE(),也就是说,它在语句的持续时间内是固定的,还是对它的每个引用(例如,插入多行时)都使用最新值?
Doin

该引用不存在。
g4ost

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.