【问题标题】:Do I need TIMESTAMP WITH TIME ZONE for opening hours?营业时间是否需要 TIMESTAMP WITH TIME ZONE?
【发布时间】:2016-07-09 19:09:48
【问题描述】:

事先说明:这是移动应用程序的后端,这就是出现时区问题的原因。

我无法理解这一点。我有shop_times 存储从一天中的什么时间到一天中的另一个时间商店开业的信息。

因为我希望能够知道shop_offer 是在什么时间提供的,所以我还存储了这个shop_times 在什么时期有效或有效的时间间隔。 shop_offer 本身有一个有效的时期。目前我在所有这些间隔中使用TIMESTAMP WITH TIME ZONE,但我不知道我是否真的需要它。

如果用户在伦敦并想查看优惠和可用时间,我可以简单地将店主定义的日期和时间发送给他。我也可以将其显示为当地时间,因此我认为我实际上不需要在这里需要时区信息。

另一方面,如果没有时区信息,我无法询问“in 有多少小时可用”,因为例如2016-03-22 08:00:00 不足以说明,因为移动用户可能在不同的时区。但是,我可以简单地将时区存储到我的shop 实体中。毕竟,决定时区的是商店的位置。因此,如果移动用户问这个问题,我可以将商店的时区发送给他,他可以计算出这个问题的答案。

那么.. 我应该还是不带时区信息来存储时间段信息?

这是我的表格目前的样子:

CREATE TABLE shop_times (

    -- PRIMARY KEY

    id BIGSERIAL NOT NULL,

    shop_id BIGINT NOT NULL,

    CONSTRAINT fk__shop_times__shop
        FOREIGN KEY (shop_id)
        REFERENCES shop(id),

    PRIMARY KEY (id, shop_id),  

    -- ATTRIBUTES

    valid_from_day TIMESTAMP WITH TIME ZONE NOT NULL, 
    valid_until_day TIMESTAMP WITH TIME ZONE NOT NULL,

    time_from TIME WITHOUT TIME ZONE NOT NULL,
    time_to TIME WITHOUT TIME ZONE NOT NULL,

    -- CONSTRAINTS

    CHECK(valid_from_day <= valid_until_day),

    CHECK(time_from < time_to)

);


CREATE TABLE shop_offer_time_period (

    -- PRIMARY KEY 

    shop_times_id BIGINT NOT NULL,

    shop_offer_id BIGINT NOT NULL,

    shop_id BIGINT NOT NULL, 

    CONSTRAINT fk__shop_offer_time_period__shop_times
        FOREIGN KEY (shop_times_id, shop_id)
        REFERENCES shop_times(id, shop_id),

    CONSTRAINT fk__shop_offer_time_period__shop_offer
        FOREIGN KEY (shop_offer_id, shop_id)
        REFERENCES shop_offer(id, shop_id),

    PRIMARY KEY (shop_times_id, shop_offer_id, shop_id),

    -- ATTRIBUTES

    valid_for_days_bitmask INT NOT NULL,

    price REAL NOT NULL,

    valid_from_day TIMESTAMP WITH TIME ZONE NOT NULL,   
    valid_until_day TIMESTAMP WITH TIME ZONE NOT NULL,

);

【问题讨论】:

    标签: sql postgresql datetime timezone


    【解决方案1】:

    需要注意的几点:

    • TIMESTAMP WITH TIME ZONE 不存储时区。这只是意味着 Postgres 在 (1) 解析字符串 (2) 格式化字符串 (3) 确定时间属于哪一天时应用当前的 TIMEZONE 设置,例如对于date_truncextract

    • 在内部,TIMESTAMP WITHWITHOUT TIME ZONE 表示即时。它不存储为字符串。时区仅在您从用户输入解析商店营业时间或将其格式化以显示给购物者时才重要。无论您在哪个时区,都是同一时刻。它只是写成“东部时间下午 5 点”或“太平洋时间下午 2 点”。

    听起来您需要一个 shops.time_zone 列和一个 shopper.time_zone 列(或任何您的表格)。这将让您从用户的角度正确解析/格式化这些时间。

    不需要任何时区信息来计算“这在多少小时内可用?”。那是因为NOW()是一瞬间,而offer的开始时间也是一瞬间,而且无论你在哪个时区,它们之间的差异总是2小时(或其他)。

    如果您的应用以 JSON 格式从数据库接收时间戳,那么您可能会将它们作为字符串传递。如果是这样,我会标准化以 UTC 格式传递它们,这样应用程序就可以轻松地解释它们并进行客户端计算,例如“在多少小时内可用”。

    【讨论】:

      猜你喜欢
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 2020-09-20
      • 2011-03-14
      • 1970-01-01
      • 2015-07-01
      • 2012-01-07
      相关资源
      最近更新 更多