简体   繁体   English

PostgreSQL中夏令时的时区

[英]Time zone with daylight savings times in PostgreSQL

We're deploying our own stream gauges (a lot like this USGS gauge: http://waterdata.usgs.gov/usa/nwis/uv?site_no=03539600 ) so us kayakers know whether or not there's enough water to paddle the stream and don't waste time and gas to drive out there. 我们正在部署我们自己的流量计(很像USGS规格: http ://waterdata.usgs.gov/usa/nwis/uv?site_no = 03539600)所以我们皮划艇运动员知道是否有足够的水来划水流并且不要浪费时间和气体去那里。 We hope install a few of these across the southeast whitewater region which spans the eastern and central time zones. 我们希望在横跨东部和中部时区的东南白水区安装其中一些。

I'm storing the time a record is inserted using the default value of current_time for the record. 我正在使用记录的默认值current_time存储插入记录的时间。 I'd like to later display the data using the MM/DD/YYYY HH12:MI AM TZ format, which outputs reading like 03/12/2012 01:00 AM CDT . 我想稍后使用MM/DD/YYYY HH12:MI AM TZ格式显示数据,输出类似于03/12/2012 01:00 AM CDT读数。 I'd also like for the output to be aware of changes in day light savings time, so the last part of the previous sentence would change between CST and CDT when we 'spring forward' and 'fall back'. 我也希望输出能够意识到日光节省时间的变化,所以当我们“向前”和“退回”时,前一句的最后部分会在CST和CDT之间发生变化。 This change occurred on 3/11/2012 this year and I've included dates on both sides of this DST line below. 这一变化发生在今年3月11日,我在下面的DST线两侧都包含了日期。 I'm using my Windows 7 laptop for development and we will later be deploying on a Unix box. 我正在使用我的Windows 7笔记本电脑进行开发,之后我们将在Unix机器上进行部署。 Postgres has apparently detected that my Windows computer is set to eastern US time zone. Postgres显然发现我的Windows电脑设置在美国东部时区。 I'm trying this with a 'timestamp without time zone' field and a 'timestamp with time zone' field but can't get it to work. 我正在尝试使用“没有时区的时间戳”字段和“带时区的时间戳”字段但无法使其工作。

I've tried using 'at time zone' in my selects and every thing is working until it's time to display the time zone. 我已经尝试在我的选择中使用“在时区”,并且每件事都在工作,直到显示时区为止。 The actual hour is part of the time stamp is correctly subtracted by an hour when I ask for the time in CDT. 当我在CDT要求时间时,实际小时是时间戳的一部分被正确地减去一个小时。 But EDT is displayed in the output. 但EDT显示在输出中。

SELECT reading_time as raw,
       reading_time at time zone 'CDT',
       to_char(reading_time at time zone 'CDT',
           'MM/DD/YYYY HH12:MI AM TZ') as formatted_time
  FROM readings2;

"2012-04-29 17:59:35.65";"2012-04-29 18:59:35.65-04";"04/29/2012 06:59 PM EDT"
"2012-04-29 17:59:40.19";"2012-04-29 18:59:40.19-04";"04/29/2012 06:59 PM EDT"
"2012-03-10 00:00:00";"2012-03-10 00:00:00-05";"03/10/2012 12:00 AM EST"
"2012-03-11 00:00:00";"2012-03-11 00:00:00-05";"03/11/2012 12:00 AM EST"
"2012-03-12 00:00:00";"2012-03-12 01:00:00-04";"03/12/2012 01:00 AM EDT"

I'm storing the time zone that each of our gauges is located in a character varying field a separate table. 我将每个仪表所在的时区存储在一个字符变化字段中的单独表格中。 I considered just appending this value to the end of the time output, but I want it to change from from CST to CDT without my intervention. 我考虑过只将这个值附加到时间输出的末尾,但我希望它在没有我干预的情况下从CST更改为CDT。

Thanks for your help. 谢谢你的帮助。

Instead of using time zone names like CDT or CST, you could consider using full Olsen-style time zone names . 您可以考虑使用完整的Olsen样式时区名称 ,而不是使用CDT或CST等时区名称 In the case of central time, you could choose a time zone. 在中央时间的情况下,您可以选择时区。 Either one that matches your location, such as America/Chicago , or just US/Central . 要么匹配您的位置,例如America/Chicago ,要么只是US/Central This ensures PostgreSQL uses the Olsen tz database to automatically figure out whether daylight saving time applies at any given date. 这可确保PostgreSQL使用Olsen tz数据库自动确定夏令时是否适用于任何给定日期。

You definitely want a TIMESTAMP WITH TIME ZONE column (which is also known as timestamptz in PostgreSQL). 你肯定想要一个TIMESTAMP WITH TIME ZONE列(在PostgreSQL中也被称为timestamptz )。 That will store the timestamp in UTC, so that it represents a particular moment in time. 这将以UTC格式存储时间戳,以便它代表特定的时刻。 Contrary to what the name suggests, it does not save a time zone in the column -- you can view the retrieved timestamp in the time zone of your choosing with the AT TIME ZONE phrase. 相反的是,顾名思义,它保存时区在列-你可以与自己选择的时区查看检索到的时间戳AT TIME ZONE短语。

The semantics of TIMESTAMP WITHOUT TIME ZONE are confusing and nearly useless. TIMESTAMP没有时区的语义令人困惑,几乎无用。 I strongly recommend you don't use that type at all for what you are describing. 我强烈建议您根据所描述的内容完全不使用该类型。

I'm really confused by the part of the question which talks about storing the timestamp in a CHARACTER VARYING column. 关于在CHARACTER VARYING列中存储时间戳的问题,我真的很困惑。 That seems as though it might be part of the problem. 这似乎可能是问题的一部分。 If you can store it in timestamptz right from the start I suspect that you will have fewer problems. 如果你可以从一开始就将它存储在timestamptz ,我怀疑你会遇到更少的问题。 Barring that, it would be safest to use the -04 notation for offset from UTC; 除此之外,使用-04表示法来抵消UTC是最安全的; but that seems like more work to me for no benefit. 但这对我来说似乎更多的工作没有任何好处。

You can create a table of known timezones in the format suggested in Guan Yang's answer , and then use a foreign key column to this table. 您可以使用Guan Yang的答案中建议的格式创建已知时区的表,然后对该表使用外键列。 Valid timezones can be obtained from pg_timezone_names I've gone into more detail in this related answer . 有效的时区可以从pg_timezone_names获得我在这个相关的答案中已经详细介绍了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM