PostgreSQL教程 -》数据类型 -》日期时间间隔输入
最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!
我要咨询8.5.4. 间隔输入
interval值可以使用下列语法书写:
[@] quantity unit [quantity unit...] [direction]
其中quantity是一个数字(很可能是有符号的); unit是毫秒、 millisecond、second、 minute、hour、day、 week、month、year、 decade、century、millennium 或者缩写或者这些单位的复数; direction可以是ago或者为空。At符号(@)是一个可选的噪声。不同单位的数量通过合适的符号计数被隐式地添加。ago对所有域求反。如果IntervalStyle被设置为postgres_verbose,该语法也被用于间隔输出。
日、小时、分钟和秒的数量可以不适用显式的单位标记指定。例如,'1 12:59:10'被读作'1 day 12 hours 59 min 10 sec'。同样,一个年和月的组合可以使用一个横线指定,例如'200-10'被读作'200年10个月'(这些较短的形式事实上是SQL标准唯一许可的形式,并且在IntervalStyle被设置为sql_standard时用于输出)。
间隔值也可以被写成 ISO 8601 时间间隔,使用该标准4.4.3.2小节的“带标志符的格式”或者4.4.3.3小节的“替代格式”。带标志符的格式看起来像这样:
P quantity unit [ quantity unit ...] [ T [ quantity unit ...]]
该串必须以一个P开始,并且可以包括一个引入当日时间单位的T。可用的单位缩写在表 8.16中给出。单位可以被忽略,并且可以以任何顺序指定,但是小于一天的单位必须出现在T之后。特别地,M的含义取决于它出现在T之前还是之后。
表 8.16. ISO 8601 间隔单位缩写
缩写 含义
Y 年
M 月(在日期部分中)
W 周
D 日
H 小时
M 分钟 (在时间部分中)
S 秒
如果使用替代格式:
P [ years-months-days ] [ T hours:minutes:seconds ]
串必须以P开始,并且一个T分隔间隔的日期和时间部分。其值按照类似于 ISO 8601日期的数字给出。
在用一个域声明书写一个间隔常量时,或者为一个用域声明定义的间隔列赋予一个串时,对于为标记的量的解释依赖于域。例如INTERVAL '1' YEAR被解读成1年,而INTERVAL '1'表示1秒。同样,域声明允许的最后一个有效域“右边”的域值会被无声地丢弃掉。例如书写INTERVAL '1 day 2:03:04' HOUR TO MINUTE将会导致丢弃秒域,而不是日域。
根据SQL标准,一个间隔值的所有域都必须由相同的符号,这样一个领头的负号将会应用到所有域;例如在间隔文字'-1 2:03:04'中的负号会被应用于日、小时、分钟和秒部分。PostgreSQL允许域具有不同的符号,并且在习惯上认为以文本表示的每个域具有独立的符号,因此在这个例子中小时、分钟和秒部分被认为是正值。如果IntervalStyle被设置为sql_standard,则一个领头的符号将被认为是应用于所有域(但是仅当没有额外符号出现)。否则将使用传统的PostgreSQL解释。为了避免混淆,我们推荐在任何域为负值时为每一个域都附加一个显式的符号。
在冗长的输入格式中,以及在更紧凑输入格式的某些域中,域值可以有分数部分;例如'1.5 week'或'01:02:03.45'。这样的输入被转换为合适的月数、日数和秒数用于存储。当这样会导致月和日中的分数时,分数被加到低序域中,使用的转换因子是1月=30日和1日=24小时。例如,'1.5 month'会变成1月和15日。只有秒总是在输出时被显示为分数。
表 8.17展示了一些有效interval输入的例子。
表 8.17. 间隔输入
例子描述
1-2 SQL标准格式:1年2个月
3 4:05:06 SQL标准格式:3日4小时5分钟6秒
1 year 2 months 3 days 4 hours 5 minutes 6 seconds 传统Postgres格式:1年2个月3日4小时5分钟6秒钟
P1Y2M3DT4H5M6S “带标志符的”ISO 8601 格式:含义同上
P0001-02-03T04:05:06 ISO 8601 的“替代格式”:含义同上
在内部,interval值被存储为months、days以及seconds。之所以这样做是因为一个月中的天数是变化的,并且在涉及到夏令时调整时一天可以有23或者25个小时。months以及days域是整数,而seconds域可以存储分数。因为区间通常是从常量字符串或者timestamp减法创建而来,这种存储方法在大部分情况下都很好,但是也可能导致预料之外的结果:
SELECT EXTRACT(hours from '80 minutes'::interval);
date_part
-----------
1
SELECT EXTRACT(days from '80 hours'::interval);
date_part
-----------
0
函数justify_days和justify_hours可以用来调整溢出其正常范围之外的days和hours。