如何使用 postgres-rs 和时间 0.3 从 Rust 中的 TIMESTAMPTZ 值获取 UTC 偏移量?

问题描述 投票:0回答:1

我正在尝试使用 postgres-rs 显示本地时间,其中 time-rs 0.3 而不是 chrono-rs 0.4。但将时区设置为 Europe/Amsterdam 时,我得到的只是 UTC 时间戳,没有时区信息来纠正它。

从 psql

show timezone; select now();
读取
Europe/Amsterdam
2024-10-01 10:38:36.63829+02

但是当我在 Rust 中尝试同样的事情时:

// mut conn: PooledConnection<PostgresConnectionManager<MakeTlsConnector>>

let mut tz: Option<String> = None;
if let Ok(r) = conn.query_one("show timezone", &[]) { tz = r.get(0); }
println!("timezone: {:?}", tz);

let mut now: Option<OffsetDateTime> = None;
if let Ok(r) = conn.query_one("select now()", &[]) { now = r.get(0); }
println!("now: {:?}", now);

我得到:

timezone: Some("Europe/Amsterdam")
now: Some(2024-10-01 8:41:49.767418 +00:00:00)

如果没有 OffsetDateTime.offset() 的适当值,我如何正确显示当地时间?

postgresql rust time timezone
1个回答
-2
投票

使用 chrono-tz-rs

Postgres 将

TIMESTAMPTZ
存储为 UTC,就像
TIMESTAMP
一样。唯一的区别是第一种类型表示任何值都应该在本地解释。因此,在存储和显示之前,值会被转换为UTC/从UTC。

根据文档,可以预期类型为

TIMEZONETZ
的值将在数据库连接上设置的区域设置中返回:

所有时区感知的日期和时间均以 UTC 内部存储。他们 转换为 TimeZone 指定区域的本地时间 显示给客户端之前的配置参数。

您可能会将 “在显示给” 之前解释为 “在发送给” 之前,但实际上它归结为 “在由 客户显示之前”

来自

此线程

诸如 psql 或 pgAdmin 之类的客户端或任何通过以下方式进行通信的应用程序 libpq(就像带有 pg gem 的 Ruby)提供了偏移量 当前时区或根据给定时区 [..]

实际上,转换不是在服务器端进行,而是通过

libpq

在客户端进行。
因为您没有在 Rust 中使用任何与 
libpq
 的直接绑定,所以 
TIMESTAMPTZ
 值仍然采用 UTC。

最简单的解决方案是

使用 chrono 0.4, 因为在 chrono-rs 之上有 chrono-tz-rs,它可以使用 IANA 数据库从 UTC 进行转换:

// row: &postgres::Row Option<stdDateTime<Local>> = row.get(index);
    
© www.soinside.com 2019 - 2024. All rights reserved.