从UUID版本1获取UNIX时间戳

9

在我们的Java应用程序中,我们正在尝试从 版本1 的UUID中获取UNIX时间。但它没有给出正确的日期时间值。

long time = uuid.timestamp();
time = time / 10000L;   // Dividing by 10^4 as it's in 100 nanoseconds precision 
Calendar c = Calendar.getInstance();
c.setTimeInMillis(time);
c.getTime();

有人能帮忙吗?


1
你不是在用错误的数字(10^8)进行除法吗?时间戳给出了100纳秒(10^-7秒)块的数量,因此您需要10^4个块才能获得1毫秒(10^-3秒)。因此,您必须除以10000L。 - halex
@Halex修复了除数。谢谢。 - Thiyanesh
5个回答

16

timestamp() 的文档如下:

生成的时间戳以自1582年10月15日午夜(UTC)以来100纳秒为单位进行测量。

因此,您需要从那个时间偏移它。例如:

Calendar uuidEpoch = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
uuidEpoch.clear();
uuidEpoch.set(1582, 9, 15, 0, 0, 0); // 9 = October
long epochMillis = uuidEpoch.getTime().getTime();

long time = (uuid.timestamp() / 10000L) + epochMillis;
// Rest of code as before

3
你将uuid.timestamp()除以错误的数字(10^8),应该改为除以10000L。Timestamp提供了100纳秒(10^-7秒)的块数,因此需要10^4个块才能获得1毫秒(10^-3秒)。OP在他的代码中也有相同的错误。 - halex
6
你无法想象我为在你的答案中找到一个小错误而感到多么自豪 :) - halex

6

0

在MySQL中:

SET 
  @t0:=SYSDATE(6)
, @u0:=UUID()
, @t1:=SYSDATE(6)
; SELECT 
  @u0 AS _u0
, @u1:=CONCAT(SUBSTR(@u0,16,3),SUBSTR(@u0,10,4),SUBSTR(@u0,1,8)) AS _u1
, @t0 AS _t0
, FROM_UNIXTIME(CONV(@u1,16,10)/1e7-12219292800) AS _tu
, @t1 AS _t1 \G

Query OK, 0 rows affected (0.00 sec)

*************************** 1. row ***************************
_u0: 060e0537-ce21-11ec-9807-525400432b3b
_u1: 1ecce21060e0537
_t0: 2022-05-07 18:16:17.246698
_tu: 2022-05-07 18:16:17.246750
_t1: 2022-05-07 18:16:17.246755
1 row in set (0.00 sec)

0
在我的情况下,以下代码有效。
    final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
    UUID uuid = UUID.fromString("6470d760-d93d-11e9-8b32-858313a776ba");
    long  time = (uuid.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) / 10000;
    // Rest of code as before

0

如何使用UuidUtiluuid-creator中提取UUID的时间:

Instant instant = UuidUtil.getInstant(uuid);

long secs = instant.getEpochSecond(); // seconds since 1970-01-01
long msecs = instant.toEpochMilli(); // millis since 1970-01-01

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接