您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

3.5. 日期/时间类型

PostgreSQL 支持 SQL 中所有的日期和时间类型。

Table 3-10. 日期/时间类型

类型 描述 存储 最早 最晚 分辨率
timestamp [ ( p ) ] without time zone 包括日期和时间 8 字节 4713 BC AD 1465001 1 毫秒 / 14 位
timestamp [ ( p ) ] [ with time zone ] 日期和时间 8 字节 4713 BC AD 1465001 1 毫秒 / 14 位
interval [ ( p ) ] 用于时间间隔 12 字节 -178000000 年 178000000 年 1 毫秒
date 只用于日期 4 字节 4713 BC 32767 AD 1 天
time [ ( p ) ] [ without time zone ] 只用于一日内时间 8 字节 00:00:00.00 23:59:59.99 1 毫秒
time [ ( p ) ] with time zone 只用于一日内时间 12 字节 00:00:00.00+12 23:59:59.99-12 1 毫秒

time timestamp interval 接受一个可选的 精度值 p ,这个精度值声明在秒域后面 小数点之后保留的位数.缺省的时候在精度上是没有明确的绑定的, 实际的精度是由用于该数据存储的下层双精度浮点数决定的( 用于 interval 时是秒数,自 2000-01-01 开始, timestamp 也如此). p 有用的范围对 timestamp 是从 0 到大约 6, 但对 interval 可以更多.系统可以接受范围从 0 到 13 的 p 值.

时区和时区习惯都是受政治习惯影响,不仅仅受地球地理因素影响. 在 19 世纪里,全球的时区慢慢变得更标准化了一些,但是仍然容易遭受 随意的修改. PostgreSQL 使用你的 操作系统下层的特性提供时区支持,并且这些系统通常只包含 1902 年到 2038 年之间的信息(对应于传统 Unix 系统时间的完整跨度). timestamp with time zone time with time zone 将只在这个年代范围内使用时区信息, 如果时间超过这个范围,那么假设时间是 UTC.

为了保证能从早于 PostgreSQL 7.0 的版本升级, 我们还能识别 datetime (等效于 timestamp )和 timespan (等效于 interval )。 不过对这些类型的支持现在局限于隐含转换成 timestamp interval , 并且对它们的支持将在下一个 PostgreSQL 版本(很可能叫 7.3)中删除。

类型 abstime reltime 是低分辨率类型,它们被用于系统内部。 我们不鼓励你在新的应用里面使用这些类型,同时我 们支持合适的时候把旧应用中对应的类型转换成目前上面指明的。 因为这些旧类型的部分或全部可能会在未来的版本里消失。

3.5.1. 日期/时间输入

日期和时间的输入几乎可以是任何合理的格式,包括 ISO 8601 SQL -兼容的, 传统 PostgreSQL 的和其他的形式。 对于一些格式,日期输入里的月份和日子输入可能会让人模糊, 因此系统里有一些支持方法可以用来声明自己预期的这些字段的顺序. 命令 SET DateStyle TO 'US' SET DateStyle TO 'NonEuropean' 表示设置为“月份在日子前面”,而命令 SET DateStyle TO 'European' 表示设置为“日子在月份前面”。缺省是 ISO 风格,但是缺省值可以在编译或者运行时改变。

PostgreSQL 在处理日期/时间上比 SQL 标准要求的更灵活. 参阅 Appendix A 获取关于日期/时间输入的准确的分析规则和可识别文本字段, 包括月份,星期几,和时区.

请记住任何日期或者时间的文本输入需要由单引号包围, 就象一个文本字符串一样。 参考 Section 1.1.2.5 获取更多信息. SQL9x 要求下面的语法



type

 [ (

p

) ] '

value

'

在这里可选的精度声明中的 p 是一个整数, 对应在秒域中小数部分的位数, 我们可以对 time timestamp ,和 interval 类型声明精度.

3.5.1.1. date(日期)

下表是 date 类型可能的输入方式。

Table 3-11. 日期输入

例子 描述
January 8, 1999 无歧义
1999-01-08 ISO-8601 格式,建议方式
1/8/1999 U.S.;在 European 模式下读做八月一日
8/1/1999 European;在 U.S. 模式下读做八月一日
1/18/1999 U.S.;在任何模式下都读做一月十八日
19990108 ISO-8601 年,月,日
990108 ISO-8601 年,月,日
1999.008 年和年里的第几天
99008 年和年里的第几天
J2451187 Julian day
January 8, 99 BC 公元前99年

