Postgres将时间戳尾随零截断

时间:2019-06-27 13:47:30

标签: postgresql timestamp milliseconds truncated

Postgres(V11.3,64bit,Windows)截取时间戳的尾随零。因此,如果我将时间戳记'2019-06-12 12:37:07.880'插入表中,并在文本postgres返回'2019-06-12 12:37:07.88'时将其读回。

Table date_test:
CREATE TABLE public.date_test (
  id SERIAL,
  "timestamp" TIMESTAMP WITHOUT TIME ZONE NOT NULL,
  CONSTRAINT pkey_date_test PRIMARY KEY(id) 
)

插入数据时的SQL命令:

INSERT INTO date_test (timestamp) VALUES( '2019-06-12 12:37:07.880' )

用于检索数据的SQL命令:

SELECT dt.timestamp ::TEXT FROM date_test dt

returns '2019-06-12 12:37:07.88'

您认为这是错误还是功能?

我的真正问题是:我正在从C ++程序运行查询,我必须将数据库返回的数据转换为适当的数据类型。由于该协议是基于文本的,因此我从数据库中读取的所有内容均为纯文本。解析时间戳时,我首先将字符串标记化,然后将每个标记转换为整数。并且由于毫秒部分被截断了,所以最后一个标记是“ 88”而不是“ 880”,转换“ 88”会产生另一个值,该值会将“ 880”转换为整数。

2 个答案:

答案 0 :(得分:1)

这是使用强制转换为文本时的默认显示格式。

如果要查看所有三个数字,请使用

SELECT _utf32 0x1F47E AS "Supplementary Character in utf32",
       CONVERT(_utf32 0x1F47E USING utf8mb4) AS "Supplementary Character in utf8mb4",
       CHARSET(CONVERT(_utf32 0x1F47E USING utf8mb4)) AS "Proof",

       "---" AS "---",

       _utf32 0x2192 AS "BMP character in utf32",
       CONVERT(_utf32 0x2192 USING utf8) AS "BMP character in utf8",
       CHARSET(CONVERT(_utf32 0x2192 USING utf8)) AS "Proof";

将返回to_char()

答案 1 :(得分:0)

这仅是演示问题。

首先请注意,07.88秒和07.880秒是相同的时间量(与此同时,时间也为7.88和07.880000000)。

PostgreSQL在内部以一种我们不必担心的方式表示时间戳,只要它是明确的表示即可。检索时间戳时,它会格式化为一些字符串。这就是PostgreSQL显然选择不打印冗余尾随零的地方。因此,说它会截断任何东西可能甚至是不正确的。它只是避免生成该0

我认为,不错的解决方案是在C ++中修改解析器以接受任意数量的小数,并正确地解析带有和不带有零的小数。答案中a_horse_with_no_name给出了另一个可行的解决方案。