PostgreSQL教程 -》数据类型 -》时区
最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!
我要咨询8.5.3. 时区
时区和时区习惯不仅仅受地球几何形状的影响,还受到政治决定的影响。 到了19世纪,全球的时区变得稍微标准化了些,但是还是易于遭受随意的修改,部分是因为夏时制规 则。PostgreSQL使用广泛使用的 IANA (Olson) 时区数据库来得到有关历史时区规则的信息。对于未来的时间,我们假设关于一个给定时区的最新已知 规则将会一直持续到无穷远的未来。
PostgreSQL努力在典型使用中与SQL标准的定义相兼容。但SQL标准在日期和时间类型和功能上有一些奇怪的混淆。两个显而易见的问题是:
尽管date类型与时区没有联系,而time类型却可以有。 然而,现实世界的时区只有在与时间和日期都关联时才有意义, 因为偏移(时差)可能因为实行类似夏时制这样的制度而在一年里有所变化。
缺省的时区会指定一个到UTC的数字常量偏移(时差)。因此,当跨DST边界做日期/时间算术时, 我们根本不可能适应于夏时制时间。
为了克服这些困难,我们建议在使用时区的时候,使用那些同时包含日期和时间的日期/时间类型。我们不建议使用类型 time with time zone (尽管PostgreSQL出于遗留应用以及与SQL标准兼容性的考虑支持这个类型)。 PostgreSQL假设你用于任何类型的本地时区都只包含日期或时间。
在系统内部,所有时区相关的日期和时间都用UTC存储。它们在被显示给客户端之前会被转换成由TimeZone配置参数指定的本地时间。
PostgreSQL允许你使用三种不同形式指定时区:
一个完整的时区名字,例如America/New_York。能被识别的时区名字被列在pg_timezone_names视图中(参见第 51.92 节)。PostgreSQL用广泛使用的 IANA 时区数据来实现该目的,因此相同的时区名字也可以在其他软件中被识别。
一个时区缩写,例如PST。这样一种声明仅仅定义了到UTC的一个特定偏移,而不像完整时区名那样指出整套夏令时转换日期规则。能被识别的缩写被列在pg_timezone_abbrevs视图中(参见第 51.91 节)。你不能将配置参数TimeZone或log_timezone设置成一个时区缩写,但是你可以在日期/时间输入值和AT TIME ZONE操作符中使用时区缩写。
除了时区名和缩写,PostgreSQL将接受POSIX-风格的 时区声明,形式为STDoffset或 STDoffsetDST, 其中STD是一个区域缩写、offset是从UTC西 起的以小时计的数字偏移量、DST是一个可选的夏令时区域缩 写(被假定为给定偏移量提前一小时)。例如,如果EST5EDT还不是一 个被识别的区域名,它可以被接受并且可能和美国东海岸时间的功效相同。在这种语法中, 一个时区缩写可以是一个字母的字符串或者由尖括号(<>)包围 的任意字符串。当一个夏令时区域缩写出现时,会假定根据 IANA 时区数据库的 posixrules条目中使用的同一个夏令时转换规则使用它。 在一个标准的PostgreSQL安装中, posixrules和US/Eastern相同, 因此POSIX-风格的时区声明遵循美国的夏令时规则。如果需要,你可以通过替换 posixrules文件来调整这种行为。
简而言之,在缩写和全称之间是有不同的:缩写表示从UTC开始的一个特定偏移量, 而很多全称表示一个本地夏令时规则并且因此具有两种可能的UTC偏移量。例如, 2014-06-04 12:00 America/New_York表示纽约本地时间的中午, 这个特殊的日期是东部夏令时间(UTC-4)。因此2014-06-04 12:00 EDT 指定的是同一个时间点。但是2014-06-04 12:00 EST指定东部标准时间的 中午(UTC-5),不管在那个日期夏令时是否生效。
更要命的是,某些行政区已经使用相同的时区缩写在不同的时间表示不同的 UTC 偏移量。例如, 在莫斯科MSK在某些年份表示 UTC+3 而在另一些年份表示 UTC+4。 PostgreSQL 会根据在指定的日期它们到底表示什么(或者最近表示什么) 来解释这种缩写。但是,正如上面的EST例子所示,这并不是必须和那一天的本地 标准时间相同。
你应该注意到POSIX-风格的时区特性可能导致伪造的输入被接受,因为它没有对区域缩写合理性的检查。例如SET TIMEZONE TO FOOBAR0将会正常工作,让系统实际使用一个相当奇怪的UTC缩写。另一个需要记住的问题是在POSIX时区名中,正值的偏移量被用于格林威治以西的位置。在其他情况下,PostgreSQL将遵循 ISO-8601 惯例,认为正值的时区偏移量是格林威治以东。
在所有情况下,时区名及其缩写都是大小写不敏感的(这是对PostgreSQL 8.2之前版本的一个修改,在这些版本中某些环境下时区名是大小写敏感的而在另外一些环境中却是大小写不敏感的)。
时区名和缩写都不是硬写在服务器中的,它们是从存储在安装目录下的.../share/timezone/和.../share/timezonesets/子目录中获取的(参见第 B.4 节)。
TimeZone配置参数可以在文件postgresql.conf中被设置,或者使用第 19 章中描述的任何一种标准方法设置。同时也有一些特殊的方法来设置它:
SQL命令SET TIME ZONE为会话设置时区。它是SET TIMEZONE TO的另一种拼写,它更加符合SQL的语法。
libpq客户端使用PGTZ环境变量来通过连接发送一个SET TIME ZONE命令给服务器。