Skip to main content

tdm_server_rust/utils/
legacy_time.rs

1//! DB 时间列(TIMESTAMP UTC)与 API 的直通层
2//!
3//! ## 约定
4//!
5//! - PostgreSQL 列类型:`TIMESTAMP WITHOUT TIME ZONE`,会话 `SET TIME ZONE 'UTC'`
6//! - 库内值为 UTC 墙钟;后端读写不做 ±8h 等业务偏移
7//! - API 以 RFC3339 UTC(`...Z`)输出;展示时区由前端 `WebFront-end/src/utils/datetime.ts` 处理
8//!
9//! ## 使用
10//!
11//! - 读行:`try_dt(row, "updateTime")` 或 `naive_db_to_api_utc(naive)`
12//! - 写入:`api_to_db_naive(Utc::now())` 或 `api_to_db_naive(instant)`
13
14use chrono::{DateTime, NaiveDateTime, Utc};
15use sqlx::{postgres::PgRow, Row};
16
17/// DB `DateTime<Utc>` → API(恒等)
18pub fn db_to_api_utc(stored: DateTime<Utc>) -> DateTime<Utc> {
19    stored
20}
21
22/// 可选 DB 时间 → API
23pub fn db_to_api_utc_opt(stored: Option<DateTime<Utc>>) -> Option<DateTime<Utc>> {
24    stored
25}
26
27/// `TIMESTAMP` 列读出的 naive 值视为 UTC
28pub fn naive_db_to_api_utc(naive: NaiveDateTime) -> DateTime<Utc> {
29    naive.and_utc()
30}
31
32/// 可选 naive → API UTC
33pub fn naive_db_to_api_utc_opt(naive: Option<NaiveDateTime>) -> Option<DateTime<Utc>> {
34    naive.map(naive_db_to_api_utc)
35}
36
37/// API UTC 写入 DB(TIMESTAMPTZ 列时保留)
38pub fn api_to_db_utc(instant: DateTime<Utc>) -> DateTime<Utc> {
39    instant
40}
41
42/// API UTC 写入 `TIMESTAMP` 列
43pub fn api_to_db_naive(instant: DateTime<Utc>) -> NaiveDateTime {
44    instant.naive_utc()
45}
46
47/// 从 PG 行读取时间列(优先 `TIMESTAMP` naive,兼容 TIMESTAMPTZ)
48pub fn try_dt(row: &PgRow, col: &str) -> Option<DateTime<Utc>> {
49    if let Ok(n) = row.try_get::<NaiveDateTime, _>(col) {
50        return Some(n.and_utc());
51    }
52    row.try_get::<DateTime<Utc>, _>(col).ok()
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use chrono::TimeZone;
59
60    #[test]
61    fn db_to_api_utc_is_identity() {
62        let t = Utc.with_ymd_and_hms(2024, 6, 1, 10, 0, 0).unwrap();
63        assert_eq!(db_to_api_utc(t), t);
64    }
65
66    #[test]
67    fn naive_db_to_api_utc_treats_naive_as_utc() {
68        let naive = chrono::NaiveDate::from_ymd_opt(2024, 6, 1)
69            .unwrap()
70            .and_hms_opt(10, 0, 0)
71            .unwrap();
72        let expected = Utc.with_ymd_and_hms(2024, 6, 1, 10, 0, 0).unwrap();
73        assert_eq!(naive_db_to_api_utc(naive), expected);
74    }
75}