Postgres 支持 SQL 中所有的日期和时间类型。
Table 3-6. 日期/时间类型
类型 | 描述 | 存储 | 最早 | 最晚 | 分辨率 |
---|---|---|---|---|---|
timestamp | 包括日期和时间 | 8 字节 | 4713 BC | AD 1465001 | 1 毫秒 / 14 位 |
timestamp [ with time zone ] | 带时区的日期和时间 | 8 字节 | 1903 AD | 2037 AD | 1 毫秒 / 14 位 |
interval | 用于时间间隔 | 12 字节 | -178000000 年 | 178000000 年 | 1 毫秒 |
date | 只用于日期 | 4 字节 | 4713 BC | 32767 AD | 1 天 |
time [ without time zone ] | 只用于一日内时间 | 4 字节 | 00:00:00.00 | 23:59:59.99 | 1 毫秒 |
time [time with time zone] | 只用于一日内时间 | 4 字节 | 00:00:00.00+12 | 23:59:59.99-12 | 1 毫秒 |
注意: 为了保证和早期 Postgres 版本的兼容, 我们还继续提供 datetime (等效于 timestamp)和 timespan(等效于 interval)。 不过对这些类型的支持现在局限于 进行一个隐含的转换,转换成 timestamp和 interval。 类型 abstime 和 reltime 是低分辨率类型,它们被用于系统内部。 我们不鼓励你在新的应用里面使用这些类型,同时我 们支持合适的时候把旧应用中对应的类型转换成目前上面指明的。 因为这些旧类型的部分或全部可能会 在未来的版本里消失。
日期和时间的输入几乎可以是任何合理的格式,包括 ISO-8601,SQL-兼容的, 传统 Postgres 的和其他的形式。 日期输入里的月份和日子输入可能会让人模糊, 因此存在一个设置用于表明具体应该如何解释。 命令 SET DateStyle TO 'US' 或 SET DateStyle TO 'NonEuropean' 表示设置为“月份在日子前面”,而命令 SET DateStyle TO 'European' 表示设置为“日子在月份前面”。缺省是 ISO 风格,但是缺省值可以在编译或者运行时改变。
参阅 Appendix A 获取关于日期/时间输入的准确的分析规则和可识别的时区的信息。
请记住任何日期或者时间输入需要由单引号包围,就象一个文本字符串一样。 参考 Section 1.1.2.5 获取更多信息.SQL 要求下面的语法
type 'value'不过 Postgres 更灵活.
下表是 date 类型可能的输入方式。
Table 3-7. 日期输入
例子 | 描述 |
---|---|
January 8, 1999 | 无歧义 |
1999-01-08 | ISO-8601 格式,建议方式 |
1/8/1999 | US;在 European 模式下读做八月一日 |
8/1/1999 | European;在 US 模式下读做八月一日 |
1/18/1999 | US;在任何模式下都读做一月十八日 |
19990108 | ISO-8601 年,月,日 |
990108 | ISO-8601 年,月,日 |
1999.008 | 年和年里的第几天 |
99008 | 年和年里的第几天 |
January 8, 99 BC | 公元前99年 |
Table 3-8. 月份缩写
月份 | 缩写 |
---|---|
April(四月) | Apr |
August(八月) | Aug |
December(十二月) | Dec |
February(二月) | Feb |
January(一月) | Jan |
July(七月) | Jul |
June(六月) | Jun |
March(三月) | Mar |
November(十一月) | Nov |
October(十月) | Oct |
September(九月) | Sep, Sept |
注意: 五月 (May)没有明确的缩写,原因是显而易见的。
Table 3-9. 周日缩写
周日 | 缩写 |
---|---|
Sunday(星期天) | Sun |
Mondayi(星期一) | Mon |
Tuesdayi(星期二) | Tue, Tues |
Wednesday(星期三) | Wed, Weds |
Thursday(星期四) | Thu, Thur, Thurs |
Friday(星期五) | Fri |
Saturday(星期六) | Sat |
根据 SQL99,这个类型可以称为 time 和 time without time zone(不带时区时间).
下面是有效的 time (时间)输入.
Table 3-10. 时间输入
例子 | 描述 |
---|---|
04:05:06.789 | ISO-8601 |
04:05:06 | ISO-8601 |
04:05 | ISO-8601 |
040506 | ISO-8601 |
04:05 AM | 与 04:05 一样;AM 不影响数值 |
04:05 PM | 与 16:05一样;输入小时数必须 <= 12 |
z | 与 00:00:00 一样 |
zulu | 与 00:00:00 一样 |
allballs | 与 00:00:00 一样 |
这个类型是 SQL92 定义的,但是该定义显示出非常基本的不足, 令这个类型几乎无用。在多数情况下, date, time,和 timestamp 的组合应该能提供任何应用所需要的日期/时间功能的全部内容。
带时区时间 接受所有对 time 类型也合法的输入,附加一个合法的时区,如下:
Table 3-11. 带时区时间输入
例子 | 描述 |
---|---|
04:05:06.789-8 | ISO-8601 |
04:05:06-08:00 | ISO-8601 |
04:05-08:00 | ISO-8601 |
040506-08 | ISO-8601 |
参考 Table 3-12 获取更多时区的例子。
有效的 timestamp 类型的输入包含一个日期和一个时间的连接, 后面跟着可选的 AD 或 BC,再后面跟着 可选的时区。(参阅下面。)因此
1999-01-08 04:05:06 -8:00是一个有效的 timestamp 值,它是 ISO-兼容的。另外,已经广泛使用的格式
January 8 04:05:06 1999 PST也是支持的。
时区 | 描述 |
---|---|
PST | 太平洋标准时间(Pacific Standard Time) |
-8:00 | ISO-8601 与 PST 的偏移 |
-800 | ISO-8601 与 PST 的偏移 |
-8 | ISO-8601 与 PST 的偏移 |
interval可以用下面语法声明:
Quantity Unit [Quantity Unit...] [Direction] @ Quantity Unit [Direction]这里:Quantity 是 ..., -1, 0, 1, 2, ...; Unit 是 second, minute, hour, day, week, month, year, decade, century, millennium, 或者这些单位的缩写或复数; Direction 可以是 ago 或者为空。
下面的 SQL-兼容的函数可以用于对应的数据类型的日期或时间输入: CURRENT_DATE, CURRENT_TIME,CURRENT_TIMESTAMP。
Postgres 为方便起见同样还支持几个特殊常量。
Table 3-13. 日期/时间特殊常量
常量 | 描述 |
---|---|
current | 当前事务时间, (使用时)deferred |
epoch | 1970-01-01 00:00:00+00 (Unix 系统零时) |
infinity | 比任何有效时间晚 |
-infinity | 比任何有效时间早 |
invalid | 非法输入 |
now | 当前事务时间 |
today | 今日午夜 |
tomorrow | 明日午夜 |
yesterday | 昨日午夜 |
使用 SET DateStyle,输出格式可以设成四种风格之一: ISO-8601,SQL (Ingres),传统的 Postgres,和 German 。缺省是 ISO 格式。
Table 3-14. 日期/时间输出风格
风格描述 | 描述 | 例子 |
---|---|---|
'ISO' | ISO-8601 标准 | 1997-12-17 07:37:16-08 |
'SQL' | 传统风格 | 12/17/1997 07:37:16.00 PST |
'Postgres' | 原始风格 | Wed Dec 17 07:37:16 1997 PST |
'German' | 地区风格 | 17.12.1997 07:37:16.00 PST |
date 和 time 风格的输出当然只是对应上面例子的日期或者时间部分。
SQL 风格有欧洲和非欧洲(US)变种, 决定月份后面是日期还是正相反.(参阅上面日期/时间输入部 分,看看这个设置是如何影响对输入值的解释。)
Table 3-15. 日期顺序传统
风格描述 | 描述 | 例子 |
---|---|---|
European | 日/月/年 | 17/12/1997 15:37:16.00 MET |
US | 月/日/年 | 12/17/1997 07:37:16.00 PST |
interval 的输出看起来象输入格式,只是象 week 或 century 这样的单位被转换成年和日。在 ISO 模式下输出看起来象
[ Quantity Units [ ... ] ] [ Days ] Hours:Minutes [ ago ]
有几种方法可以影响日期/时间类型的输出:
直接在 postmaster 启动时用于后端的环境变量 PGDATESTYLE。
会话开始时用于 libpg 的环境变量 PGDATESTYLE。
SQL 命令 SET DATESTYLE。
Postgres 在典型应用中尽可能与 SQL92 的定义相兼容.但 SQL92 标准在日期和时间类型 和功能上有一些奇怪的混淆.两个显而易见的问题是:
date (日期)类型与时区没有联系,而 time (时间)类型却有或可以有. 然而,现实世界的时区只有在与时间和日期都关联时才有意义, 因为时间偏移量(时差)可能因为实行类似夏 时制这样的制度而在一年里有所变化.
缺省的时区用一个整数常量表示与GMT/UTC的偏移(时差). 如果这样, 当跨 DST 界限做日期/时间算术时, 我们根本不可能把夏时制这样的因素计算进去.
为了克服这些困难,我们建议在使用时区的时候, 使用那些同时包含日期和时间的日期/时间类型. 我们建议不要使用 SQL92 的类型 TIME WITH TIME ZONE (尽管 Postgres 出于合理应用以及为了与其他RDBMS实现兼容的考虑支持这个类型). Postgres 假设任何类型的本地时间 都只包含日期或时间.而且,时区支持是源自下层操作系统的时区功能. 因此可以对付夏时制和其他可预料的性质.
Postgres 从操作系统获得介于1902年和2038年的日期的时区支持 (近乎是典型的Unix类系统的日期限 制).在这个范围之外的日期都假设为用全球统一时间 (Universal Coordinated Time,UTC)声明和使用。
在系统内部,所有日期和时间都是用全球统一时间(UTC)格式存储, 也就是通常所说的格林威治时间(GMT). 时间在发给客户前端前由数据库服务器转换成本地时间, 因而缺省的时区是服务器的时区.
有几种影响时区特性的方法:
直接在 postmaster 启动时后端使用 TZ 环境变量作为缺省时区.
客户端使用 libpq 时用 PGTZ 环境变量将时区信息传递给后端.
SQL 命令 SET TIME ZONE 可以给会话设置时区.
SQL92在
timestamp AT TIME ZONE 'zone' 上有修饰词.这里的 zone 可以声明为文本的时区 (比如.'PST')或者声明为一个时间间隔. (比如.INTERVAL '-08:00').
注意: 如果使用了非法的时区,时区变为 GMT(在大多数系统上)。
注意: 如果设置了编译选项 USE_AUSTRALIAN_RULES,那么 那么 EST 代表澳大利亚东部标准时间, ( Australia Eastern Std Time)与 UTC 有 +10:00 小时的偏移量。
Postgres 使用 Julian 记日法用于所有日期/时间计算。 如果假设一年的长度是365.2425天时,这个方法可以 很精确地预计/计算从4713BC(公元前4713年)到很久的未来的任意一天的日期。
19世纪以前的日期传统(历法)对一些趣味读物有意义, 但是在我们这里好象没有充分的理由把它们编码入日 期/时间控制器里面去。