3.5.1.2. time [ ( p ) ] [ without time zone ]

根据 SQL99,这个类型可以声明为 time time without time zone(不带时区时间) . 可选的精度应该介于 0 和 13 之间,缺省是输入时间文本的精度.

下面是有效的 time (时间)输入.

Table 3-12. 时间输入

例子 描述
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
allballs 与 00:00:00 一样

3.5.1.3. time [ ( p ) ] with time zone

这个类型是 SQL92 定义的,但是该定义显示 的属性容易让人怀疑其有用性. 在多数情况下, date time timestamp without time zone timestamp with time zone 的组合应该能提供任何应用所需要的日期/时间功能的全部内容。

可选的精度 p 应该介于 0 和 13 之间, 缺省是输入时间文本的精度.

time with time zone 接受所有对 time 类型也合法的输入,附加一个合法的时区,如下:

Table 3-13. time with time zone 输入

例子 描述
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-14 获取更多时区的例子。

3.5.1.4. timestamp [ ( p ) ] without time zone

timestamp [ ( p ) ] without time zone 类型的有效输入由一个 日期和时间的联接组成,后面跟着一个可选的 AD 或者 BC ,然后再跟着可选的时区.(见下文.) 因此

1999-01-08 04:05:06
      

是一个有效的 timestamp without time zone 数值, 它是兼容 ISO 的.另外,下面这种使用广泛的格式

January 8 04:05:06 1999 PST
      

也受支持.

可选的精度 p 应该介于 0 和 13 之间, 缺省是输入 timestamp 文本的精度.

对于 timestamp without time zone ,任何在输入中 声明的时区都被悄悄丢弃.也就是说,生成的日期/时间数值是从 输入中明确的日期/时间字段中得出的,并且没有根据时区调整.

3.5.1.5. timestamp [ ( precision ) ] with time zone

有效的 timestamp 类型的输入包含一个日期和一个时间的连接, 后面跟着可选的 AD BC ,再后面跟着 可选的时区。(参阅下面。)因此

1999-01-08 04:05:06 -8:00
      

是一个有效的 timestamp 值,它是 ISO -兼容的。另外,已经广泛使用的格式

January 8 04:05:06 1999 PST
      

也是支持的。

可选的精度 p 应该介于 0 和 13 之间, 缺省是输入 timestamp 文本的精度.

Table 3-14. 时区输入

时区 描述
PST 太平洋标准时间(Pacific Standard Time)
-8:00 ISO-8601 与 PST 的偏移
-800 ISO-8601 与 PST 的偏移
-8 ISO-8601 与 PST 的偏移

3.5.1.6. interval [ ( precision ) ]

interval 数值可以用下面语法声明:

  Quantity Unit [Quantity Unit...] [Direction]
@ Quantity Unit [Quantity Unit...] [Direction]
      

这里: Quantity 是一个数字(可能有符号); Unit second , minute , hour , day , week , month , year , decade , century , millennium , 或者这些单位的缩写或复数; Direction 可以是 ago 或者为空。符号 @ 是一个可选的杂音.不同的单位以及相应 正确的符号都是隐含地增加的.

日期,小时,分钟,以及秒钟的数量可以在无明确单位标记的情况下声明. 比如, '1 12:59:10' '1 day 12 hours 59 min 10 sec' 读数一样.

可选的精度 p 应该介于 0 和 13 之间, 并且缺省是输入文本的精度.

3.5.1.7. 特殊值

下面的 SQL -兼容的函数可以用于 对应的数据类型的日期或时间输入: CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP 。 后面两个接受一个可选的精度声明.

PostgreSQL 为方便起见同样还支持几个特殊常量。

Table 3-15. 日期/时间特殊常量

常量 描述
epoch 1970-01-01 00:00:00+00 (Unix 系统零时)
infinity 比任何有效时间晚
-infinity 比任何有效时间早
invalid 非法输入
now 当前事务时间
today 今日午夜
tomorrow 明日午夜
yesterday 昨日午夜
zulu, allballs, z 00:00:00.00 GMT
'now' 是在该值第一次被解释时计算的,

