我需要TIMESTAMP WITH TIME ZONE开放时间吗?

时间:2016-03-22 18:15:21

标签: sql postgresql datetime timezone

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

我无法理解这一点。我正在shop_times存储从一天中的哪个时间到商店开放的另一个时间的信息。

由于我希望能够告诉您shop_offer 提供的时间,我还会存储时间间隔,告知此shop_times的有效期是多少? 。 shop_offer本身有一个有效的句号。目前我正在使用TIMESTAMP WITH TIME ZONE来表示所有这些时间间隔,但我无法判断我是否真的需要它。

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

另一方面,如果没有时区信息,我就无法询问" 可用的小时数&# 34;因为例如由于移动用户可能位于不同的时区,因此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,

);

1 个答案:

答案 0 :(得分:0)

有几点需要注意:

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

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

听起来你需要shops.time_zone列和shopper.time_zone列(或者你的表被调用)。这样,您就可以从用户的角度正确地解析/格式化这些时间。

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

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