是否可以让Postgresql返回我需要的时区的日期,逐个查询?

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

我正在使用

sqlx
0.7.3 和
time
0.3.34。

我有这个结构:

#[derive(Debug, sqlx::FromRow)]
pub struct Game {
    pub id: String,
    pub created_at: time::OffsetDateTime,
    pub date_time: time::OffsetDateTime,
    pub score: i64,
    // and many other fields
}

我可以阅读以下查询:

let query = "SELECT * from games"

let games = query.build_query_as::<Game>().fetch_all(db_connection).await?;

我可以插入查询,例如:

let query = r#"INSERT INTO "games" ("id", ..columns...) VALUES ($1, $2, ...and other values...) RETURNING *"#;

let games = sqlx::query_as::<_, Game>(query)
    .bind(value)
    .bind(another_value)
    .fetch_one(db_connection)
    .await?;

一切正常(还有其他更困难的查询)。

现在是问题。

created_at
date_time
字段以Postgresql的
timestamptz
类型保存在数据库中。太棒了。

但是当我检索这些字段时,我需要将它们获取到当前用户的时区。

示例:

如果当前用户查询游戏数据当前位于时区

Europe/Berlin
,Rust 中的后端代码应该在该时区的结构日期时间字段上工作,而不是在
UTC
上工作,这显然是使用
time::OffsetDateTime
与 sqlx 的默认设置。

我知道我可以在 Rust 代码中在后端进行转换(例如将

time::OffsetDateTime
转换为
time::PrimitiveDateTime
或使用 time-tz crate 的方法),但是 我想直接在 Postgresql 中进行转换

我读到我可以使用

AT TIME ZONE 'Europe/Berlin'
PG 的构造来执行此操作,但是所有查询中的所有日期又如何呢?即使我在 PG 的 CTE 末尾使用类似
RETURNING *
的内容?

我读到我可以在查询之前使用

SET TIME ZONE 'Europe/Berlin'
,并且我尝试过但sqlx的作者回答:

query_as
使用二进制协议,始终输出 UTC 时间戳。

所以我现在迷路了。

是否可以让 Postgresql 按查询返回我需要的时区的日期?

postgresql rust timezone timestamp-with-timezone rust-sqlx
1个回答
0
投票

你可以使用chrono

DateTime 是时区感知的,必须从 TimeZone 对象构造,该对象定义如何将本地日期转换为 和 从 UTC 日期返回。有3个著名的时区 实施:

  • Utc 指定 UTC 时区。这是最有效率的。

使用 chrono::{DateTime, Utc};

pub struct Game {
    pub id: String,
    pub created_at: time::DateTime<Utc>,,
    pub date_time: time::DateTime<Utc>,,
   
}
© www.soinside.com 2019 - 2024. All rights reserved.