我们正在部署自己的流量计(很像这个USGS流量计:http://waterdata.usgs.gov/usa/nwis/uv?site_no=03539600(,所以我们皮划艇运动员知道是否有足够的水来划过溪流,而不是浪费时间和汽油开车去那里。 我们希望在横跨东部和中部时区的东南白水地区安装其中的一些。
我使用记录的默认值 current_time 存储插入记录的时间。 我想稍后使用 MM/DD/YYYY HH12:MI AM TZ
格式显示数据,该格式输出的读数像 03/12/2012 01:00 AM CDT
.我还希望输出能够了解夏令时的变化,因此当我们"向前"和"后退"时,上一句的最后一部分将在 CST 和 CDT 之间发生变化。 此更改发生在今年 3 年 11 月 2012 日,我在下面列出了此 DST 行两侧的日期。 我正在使用我的Windows 7笔记本电脑进行开发,稍后我们将部署在Unix机器上。 Postgres显然检测到我的Windows计算机设置为美国东部时区。我正在尝试使用"没有时区的时间戳"字段和"带时区的时间戳"字段,但无法使其工作。
我尝试在我的选择中使用"时区",一切都在工作,直到需要显示时区。 当我在 CDT 中询问时间时,实际小时是时间戳的一部分,正确地减去一个小时。 但 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"
我将每个仪表位于字符变化字段中的时区存储在单独的表中。 我考虑只是将此值附加到时间输出的末尾,但我希望它从 CST 更改为 CDT,而无需我的干预。
感谢您的帮助。
与其使用时区缩写,如 CDT
或 CST
,您可以考虑使用完整的奥尔森风格的时区名称。在中部时间的情况下,您可以选择一个时区。要么与您的位置匹配,例如 America/Chicago
,要么只是 US/Central
.这确保了PostgreSQL使用Olson tz数据库自动确定夏令时是否适用于任何给定日期。
你肯定想要一个TIMESTAMP WITH TIME ZONE
列(在PostgreSQL中也称为timestamptz
(。 这将以 UTC 格式存储时间戳,以便它表示特定时刻。 与名称所暗示的相反,它不会在列中保存时区 - 您可以使用AT TIME ZONE
短语查看所选时区中检索到的时间戳。
没有时区的时间戳的语义令人困惑,几乎毫无用处。 我强烈建议您根本不使用该类型来描述您所描述的内容。
我对问题中关于将时间戳存储在CHARACTER VARYING
列中的部分感到非常困惑。 这似乎可能是问题的一部分。 如果你从一开始就可以把它存储在timestamptz
中,我怀疑你的问题会更少。 除此之外,使用 -04 表示法作为 UTC 的偏移量是最安全的;但这对我来说似乎是更多的工作,没有任何好处。
您可以按照管洋回答中建议的格式创建已知时区的表,然后对该表使用外键列。有效的时区可以从pg_timezone_names
获得,我在这个相关的答案中详细介绍了。