在postgresql中从v1 uuid转换或提取timestamptz

Kru*_*rut 9 postgresql uuid

我正试图从V1 uuid中提取时间戳,天真地希望这有效:

select '3efe0a20-f1b3-11e3-bb44-14109fec739e'::uuid::timestamp;
Run Code Online (Sandbox Code Playgroud)

这是一个快速示例,展示如何提取时间,但我希望postgresql内置一些内容而不是创建一次性pl/pgSql函数.http://play.golang.org/p/XRCooLgfaG

Kru*_*rut 13

我用我的数据库中的uuid测试了它,它似乎运行得很好,即使没有未签名的bigints

CREATE FUNCTION uuid_timestamp(id uuid) RETURNS timestamptz AS $$
  select TIMESTAMP WITH TIME ZONE 'epoch' +
      (((('x' || lpad(split_part(id::text, '-', 1), 16, '0'))::bit(64)::bigint) +
      (('x' || lpad(split_part(id::text, '-', 2), 16, '0'))::bit(64)::bigint << 32) +
      ((('x' || lpad(split_part(id::text, '-', 3), 16, '0'))::bit(64)::bigint&4095) << 48) - 122192928000000000) / 10000000 ) * INTERVAL '1 second';    
$$ LANGUAGE SQL
  IMMUTABLE
  RETURNS NULL ON NULL INPUT;
Run Code Online (Sandbox Code Playgroud)

我在2099年创建的V1 uuid!

select uuid_timestamp('6d248400-65b7-1243-a57a-14109fec739e');
uuid_timestamp     
------------------------
 2099-08-01 11:30:00-07
(1 row)
Run Code Online (Sandbox Code Playgroud)

  • / 10000000 :: DOUBLE PRECISION`亚秒精度 (2认同)