注意: PostgreSQL 7.2 开始, 我们不再支持 'current' 作为日期/时间常量. 在以前, 'current' 是作为特殊数值存储的, 并只是在一个表达式或者类型转换的时候计算成 'now'

3.5.2. 日期/时间输出

使用 SET DateStyle ,输出格式可以设成四种风格之一: ISO 8601, SQL (Ingres),传统的 PostgreSQL,和 German 。缺省是 ISO 格式。

Table 3-16. 日期/时间输出风格

风格描述 描述 例子
'ISO' ISO-8601 标准 1997-12-17 07:37:16-08
'SQL' 传统风格 12/17/1997 07:37:16.00 PST
'PostgreSQL' 原始风格 Wed Dec 17 07:37:16 1997 PST
'German' 地区风格 17.12.1997 07:37:16.00 PST

date time 风格的输出当然只是对应上面例子的日期或者时间部分。

SQL 风格有欧洲和非欧洲(U.S.)变种, 决定月份后面是日期还是正相反.(参阅 Section 3.5.1 分,看看这个设置是如何影响对输入值的解释。)

Table 3-17. 日期顺序传统

风格描述 描述 例子
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

3.5.3. 时区

PostgreSQL 在典型应用中尽可能与 SQL92 的定义相兼容.但 SQL92 标准在日期和时间类型 和功能上有一些奇怪的混淆.两个显而易见的问题是:

  • date (日期)类型与时区没有联系,而 time (时间)类型却有或可以有. 然而,现实世界的时区只有在与时间和日期都关联时才有意义, 因为时间偏移量(时差)可能因为实行类似夏 时制这样的制度而在一年里有所变化.

  • 缺省的时区用一个整数常量表示与 GMT/UTC 的偏移(时差). 如果这样, 当跨 DST 界限做日期/时间算术时, 我们根本不可能把夏时制这样的因素计算进去.

为了克服这些困难,我们建议在使用时区的时候, 使用那些同时包含日期和时间的日期/时间类型. 我们建议 不要 使用 SQL92 的类型 time with time zone (尽管 PostgreSQL 出于合理应用以及为了与其他RDBMS实现兼容的考虑支持这个类型). PostgreSQL 假设你用于任何类型的本地时间 都只包含日期或时间.而且,时区支持是源自下层操作系统的时区功能. 因此可以对付夏时制和其他可预料的性质.

PostgreSQL 从操作系统获得介于1902年和2038年的日期的时区支持 (近乎是典型的Unix类系统的日期限 制).在这个范围之外的日期都假设为用全球统一时间 (Universal Coordinated Time,UTC)声明和使用。

在系统内部,所有日期和时间都是用全球统一时间(UTC)格式存储, 也就是通常所说的格林威治时间(GMT). 时间在发给客户前端前由数据库服务器转换成本地时间, 因而缺省的时区是服务器的时区.

有几种影响时区特性的方法:

  • 直接在 postmaster 启动时后端使用 TZ 环境变量作为缺省时区.

  • 如果在客户端设置了 PGTZ 环境变量,那么 libpq 在联接时将使用 这个环境变量给后端发送一个 SET TIME ZONE 命令.

  • SQL 命令 SET TIME ZONE 可以给会话设置时区.

  • SQL92

    
    
    timestamp
    
     AT TIME ZONE '
    
    zone
    
    '
            上有修饰词.
            

    这里的 zone 可以声明为文本的时区 (比如. 'PST' )或者声明为一个时间间隔. (比如. INTERVAL '-08:00' ).

注意: 如果使用了非法的时区,时区变为 GMT(在大多数系统上)。

注意: 如果设置了运行时选项 AUSTRALIAN_TIMEZONES , 那么 CST EST 指的是澳大利亚时区,而不是美国时区.

3.5.4. 内部

PostgreSQL 使用 Julian 记日法用于所有日期/时间计算。 如果假设一年的长度是365.2425天时,这个方法可以 很精确地预计/计算从4713BC(公元前4713年)到很久的未来的任意一天的日期。

19世纪以前的日期传统(历法)对一些趣味读物有意义, 但是在我们这里好象没有充分的理由把它们编码入日 期/时间控制器里面去。