日期时间函数和操作符
时间/日期函数和操作符
日期/时间函数展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。日期/时间操作符演示了基本算术操作符(+、*等)的行为。而与格式化相关的函数,可以参考数据类型格式化函数。你应该很熟悉日期/时间类型中的日期/时间数据类型的背景知识。
所有下文描述的接受time或timestamp输入的函数和操作符实际上都有两种变体: 一种接收time with time zone或timestamp with time zone, 另外一种接受time without time zone或者timestamp without time zone。为了简化,这些变种没有被独立地展示。此外,+和*操作符都是可交换的操作符对(例如,date+integer 和 integer+date);我们只显示其中一个。
日期/时间操作符
+
操作符
: +
描述
日期或时间相加
示例
1 palopgsql=# select date '2001-09-28' + integer '7';
2 ?column?
3 ------------
4 2001-10-05
5 (1 row)
6
7 palopgsql=# select date '2001-09-28' + time '03:00';
8 ?column?
9 ------------
10 2001-09-28 03:00:00
11 (1 row)
12
13 palopgsql=# select interval '1 day' + interval '1 hour';
14 ?column?
15 ------------
16 1 day 01:00:00
17 (1 row)
18
19 palopgsql=# select timestamp '2001-09-28 01:00' + interval '23 hours';
20 ?column?
21 ------------
22 2001-09-29 00:00:00
23 (1 row)
24
25 palopgsql=# select time '01:00' + interval '3 hours';
26 ?column?
27 ----------
28 04:00:00
29 (1 row)
30 ```
31
32
33##### `-`
34
35操作符
36: `-`
37
38## 描述
39
40日期或时间相加
41
42## 示例
43
44``` sql
45 palopgsql=# select - interval '23 hours';
46 ?column?
47 ------------
48 -23:00:00
49 (1 row)
50
51 palopgsql=# select date '2001-10-01' - date '2001-09-28';
52 ?column?
53 ------------
54 3
55 (1 row)
56
57 palopgsql=# select date '2001-10-01' - integer '7';
58 ?column?
59 ------------
60 2001-09-24
61 (1 row)
62
63 palopgsql=# select date '2001-09-28' - interval '1 hour';
64 ?column?
65 ------------
66 2001-09-27 23:00:00
67 (1 row)
68
69 palopgsql=# select time '05:00' - time '03:00';
70 ?column?
71 ------------
72 02:00:00
73 (1 row)
74
75 palopgsql=# select time '05:00' - interval '2 hours';
76 ?column?
77 ----------
78 03:00:00
79 (1 row)
80
81 palopgsql=# select timestamp '2001-09-28 23:00' - interval '23 hours';
82 ?column?
83 ---------------------
84 2001-09-28 00:00:00
85 (1 row)
86
87 palopgsql=# select interval '1 day' - interval '1 hour';
88 ?column?
89 -----------------
90 1 day -01:00:00
91 (1 row)
92
93 palopgsql=# select timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00';
94 ?column?
95 ----------------
96 1 day 15:00:00
97 (1 row)
98 ```
99
100
101
102##### `*`
103
104操作符
105: `*`
106
107## 描述
108
109日期间隔的倍数
110
111## 示例
112
113``` sql
114 palopgsql=# select 900 * interval '1 second';
115 ?column?
116 -----------------
117 00:15:00
118 (1 row)
119
120 palopgsql=# select 21 * interval '1 day';
121 ?column?
122 -----------------
123 21 days
124 (1 row)
125
126 palopgsql=# select double precision '3.5' * interval '1 hour';
127 ?column?
128 -----------------
129 03:30:00
130 (1 row)
131 ```
132
133
134##### `/`
135
136操作符
137: `/`
138
139## 描述
140
141日期间隔的倍数
142
143## 示例
144
145``` sql
146 palopgsql=# select interval '1 hour' / double precision '1.5';
147 ?column?
148 -----------------
149 00:40:00
150 (1 row)
151
152 palopgsql=# select interval '1 hour' / interval '20 second';
153 ?column?
154 -----------------
155 180
156 (1 row)
157 ```
158
159
160#### 日期/时间函数
161
162##### `age()`
163
164## 语法
165
166`age(timestamp[, timestamp])`
167
168返回类型
169: interval
170
171## 描述
172
173减去参数,生成一个使用年、月(而不是只用日)的“符号化”的结果; 参数仅一个时表示参数日期与current_date(在午夜)的差值
174
175## 示例
176
177``` sql
178 palopgsql=# select age(timestamp '2001-04-10', timestamp '1957-06-13');
179 age
180 -------------------------
181 43 years 9 mons 27 days
182 (1 row)
183
184 palopgsql=# select age(timestamp '1957-06-13');
185 age
186 -------------------------
187 64 years 7 mons 11 days
188 (1 row)
189 ```
190
191
192##### `clock_timestamp()`
193
194## 语法
195
196clock_timestamp()
197
198返回类型
199: timestamp with time zone
200
201## 描述
202
203当前日期和时间(在语句执行期间变化);见 当前日期/时间
204
205##### `current_date()`
206
207## 语法
208
209current_date
210
211返回类型
212: date
213
214## 描述
215
216当前日期;见 当前日期/时间
217
218##### `current_time()`
219
220## 语法
221
222current_time
223
224返回类型
225: time with time zone
226
227## 描述
228
229当前时间(一天中的时间);见 当前日期/时间
230
231##### `current_timestamp()`
232
233## 语法
234
235current_timestamp
236
237返回类型
238: timestamp with time zone
239
240## 描述
241
242当前日期和时间(当前事务开始时);见 当前日期/时间
243
244##### `date_part()`
245
246## 语法
247
248`date_part(text, [timestamp|interval])`
249
250返回类型
251: double precision
252
253## 描述
254
255获得子域(等价于extract);见 EXTRACT,date_part
256
257## 示例
258
259``` sql
260 palopgsql=# select date_part('hour', timestamp '2001-02-16 20:38:40');
261 date_part
262 -----------
263 20
264 (1 row)
265
266 palopgsql=# select date_part('month', interval '2 years 3 months');
267 date_part
268 -----------
269 3
270 (1 row)
271 ```
272
273
274
275##### `date_trunc()`
276
277## 语法
278
279`date_trunc(text,[timestamp|interval])`
280
281返回类型
282: `[timestamp|interval]`
283
284## 描述
285
286截断到指定精度;另见 date_trunc
287
288## 示例
289
290``` sql
291 palopgsql=# select date_trunc('hour', timestamp '2001-02-16 20:38:40');
292 date_trunc
293 ---------------------
294 2001-2-16 20:00
295 (1 row)
296
297 palopgsql=# select date_trunc('hour', interval '2 days 3 hours 40 minutes');
298 date_trunc
299 -----------------
300 2 days 03:00:00
301 (1 row)
302 ```
303
304
305##### `extract()`
306
307## 语法
308
309extract(*`field`* from `[timestamp|interval]`)
310
311返回类型
312: double precision
313
314## 描述
315
316获得子域;见 EXTRACT,date_part
317
318## 示例
319
320``` sql
321 palopgsql=# select extract(hour from timestamp '2001-02-16 20:38:40');
322 date_part
323 -----------
324 20
325 (1 row)
326
327 palopgsql=# select extract(month from interval '2 years 3 months');
328 date_part
329 -----------
330 3
331 (1 row)
332 ```
333
334
335
336##### `isfinite()`
337
338## 语法
339
340isfinite([date|timestamp|interval])
341
342返回类型
343: boolean
344
345## 描述
346
347测试有限日期(不是+/-无限)或有限间隔
348
349## 示例
350
351``` sql
352 palopgsql=# select isfinite(date '2001-02-16');
353 isfinite
354 ----------
355 t
356 (1 row)
357
358 palopgsql=# select isfinite(timestamp '2001-02-16 21:28:30');
359 isfinite
360 ----------
361 t
362 (1 row)
363
364 palopgsql=# select isfinite(interval '4 hours');
365 isfinite
366 ----------
367 t
368 (1 row)
369 ```
370
371
372##### `justify_days()`
373
374## 语法
375
376justify_days(interval)
377
378返回类型
379: interval
380
381## 描述
382
383调整间隔这样30天时间周期可以表示为月
384
385## 示例
386
387``` sql
388 palopgsql=# select justify_days(interval '35 days');
389 justify_days
390 --------------
391 1 mon 5 days
392 (1 row)
393 ```
394
395
396##### `justify_hours()`
397
398## 语法
399
400justify_hours(interval)
401
402返回类型
403: interval
404
405## 描述
406
407调整间隔这样24小时时间周期可以表示为日
408
409## 示例
410
411``` sql
412 palopgsql=# select justify_hours(interval '27 hours');
413 justify_hours
414 ----------------
415 1 day 03:00:00
416 (1 row)
417 ```
418
419
420##### `justify_interval()`
421
422## 语法
423
424justify_interval(interval)
425
426返回类型
427: interval
428
429## 描述
430
431使用justify_days和justify_hours调整间隔,使用额外的符号调整
432
433## 示例
434
435``` sql
436 palopgsql=# select justify_interval(interval '1 mon -1 hour');
437 justify_interval
438 ------------------
439 29 days 23:00:00
440 (1 row)
441 ```
442
443
444##### `localtime()`
445
446## 语法
447
448localtime
449
450返回类型
451: time
452
453## 描述
454
455当前时间(一天中的时间);见 当前日期/时间
456
457##### `localtimestamp()`
458
459## 语法
460
461localtimestamp
462
463返回类型
464: timestamp
465
466## 描述
467
468当前日期和时间(当前事务的开始);见 当前日期/时间
469
470##### `make_date()`
471
472## 语法
473
474make_date(*`year`* int, *`month`* int, *`day`* int)
475
476返回类型
477: date
478
479## 描述
480
481从年、月、日域创建日期
482
483## 示例
484
485``` sql
486 palopgsql=# select make_date(2013, 7, 15);
487 make_date
488 ------------
489 2013/7/15
490 (1 row)
491 ```
492
493##### `make_interval()`
494
495## 语法
496
497make_interval(*`years`* int DEFAULT 0, int DEFAULT 0,*`weeks`* int DEFAULT 0, *`days`* int DEFAULT 0,*`hours`* int DEFAULT 0, *`mins`* int DEFAULT 0,*`secs`* double precision DEFAULT 0.0)
498
499返回类型
500: interval
501
502## 描述
503
504从年、月、周、日、时、分、秒域创建 interval
505
506## 示例
507
508``` sql
509 palopgsql=# select make_interval(days => 10);
510 make_interval
511 ---------------
512 10 days
513
514 (1 row)
515 ```
516
517
518
519##### `make_time()`
520
521## 语法
522
523make_time(*`hour`* int, *`min`* int, *`sec`* double precision)
524
525返回类型
526: time
527
528## 描述
529
530从时、分、秒域创建时间
531
532## 示例
533
534``` sql
535 palopgsql=# select make_time(8, 15, 23.5);
536 make_time
537 ------------
538 08:15:23.5
539 (1 row)
540 ```
541
542
543
544##### `make_timestamp()`
545
546## 语法
547
548make_timestamp(*`years`* int, *`months`* int, *`days`* int,*`hour`* int, *`min`* int, *`sec`* double precision)
549
550返回类型
551: timestamp
552
553## 描述
554
555从年、月、日、时、分、秒域创建时间戳
556
557## 示例
558
559``` sql
560 palopgsql=# select make_timestamp(2013, 7, 15, 8, 15, 23.5);
561 make_timestamp
562 -----------------------
563 2013-07-15 08:15:23.5
564 (1 row)
565 ```
566
567##### `make_timestamptz()`
568
569## 语法
570
571make_timestamptz(*`years`* int, *`months`* int,*`days`* int, *`hour`* int, *`min`* int, *`sec`* double precision, [*`timezone`* text])
572
573返回类型
574: timestamp with time zone
575
576## 描述
577
578从年、月、日、时、分、秒域创建带时区的时间戳。如果没有指定*timezone*, 则使用当前时区。
579
580## 示例
581
582``` sql
583 palopgsql=# select make_timestamptz(2013, 7, 15, 8, 15, 23.5);
584 make_timestamptz
585 --------------------------
586 2013-07-15 08:15:23.5+08
587 (1 row)
588 ```
589
590
591
592##### `now()`
593
594## 语法
595
596now()
597
598返回类型
599: timestamp with time zone
600
601## 描述
602
603当前日期和时间(当前事务的开始);见 当前日期/时间
604
605##### `statement_timestamp()`
606
607## 语法
608
609statement_timestamp()
610
611返回类型
612: timestamp with time zone
613
614## 描述
615
616当前日期和时间(当前事务的开始);见 当前日期/时间
617
618##### `timeofday()`
619
620## 语法
621
622timeofday()
623
624返回类型
625: text
626
627## 描述
628
629当前日期和时间(像clock_timestamp,但是作为一个text字符串)
630
631##### `transaction_timestamp()`
632
633## 语法
634
635transaction_timestamp()
636
637返回类型
638: timestamp with time zone
639
640## 描述
641
642当前日期和时间(当前事务的开始);见 当前日期/时间
643
644##### `to_timestamp()`
645
646## 语法
647
648to_timestamp(double precision)
649
650返回类型
651: timestamp with time zone
652
653## 描述
654
655把 Unix 时间(从 1970-01-01 00:00:00+00 开始的秒)转换成 timestamp
656
657## 示例
658
659``` sql
660 palopgsql=# select to_timestamp(1284352323);
661 to_timestamp
662 ------------------------
663 2010-09-13 12:32:03+08
664 (1 row)
665 ```
666
667##### QL操作符`OVERLAPS`
668
669
670## 语法
671
672``` sql
673 (start1, end1) OVERLAPS (start2, end2)
674 (start1, length1) OVERLAPS (start2, length2)
675 ```
676
677## 描述
678
679这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,`OVERLAPS`会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔 *`start`*`<=` *`time`* `<`*`end`*,除非 *`start`* 和 *`end`* 相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。
680
681## 示例
682
683``` sql
684 palopgsql=# SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
685 palopgsql-# (DATE '2001-10-30', DATE '2002-10-30');
686 overlaps
687 ----------
688 t
689 (1 row)
690
691 palopgsql=# SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
692 palopgsql-# (DATE '2001-10-30', DATE '2002-10-30');
693 overlaps
694 ----------
695 f
696 (1 row)
697
698 palopgsql=# SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
699 palopgsql-# (DATE '2001-10-30', DATE '2001-10-31');
700 overlaps
701 ----------
702 f
703 (1 row)
704
705 palopgsql=# SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
706 palopgsql-# (DATE '2001-10-30', DATE '2001-10-31');
707 overlaps
708 ----------
709 t
710 (1 row)
711 ```
712
713##### 夏令时说明
714
715当把一个`interval`值添加到`timestamp with time zone`上(或从中减去)时, days部分会按照指定的天数增加或减少`timestamp with time zone`的日期。对于横跨夏令时的变化(当会话的时区被设置为可识别DST的时区时),这意味着`interval '1 day'`并不一定等于`interval '24 hours'`。例如,当会话的时区设置为`CST7CDT`时,` timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' `的结果是`timestamp with time zone '2005-04-03 12:00-06'`,而将`interval '24 hours'`增加到相同的初始`timestamp with time zone`的结果则是`timestamp with time zone '2005-04-03 13:00-06'`,因为`CST7CDT`时区在`2005-04-03 02:00`有一个夏令时变更。
716
717注意`age`返回的`月数`域可能有歧义,因为不同的月份有不同的天数。PalopgSQL的方法是当计算部分月数时,采用两个日期中较早的月。例如:`age('2004-06-01','2004-04-30')`使用4月份得到`1 mon 1 day`,而用5月分时会得到`1 mon 2 days`,因为5月有31天,而4月只有30天。
718
719日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 `EXTRACT(EPOCH FROM ...)`把每个值都转换成秒数,然后执行减法,这样会得到两个值之间的*秒* 数。这种方法将会适应每个月中天数、
720
721时区改变和夏令时调整。使用“`-`”操作符的日期或时间戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 `age`函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对负值域进行调整。下面的查询展示了这些方法的不同。例子中的结果由 `timezone = 'US/Eastern'`产生,这使得两个使用的日期之间存在着夏令 时的变化.
722
723## 示例
724
725``` sql
726 palopgsql=# SELECT EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
727 date_part
728 ------------
729 10540800
730 (1 row)
731
732 palopgsql=# SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
733 palopgsql(# EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
734 palopgsql-# / 60 / 60 / 24;
735 ?column?
736 ----------
737 122
738 (1 row)
739
740 palopgsql=# SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
741 ?column?
742 ----------
743 122 days
744 (1 row)
745
746 palopgsql=# SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
747 age
748 --------
749 4 mons
750 (1 row)
751 ```
752
753
754
755#### `EXTRACT()/date_part()`
756
757
758## 语法
759
760`EXTRACT/date_part(field FROM source)`
761
762
763## 描述
764
765`extract`/`date_part`函数从日期/时间值中抽取子域,例如年或者小时等。*`source`* 必须是一个类`timestamp`、`time`或`interval`的值表达式(类型为`date`的表达式将被造型为`timestamp`,并且因此也可以被同样使用)。*`field`* 是一个标识符或者字符串,它指定从源值中抽取的域。`extract`函数返回类型为`double precision`的值。 下列值是有效的域名字:
766
767 `century`
768 : 世纪
769
770 ``` sql
771 palopgsql=# SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
772 date_part
773 -----------
774 20
775 (1 row)
776
777 palopgsql=# SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
778 date_part
779 -----------
780 21
781 (1 row)
782 ```
783
784 第一个世纪从 0001-01-01 00:00:00 AD 开始,尽管那时候人们还不知道这是第一个世纪。这个定义适用于所有使用格里高利历法的国家。其中没有0 世纪,我们直接从公元前 1 世纪到公元 1 世纪。 如果你认为这个不合理,那么请把抱怨发给:罗马圣彼得教堂,梵蒂冈,教皇收。
785
786 `day`
787 : 对于`timestamp`值,是(月份)里的日域(1-31);对于`interval`值,是日数
788
789 ``` sql
790 palopgsql=# SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
791 date_part
792 -----------
793 16
794 (1 row)
795
796 palopgsql=# SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
797 date_part
798 -----------
799 40
800 (1 row)
801 ```
802
803 `decade`
804 : 年份域除以10
805
806 ``` sql
807 palopgsql=# SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
808 date_part
809 -----------
810 200
811 (1 row)
812 ```
813
814 `dow`
815 : 一周中的日,从周日(`0`)到周六(`6`)
816
817 ``` sql
818 palopgsql=# SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
819 date_part
820 -----------
821 5
822 (1 row)
823 ```
824
825 请注意,`extract`的一周中的日和`to_char(..., 'D')`函数不同。
826
827 `doy`
828 : 一年的第几天(1 -365/366)
829
830 ``` sql
831 palopgsql=# SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
832 date_part
833 -----------
834 47
835 (1 row)
836 ```
837
838 `epoch`
839 : 对于`timestamp with time zone`值, 是自 1970-01-01 00:00:00 UTC
840 以来的秒数(结果可能是负数); 对于`date` and`timestamp`值,是自本地时间 1970-01-01 00:00:00以来的描述;对于 `interval`值,它是时间间隔的总秒数。
841
842 ``` sql
843 palopgsql=# SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
844 date_part
845 --------------
846 982384720.12
847 (1 row)
848
849 palopgsql=# SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
850 date_part
851 -----------
852 442800
853 (1 row)
854 ```
855
856 不能用`to_timestamp`把一个 epoch 值转换回成时间戳:
857
858 ``` sql
859 palopgsql=# SELECT to_timestamp(982384720.12);
860 to_timestamp
861 ---------------------------
862 2001-02-17 12:38:40.12+08
863 (1 row)
864 ```
865
866 `hour`
867 : 小时域(0 - 23)
868
869 ``` sql
870 palopgsql=# SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
871 date_part
872 -----------
873 20
874 (1 row)
875 ```
876
877 `isodow`
878 : 一周中的日,从周一(`1`)到周日(`7`)
879
880 ``` sql
881 palopgsql=# SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
882 date_part
883 -----------
884 7
885 (1 row)
886 ```
887
888 除了周日,这和`dow`相同。这符合ISO 8601 中一周中的日的编号。
889
890 `isoyear`
891 : 日期所落在的ISO 8601 周编号的年(不适用于间隔)
892
893 ``` sql
894 palopgsql=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
895 date_part
896 -----------
897 2005
898 (1 row)
899
900 palopgsql=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
901 date_part
902 -----------
903 2006
904 (1 row)
905 ```
906
907 每一个ISO 8601周编号的年都开始于包含1月4日的那一周的周一,在早的1月或迟的12月中ISO年可能和格里高利年不同。更多信息见 `week`域。
908
909 这个域不能用于 PostgreSQL 8.3之前的版本。
910
911 `microseconds`
912 : 秒域,包括小数部分,乘以 1,000,000。请注意它包括全部的秒
913
914 ``` sql
915 palopgsql=# SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
916 date_part
917 -----------
918 28500000
919 (1 row)
920 ```
921
922 `millennium`
923 : 千年
924
925 ``` sql
926 palopgsql=# SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
927 date_part
928 -----------
929 3
930 (1 row)
931 ```
932
933 19xx的年份在第二个千年里。第三个千年从 2001 年 1 月 1 日开始。
934
935 `milliseconds`
936 : 秒域,包括小数部分,乘以 1000。请注意它包括完整的秒。
937
938 ``` sql
939 palopgsql=# SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
940 date_part
941 -----------
942 28500
943 (1 row)
944 ```
945
946 `minute`
947 : 分钟域(0 - 59)
948
949 ``` sql
950 palopgsql=# SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
951 date_part
952 -----------
953 38
954 (1 row)
955 ```
956
957 `month`
958 : 对于`timestamp`值,它是一年里的月份数(1 - 12); 对于`interval`值,它是月的数目,然后对 12 取模(0 -
959 11)
960
961 ``` sql
962 palopgsql=# SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
963 date_part
964 -----------
965 2
966 (1 row)
967
968 palopgsql=# SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
969 date_part
970 -----------
971 3
972 (1 row)
973
974 palopgsql=# SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
975 date_part
976 -----------
977 1
978 (1 row)
979 ```
980
981 `quarter`
982 : 该天所在的该年的季度(1 - 4)
983
984 ``` sql
985 palopgsql=# SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
986 date_part
987 -----------
988 1
989 (1 row)
990 ```
991
992 `second`
993 : 秒域,包括小数部分(0 - 59)
994
995 ``` sql
996 palopgsql=# SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
997 date_part
998 -----------
999 40
1000 (1 row)
1001
1002 palopgsql=# SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
1003 date_part
1004 -----------
1005 28.5
1006 (1 row)
1007 ```
1008
1009 `timezone`
1010 : 与 UTC 的时区偏移,以秒记。正数对应 UTC 东边的时区,负数对应 UTC西边的时区(从技术上来看,PalopgSQL不使用UTC,因为其中不处理闰秒)。
1011
1012 `timezone_hour`
1013 : 时区偏移的小时部分。
1014
1015 `timezone_minute`
1016 : 时区偏移的分钟部分。
1017
1018 `week`
1019 : 该天在所在的ISO 8601 周编号的年份里是第几周。根据定义, 一年的第一周包含该年的 1月 4 日并且 ISO周从星期一开始。换句话说,一年的第一个星期四在第一周。
1020
1021 在 ISO 周编号系统中,早的 1 月的日期可能位于前一年的第五十二或者第五十三周,而迟的 12 月的日期可能位于下一年的第一周。例如,`2005-01-01`位于 2004 年的第五十三周,并且`2006-01-01`位于 2005年的第五十二周,而`2012-12-31`位于 2013年的第一周。我们推荐把`isoyear`域和`week`一起使用来得到一致的结果。
1022
1023 ``` sql
1024 palopgsql=# SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
1025 date_part
1026 -----------
1027 7
1028 (1 row)
1029 ```
1030
1031 `year`
1032 : 年份域。要记住这里没有`0 AD`,所以从`AD`年里抽取`BC`年应该小心处理。
1033
1034 ``` sql
1035 palopgsql=# SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
1036 date_part
1037 -----------
1038 2001
1039 (1 row)
1040 ```
1041
1042
1043
1044**注意**
1045
1046* 当输入值为 +/-Infinity时,`extract`对于单调增的域(`epoch`、`julian`、`year`、`isoyear`、`decade`、`century`以及`millennium`)返回+/-Infinity。对于其他域返回 NULL。
1047
1048
1049* `extract`函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅"数据类型格式化函数"。
1050
1051
1052
1053#### `date_trunc()`
1054
1055
1056`date_trunc`函数在概念上和用于数字的`trunc`函数类似。
1057
1058## 语法
1059
1060`date_trunc('field', source)`
1061
1062
1063## 描述
1064
1065*`source`* 是类型`timestamp`或`interval`的值表达式(类型`date`和`time`的值都分别被自动转换成`timestamp`或者`interval`)。*`field`* 选择对输入值选用什么样的精度进行截断。返回的值是`timestamp`类型或者所有小于选定的精度的域都设置为零(或者一,对于日期和月份)的`interval`。
1066
1067 *`field`* 的有效值是:
1068
1069 | |
1070 | -------------- |
1071 | `microseconds` |
1072 | `milliseconds` |
1073 | `second` |
1074 | `minute` |
1075 | `hour` |
1076 | `day` |
1077 | `week` |
1078 | `month` |
1079 | `quarter` |
1080 | `year` |
1081 | `decade` |
1082 | `century` |
1083 | `millennium` |
1084
1085## 示例
1086
1087``` sql
1088 palopgsql=# SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
1089 date_trunc
1090 ---------------------
1091 2001-02-16 20:00:00
1092 (1 row)
1093
1094 palopgsql=# SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
1095 date_trunc
1096 ---------------------
1097 2001-01-01 00:00:00
1098 (1 row)
1099 ```
1100
1101
1102#### AT TIME ZONE
1103
1104
1105`AT TIME ZONE`把时间戳 *without time zone* 转换成时间戳 *with time zone* 或者反过来,并且把*time* 值转换成不同的时区。如下,AT TIME ZONE变体展示了它的变体。
1106
1107##### timestamp without time zone
1108
1109## 语法
1110
1111timestamp without time zone AT TIME ZONE *`zone`*
1112
1113返回类型
1114: timestamp with time zone
1115
1116## 描述
1117
1118把给定的*不带时区* 的时间戳当作位于指定时区的时间对待
1119
1120##### timestamp with time zone
1121
1122## 语法
1123
1124timestamp with time zone AT TIME ZONE *`zone`*
1125
1126返回类型
1127: timestamp without time zone
1128
1129## 描述
1130
1131把给定的*带时区* 的时间戳转换到新的时区,不带时区指定
1132
1133##### time with time zone
1134
1135## 语法
1136
1137time with time zone AT TIME ZONE *`zone`*
1138
1139返回类型
1140: time with time zone
1141
1142## 描述
1143
1144把给定的*带时区* 的时间转换到新时区
1145
1146在这些表达式里,我们需要的时区 *`zone`* 可以指定为文本串(例如,`'America/Los_Angeles'`)或者一个间隔(例如,`INTERVAL '-08:00'`)。
1147
1148在文本情况下,可用的时区名字可以用时区中描述的任何方式指定。
1149
1150## 示例
1151
1152(假设本地时区是`Asia/Shanghai`)
1153
1154 ``` sql
1155 palopgsql=# SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
1156 timezone
1157 ------------------------
1158 2001-02-17 11:38:40+00
1159 (1 row)
1160
1161 palopgsql=# SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
1162 timezone
1163 ---------------------
1164 2001-02-16 18:38:40
1165 (1 row)
1166
1167 palopgsql=# SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
1168 timezone
1169 ---------------------
1170 2001-02-16 05:38:40
1171 (1 row)
1172 ```
1173
1174 第一个例子给缺少时区的值加上了时区,并且显示了使用当前`TimeZone`设置的值。第二个例子把带有时区值的时间戳移动到指定的时区,并且返回不带时区的值。这允许存储和显示不同于当前`TimeZone`设置的值。第三个例子把东京时间转换成芝加哥时间。把*time*值转换成其他时区会使用当前活跃的时区规则,因为没有提供日期。
1175
1176函数`timezone`(*`zone`*, *`timestamp`*)等效于 SQL 兼容的结构`timestamp` AT TIME ZONE *`zone`*。
1177
1178
1179
1180#### 当前日期/时间
1181
1182
1183PalopgSQL提供了许多返回当前日期和时间的函数。这些 SQL标准的函数全部都按照当前事务的开始时刻返回值:
1184
1185``` sql
1186CURRENT_DATE
1187CURRENT_TIME
1188CURRENT_TIMESTAMP
1189CURRENT_TIME(precision)
1190CURRENT_TIMESTAMP(precision)
1191LOCALTIME
1192LOCALTIMESTAMP
1193LOCALTIME(precision)
1194LOCALTIMESTAMP(precision)
CURRENT_TIME和CURRENT_TIMESTAMP传递带有时区的值;LOCALTIME和LOCALTIMESTAMP传递的值不带时区。
CURRENT_TIME、CURRENT_TIMESTAMP、LOCALTIME和LOCALTIMESTAMP可以有选择地接受一个精度参数,该精度导致结果的秒域被园整为指定小数位。如果没有精度参数,结果将被给予所能得到的全部精度。
一些例子:
1palopgsql=# SELECT CURRENT_TIME;
2 current_time
3--------------------
4 03:06:52.430152+00
5(1 row)
6
7palopgsql=# SELECT CURRENT_DATE;
8 current_date
9--------------
10 2022-02-28
11(1 row)
12
13palopgsql=# SELECT CURRENT_TIMESTAMP;
14 current_timestamp
15-------------------------------
16 2022-02-28 03:06:52.431095+00
17(1 row)
18
19palopgsql=# SELECT CURRENT_TIMESTAMP(2);
20 current_timestamp
21---------------------------
22 2022-02-28 03:06:52.43+00
23(1 row)
24
25palopgsql=# SELECT LOCALTIMESTAMP;
26 localtimestamp
27----------------------------
28 2022-02-28 03:06:53.324666
29(1 row)
因为这些函数全部都按照当前事务的开始时刻返回结果,所以它们的值在事务运行的整个期间内都不改变。我们认为这是一个特性:目的是为了允许一个事务在“当前”时间上有一致的概念,这样在同一个事务里的多个修改可以保持同样的时间戳。
PalopgSQL同样也提供了返回当前语句开始时间的函数,它们会返回函数被调用时的真实当前时间。这些非 SQL 标准的函数列表如下:
1transaction_timestamp()
2statement_timestamp()
3clock_timestamp()
4timeofday()
5now()
transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到客户端最后一条命令的时间)。statement_timestamp()和transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL命令中都会变化。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的 text串,而不是timestamp with time zone值。now()是PalopgSQL的一个传统,等效于transaction_timestamp()。
所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果:
1palopgsql=# SELECT CURRENT_TIMESTAMP;
2 current_timestamp
3-------------------------------
4 2022-02-28 03:07:42.257556+00
5(1 row)
6
7palopgsql=# SELECT now();
8 now
9-------------------------------
10 2022-02-28 03:07:42.258282+00
11(1 row)
12
13-- 对于和 DEFAULT 一起使用是不正确的
14palopgsql=# SELECT TIMESTAMP 'now';
15 timestamp
16----------------------------
17 2022-02-28 03:07:42.910342
18(1 row)
注意
在创建表期间指定一个DEFAULT子句时使用now,数据库系统将在分析这个常量的时候把now转换为一个timestamp,这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。
延时执行(pg_sleep()及其变体)
下面的这些函数可以用于让服务器进程延时执行:
1pg_sleep(seconds)
2pg_sleep_for(interval)
3pg_sleep_until(timestamp with time zone)
pg_sleep让当前的会话进程休眠 seconds 秒以后再执行。seconds 是一个double precision类型的值,所以可以指定带小数的秒数。pg_sleep_for是针对用interval指定的较长休眠时间的函数。pg_sleep_until则可以用来休眠到一个指定的时刻唤醒。例如:
1palopgsql=# SELECT pg_sleep(1.5);
2 pg_sleep
3----------
4
5(1 row)
6
7palopgsql=# SELECT pg_sleep_for('5 minutes');
8 pg_sleep_for
9--------------
10
11(1 row)
12
13palopgsql=# SELECT pg_sleep_until('tomorrow 03:00');
14 pg_sleep_until
15----------------
16
17(1 row)
注意
有效的休眠时间间隔精度是平台相关的,通常 0.01 秒是通用值。休眠延迟将至少持续指 定的时长,也有可能由于服务器负荷而比指定的时间长。特别地,pg_sleep_until并不保证能刚好在指定的时刻被唤醒,但不会在比指定时刻早的时候执行。
警告
请确保在调用pg_sleep或者其变体时,会话不会持有不必要的锁。否则其它会话必须等待该休眠会话,因而减慢整个系统速度。
如果操作系统实现了闰秒,则为60
数据类型转换函数
PalopgSQL转换函数提供一套强大的工具用于把各种数据类型(日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成指定的数据类型。这些函数都遵循公共的调用规范:第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。
转换函数
注意
to_timestamp和to_date存在的目的是为了处理无法用简单造型转换的输入格式。对于大部分标准的日期/时间格式,简单地把源字符串造型成所需的数据类型是可以的,并且简单很多。类似地,对于标准的数字表示形式,to_number也是没有必要的。- 在一个
to_char输出模板串中,一些特定的模式可以被识别并且被替换成基于给定值的被恰当地格式化的数据。任何不属于模板模式的文本都简单地照字面拷贝。同样,在一个输入模板串里(对其他函数),模板模式标识由输入数据串提供的值。如果在模板字符串中有不是模板模式的字符,输入数据字符串中的对应字符会被简单地跳过(不管它们是否等于模板字符串字符)。
还有一个单一参数的to_timestamp函数,请见"日期/时间函数"
to_char()
语法
to_char(timestamp, text), to_char(interval, text), to_char(int, text), to_char(double precision, text), to_char(numeric, text)
返回类型 : text
描述
把时间戳转成字符串; 把间隔转成字符串; 把实数或双精度转成字符串; 把数字转成字符串
示例
1 palopgsql=# select to_char(current_timestamp, 'HH12:MI:SS');
2 to_char
3 ----------
4 03:40:21
5 (1 row)
6
7 palopgsql=# select to_char(interval '15h 2m 12s', 'HH24:MI:SS');
8 to_char
9 ----------
10 15:02:12
11 (1 row)
12
13 palopgsql=# select to_char(125, '999');
14 to_char
15 ---------
16 125
17 (1 row)
18
19 palopgsql=# select to_char(125.8::real, '999D9');
20 to_char
21 ---------
22 125.8
23 (1 row)
24
25 palopgsql=# select to_char(-125.8, '999D99S');
26 to_char
27 ---------
28 125.80-
29 (1 row)
30
31 palopgsql=# select to_char(current_timestamp, 'Day, DD HH12:MI:SS');
32 to_char
33 -------------------------
34 Monday , 28 03:56:00
35 (1 row)
36
37 palopgsql=# select to_char(current_timestamp, 'FMDay, FMDD HH12:MI:SS');
38 to_char
39 ----------------------
40 Monday, 28 03:56:00
41 (1 row)
42
43 palopgsql=# select to_char(-0.1, '99.99');
44 to_char
45 ---------
46 -.10
47 (1 row)
48
49 palopgsql=# select to_char(-0.1, 'FM9.99');
50 to_char
51 ---------
52 -.1
53 (1 row)
54
55 palopgsql=# select to_char(-0.1, 'FM90.99');
56 to_char
57 ---------
58 -0.1
59 (1 row)
60
61 palopgsql=# select to_char(0.1, '0.9');
62 to_char
63 ---------
64 0.1
65 (1 row)
66
67 palopgsql=# select to_char(12, '9990999.9');
68 to_char
69 ------------
70 0012.0
71 (1 row)
72
73 palopgsql=# select to_char(12, 'FM9990999.9');
74 to_char
75 ---------
76 0012.
77 (1 row)
78
79 palopgsql=# select to_char(485, '999');
80 to_char
81 ---------
82 485
83 (1 row)
84
85 palopgsql=# select to_char(-485, '999');
86 to_char
87 ---------
88 -485
89 (1 row)
90
91 palopgsql=# select to_char(485, '9 9 9');
92 to_char
93 ---------
94 4 8 5
95 (1 row)
96
97 palopgsql=# select to_char(1485, '9,999');
98 to_char
99 ---------
100 1,485
101 (1 row)
102
103 palopgsql=# select to_char(1485, '9G999');
104 to_char
105 ---------
106 1,485
107 (1 row)
108
109 palopgsql=# select to_char(148.5, '999.999');
110 to_char
111 ----------
112 148.500
113 (1 row)
114
115 palopgsql=# select to_char(148.5, 'FM999.999');
116 to_char
117 ---------
118 148.5
119 (1 row)
120
121 palopgsql=# select to_char(148.5, 'FM999.990');
122 to_char
123 ---------
124 148.500
125 (1 row)
126
127 palopgsql=# select to_char(148.5, '999D999');
128 to_char
129 ----------
130 148.500
131 (1 row)
132
133 palopgsql=# select to_char(3148.5, '9G999D999');
134 to_char
135 ------------
136 3,148.500
137 (1 row)
138
139 palopgsql=# select to_char(-485, '999S');
140 to_char
141 ---------
142 485-
143 (1 row)
144
145 palopgsql=# select to_char(-485, '999MI');
146 to_char
147 ---------
148 485-
149 (1 row)
150
151 palopgsql=# select to_char(485, '999MI');
152 to_char
153 ---------
154 485
155 (1 row)
156
157 palopgsql=# select to_char(485, 'FM999MI');
158 to_char
159 ---------
160 485
161 (1 row)
162
163 palopgsql=# select to_char(485, 'PL999');
164 to_char
165 ---------
166 + 485
167 (1 row)
168
169 palopgsql=# select to_char(485, 'SG999');
170 to_char
171 ---------
172 +485
173 (1 row)
174
175 palopgsql=# select to_char(-485, 'SG999');
176 to_char
177 ---------
178 -485
179 (1 row)
180
181 palopgsql=# select to_char(-485, '9SG99');
182 to_char
183 ---------
184 4-85
185 (1 row)
186
187 palopgsql=# select to_char(-485, '999PR');
188 to_char
189 ---------
190 <485>
191 (1 row)
192
193 palopgsql=# select to_char(485, 'L999');
194 to_char
195 ---------
196 485
197 (1 row)
198
199 palopgsql=# select to_char(485, 'RN');
200 to_char
201 -----------------
202 CDLXXXV
203 (1 row)
204
205 palopgsql=# select to_char(485, 'FMRN');
206 to_char
207 ---------
208 CDLXXXV
209 (1 row)
210
211 palopgsql=# select to_char(5.2, 'FMRN');
212 to_char
213 ---------
214 V
215 (1 row)
216
217 palopgsql=# select to_char(482, '999th');
218 to_char
219 ---------
220 482nd
221 (1 row)
222
223 palopgsql=# select to_char(485, '"Good number:"999');
224 to_char
225 ------------------
226 Good number: 485
227 (1 row)
228
229 palopgsql=# select to_char(485.8, '"Pre:"999" Post:" .999');
230 to_char
231 ---------------------
232 Pre: 485 Post: .800
233 (1 row)
234
235 palopgsql=# select to_char(12, '99V999');
236 to_char
237 ---------
238 12000
239 (1 row)
240
241 palopgsql=# select to_char(12.4, '99V999');
242 to_char
243 ---------
244 12400
245 (1 row)
246
247 palopgsql=# select to_char(12.45, '99V9');
248 to_char
249 ---------
250 125
251 (1 row)
252
253 palopgsql=# select to_char(0.0004859, '9.99EEEE');
254 to_char
255 -----------
256 4.86e-04
257 (1 row)
258 ```
259
260
261##### `to_date()`
262
263## 语法
264
265`to_date(text, text)`
266
267返回类型
268: date
269
270## 描述
271
272把字符串转成日期
273
274## 示例
275
276``` sql
277 palopgsql=# select to_date('05 Dec 2000', 'DD Mon YYYY');
278 to_date
279 ------------
280 2000-12-05
281 (1 row)
282 ```
283
284
285
286##### `to_number()`
287
288## 语法
289
290`to_number(text, text)`
291
292返回类型
293: numeric
294
295## 描述
296
297把字符串转成数字
298
299## 示例
300
301``` sql
302 palopgsql=# select to_number('12,454.8-', '99G999D9S');
303 to_number
304 -----------
305 -12454.8
306 (1 row)
307 ```
308
309
310
311##### `to_timestamp()`
312
313## 语法
314
315`to_timestamp(text, text)`
316
317返回类型
318: timestamp with time zone
319
320## 描述
321
322把字符串转成时间戳
323
324## 示例
325
326``` sql
327 palopgsql=# select to_timestamp('05 Dec 2000', 'DD Mon YYYY') ;
328 to_timestamp
329 ------------------------
330 2000-12-05 00:00:00+00
331 (1 row)
332 ```
333
334
335
336#### 用于日期/时间格式化的模板模式
337
338下文展示了可以用于格式化日期和时间值的模版。
339
340HH模式
341: 一天中的小时 (01-12)
342
343HH12模式
344: 一天中的小时 (01-12)
345
346HH24模式
347: 一天中的小时 (00-23)
348
349MI模式
350: 分钟 (00-59)minute (00-59)
351
352SS模式
353: 秒(00-59)
354
355MS模式
356: 毫秒(000-999)
357
358US模式
359: 微秒(000000-999999)
360
361SSSS模式
362: 午夜后的秒(0-86399)
363
364AM, am, PM or pm模式
365: 正午指示器(不带句号)
366
367A.M., a.m., P.M. or p.m.模式
368: 正午指示器(带句号)
369
370Y,YYY模式
371: 带逗号的年(4 位或者更多位)
372
373YYYY模式
374: 年(4 位或者更多位)
375
376YYY模式
377: 年的后三位
378
379YY模式
380: 年的后两位
381
382Y模式
383: 年的最后一位
384
385IYYY模式
386: ISO 8601 周编号方式的年(4 位或更多位)
387
388IYY模式
389: ISO 8601 周编号方式的年的最后 3 位
390
391IY模式
392: ISO 8601 周编号方式的年的最后 2 位
393
394I模式
395: ISO 8601 周编号方式的年的最后一位
396
397BC, bc, AD或者ad模式
398: 纪元指示器(不带句号)
399
400B.C., b.c., A.D.或者a.d.模式
401: 纪元指示器(带句号)
402
403MONTH模式
404: 全大写形式的月名(空格补齐到 9 字符)
405
406Month模式
407: 全首字母大写形式的月名(空格补齐到 9 字符)
408
409month模式
410: 全小写形式的月名(空格补齐到 9 字符)
411
412MON模式
413: 简写的大写形式的月名(英文 3 字符,本地化长度可变)
414
415Mon模式
416: 简写的首字母大写形式的月名(英文 3 字符,本地化长度可变)
417
418mon模式
419: 简写的小写形式的月名(英文 3 字符,本地化长度可变)
420
421MM模式
422: 月编号(01-12)
423
424DAY模式
425: 全大写形式的日名(空格补齐到 9 字符)
426
427Day模式
428: 全首字母大写形式的日名(空格补齐到 9 字符)
429
430day模式
431
432: 全小写形式的日名(空格补齐到 9 字符)
433
434DY模式
435: 简写的大写形式的日名(英语 3 字符,本地化长度可变)
436
437Dy模式
438: 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变)
439
440dy模式
441: 简写的小写形式的日名(英语 3 字符,本地化长度可变)
442
443DDD模式
444: 一年中的日(001-366)
445
446IDDD模式
447: ISO 8601 周编号方式的年中的日(001-371,年的第 1 日时第一个 ISO 周的周一)
448
449DD模式
450: 月中的日(01-31)
451
452D模式
453: 周中的日,周日(1)到周六(7)
454
455ID模式
456: 周中的 ISO 8601 日,周一(1)到周日(7)
457
458W模式
459: 月中的周(1-5)(第一周从该月的第一天开始)
460
461WW模式
462: 年中的周数(1-53)(第一周从该年的第一天开始)
463
464IW模式
465: ISO 8601 周编号方式的年中的周数(01 - 53;新的一年的第一个周四在第一周)
466
467CC模式
468: 世纪(2 位数)(21 世纪开始于 2001-01-01)
469
470J模式
471: 儒略日(从午夜 UTC 的公元前 4714 年 11 月 24 日开始的整数日数)
472
473Q模式
474: 季度(to_date和to_timestamp会忽略)
475
476RM模式
477: 大写形式的罗马计数法的月(I-XII;I 是 一月)
478
479rm模式
480: 小写形式的罗马计数法的月(i-xii;i 是 一月)
481
482TZ模式
483: 大写形式的时区缩写(仅在to_char中支持)
484
485tz模式
486: 小写形式的时区缩写(仅在to_char中支持)
487
488TZH模式
489: 时区的小时
490
491TZM模式
492: 时区的分钟
493
494OF模式
495: 从UTC开始的时区偏移(仅在to_char中支持)
496
497#### 用于日期/时间格式化的模板模式修饰语
498
499修饰语可以被应用于模板模式来修改它们的行为。例如,`FMMonth`就是带着`FM`修饰语的`Month`模式。下文展示了可用于日期/时间格式化的修饰语模式。
500
501
502
503FM prefix
504: 填充模式(抑制前导零和填充的空格),示例:`FMMonth`
505
506
507TH suffix
508: 大写形式的序数后缀 ,示例:`DDTH`, e.g., `12TH`
509
510
511th suffix
512: 小写形式的序数后缀 ,示例:`DDth`, e.g., `12th`
513
514
515FX prefix
516: 固定的格式化全局选项(见使用须知),示例: `FX Month DD Day`
517
518
519TM prefix
520: 翻译模式(基于lc_time打印本地化的日和月名),示例: `TMMonth`
521
522
523SP suffix
524: 拼写模式(未实现),示例: `DDSP`
525
526
527
528#### 日期/时间格式化的使用须知
529
530
531 - `FM`抑制前导的零或尾随的空白,否则会把它们增加到输入从而把一个模式的输出变成固定宽度。在PalopgSQL中,`FM`只修改下一个声明,而在Oracle 中,`FM`影响所有随后的声明,并且重复的`FM`修饰语将触发填充模式开和关。
532
533 - `TM`不包括结尾空白。`to_timestamp`和`to_date`会忽略`TM`修饰语。
534
535 - 如果没有使用`FX`选项,`to_timestamp`和`to_date`会跳过输入字符串中的多个空白。例如,`to_timestamp('2000 JUN', 'YYYY MON')`是正确的,但`to_timestamp('2000 JUN', 'FXYYYY MON')`会返回一个错误,因为`to_timestamp`只期望一个空白。`FX`必须被指定为模板中的第一个项。
536
537 - 在`to_char`模板里可以有普通文本,并且它们会被照字面输出。你可以把一个子串放到双引号里强迫它被解释成一个文本,即使它里面包含模板模式也如此。例如,在 `'"Hello Year "YYYY'`中,`YYYY`将被年份数据代替,但是`Year`中单独的`Y`不会。在`to_date`、`to_number`以及`to_timestamp`中,文本和双引号字符串会导致跳过该字符串中所包含的字符数量,例如`"XX"`会跳过两个输入字符(不管它们是不是`XX`)。
538
539 - 如果想在输出里有双引号,那么你必须在它们前面放反斜线,例如 `'\"YYYY Month\"'`。不然,在双引号字符串外面的反斜线就不是特殊的。在双引号字符串内,反斜线会导致下一个字符被取其字面形式,不管它是什么字符(但是这没有特殊效果,除非下一个字符是一个双引号或者另一个反斜线)。
540
541 - 在`to_timestamp`和`to_date`中,如果年份格式声明少于四位(如`YYY`)并且提供的年份少于四位,年份将被调整为最接近于
542 2020 年,例如`95`会变成 1995。
543
544 - 在`to_timestamp`和`to_date`中,在处理超过4位数的年份时,`YYYY`转换具有限制。你必须在`YYYY`后面使用一些非数字字符或者模板,否则年份总是被解释为 4 位数字。例如(对于 20000 年):`to_date('200001131','YYYYMMDD')`将会被解释成一个 4 位数字的年份,而不是在年份后使用一个非数字分隔符,像`to_date('20000-1131', 'YYYY-MMDD')`或`to_date('20000Nov31', 'YYYYMonDD')`。
545
546 - 在`to_timestamp`和`to_date`中,`CC`(世纪)字段会被接受,但是如果有`YYY`、`YYYY`或者`Y,YYY`字段则会忽略它。如果`CC`与`YY`或`Y`一起使用,则结果被计算为指定世纪中的那一年。如果指定了世纪但是没有指定年,则会假定为该世纪的第一年。
547
548 - 在`to_timestamp`和`to_date`中,工作日名称或编号(`DAY`、`D`以及相关的字段类型)会被接受,但会为了计算结果的目的而忽略。季度(`Q`)字段也是一样。
549
550 - 在`to_timestamp`和`to_date`中,一个 ISO 8601 周编号的日期(与一个格里高利日期相区别)可以用两种方法之一被指定为`to_timestamp`和`to_date`:
551
552
553 - 年、周编号和工作日:例如`to_date('2006-42-4', 'IYYY-IW-ID')`返回日期`2006-10-19`。如果你忽略工作日,它被假定为 1(周一)。
554
555 - 年和一年中的日:例如`to_date('2006-291', 'IYYY-IDDD')`也返回`2006-10-19`。
556
557
558 尝试使用一个混合了 ISO 8601 周编号和格里高利日期的域来输入一个日期是无意义的,并且将导致一个错误。在一个 ISO周编号的年的环境下,一个“月”或“月中的日”的概念没有意义。在一个格里高利年的环境下,ISO周没有意义。用户应当避免混合格里高利和 ISO 日期声明。
559
560
561 - 虽然`to_date`将会拒绝混合使用格里高利和 ISO 周编号日期的域, `to_char`却不会,因为`YYYY-MM-DD
562 (IYYY-IDDD)` 这种输出格式也会有用。但是避免写类似`IYYY-MM-DD`的东西,那会得到在起始年附近令人惊讶的结果。
563
564 - 在`to_timestamp`中,毫秒(`MS`)和微秒(`US`)域都被用作小数点后的秒位。例如`to_timestamp('12.3', 'SS.MS')`不是 3 毫秒, 而是 300,因为该转换把它看做 12 + 0.3秒。这意味着对于格式`SS.MS`而言,输入值`12.3`、`12.30`和`12.300`指定了相同数目的毫秒。要得到三毫秒,你必须使用 `12.003`,转换会把它看做 12 + 0.003 = 12.003 秒。
565
566 下面是一个更复杂的示例:`to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US')`是 15 小时、12 分钟和 2 秒 + 20 毫秒 + 1230微秒 = 2.021230秒。
567
568 - `to_char(..., 'ID')`的一周中日的编号匹配`extract(isodow from ...)`函数,但是`to_char(..., 'D')`不匹配`extract(dow from ...)`的日编号。
569
570 - `to_char(interval)`格式化`HH`和`HH12`为显示在一个 12 小时的时钟上,即零小时和 36 小时输出为`12`,而`HH24`会输出完整的小时值,对于间隔它可以超过 23.
571
572
573
574#### 用于数字格式化的模板模式
575
576下文展示了可以用于格式化数字值的模版模式。
577
578`9`
579: 数位(如果无意义可以被删除)
580
581 `0`
582: 数位(即便没有意义也不会被删除)
583
584 `.` (period)
585: 小数点
586
587 `,` (comma)
588: 分组(千)分隔符
589
590 `PR`
591: 尖括号内的负值
592
593 `S`
594: 带符号的数字(使用区域)
595
596 `L`
597: 货币符号(使用区域)
598
599 `D`
600: 小数点(使用区域)
601
602 `G`
603: 分组分隔符(使用区域)
604
605 `MI`
606: 在指定位置的负号(如果数字 \< 0)
607
608 `PL`
609: 在指定位置的正号(如果数字 \> 0)
610
611 `SG`
612: 在指定位置的正/负号
613
614 `RN`
615: 罗马数字(输入在 1 和 3999 之间)
616
617 `TH` or `th`
618: 序数后缀
619
620
621 `V`
622: 移动指定位数(参阅注解)
623
624 `EEEE`
625: 科学记数的指数
626
627数字格式化的用法须知:
628
629
630 - `0`指定一个总是被打印的数位,即便它包含前导/拖尾的零。`9`也指定一个数位,但是如果它是前导零则会被空格替换,而如果是拖尾零并且指定了填充模式则它会被删除(对于`to_number()`来说,这两种模式字符等效)。
631
632 - 模式字符`S`、`L`、`D`以及`G`表示当前locale定义的负号、货币符号、小数点以及数字分隔符字符。不管locale是什么,模式字符句号和逗号就表示小数点和数字分隔符。
633
634 - 对于`to_char()`的模式中的一个负号,如果没有明确的规定,将为该负号保留一列,并且它将被锚接到(出现在左边)那个数字。如果`S`正好出现在某个`9`的左边,它也将被锚接到那个数字。
635
636 - 使用`SG`、`PL`或`MI`格式化的符号并不挂在数字上面; 例如,`to_char(-12, 'MI9999')`生成`'- 12'`,而`to_char(-12, 'S9999')`生成`' -12'`。(Oracle 里的实现不允许在`9`前面使用`MI`,而是要求`9`在`MI`前面。)
637
638 - `TH`不会转换小于零的数值,也不会转换小数。
639
640 - `PL`、`SG`和`TH`是PalopgSQL扩展。
641
642 - 在`to_number`中,如果没有使用`L`或`TH`之类的非数据模板模式,相应数量的输入字符会被跳过,不管它们是否匹配模板模式,除非它们是数据字符(也就是数位、负号、小数点或者逗号)。例如,`TH`会跳过两个非数据字符。
643
644 - 带有`to_char`的`V`会把输入值乘上`10^n`,其中*`n`*是跟在`V`后面的位数。带有`to_number`的`V`以类似的方式做除法。`to_char`和`to_number`不支持使用结合小数点的`V`(例如,不允许`99.9V99`)。
645
646 - `EEEE`(科学记数法)不能和任何其他格式化模式或修饰语(数字和小数点模式除外)组合在一起使用,并且必须位于格式化字符串的最后(例如`9.99EEEE`是一个合法的模式)。
647
648#### 用于数字格式化的模板模式修饰语
649
650某些修饰语可以被应用到任何模板来改变其行为。例如,`FM99.99`是带有`FM`修饰语的`99.99`模式。下文中展示了用于数字格式化模式修饰语。
651
652
653`FM prefix`
654: 填充模式(抑制拖尾零和填充的空白),示例:FM99.99
655
656
657`TH suffix`
658: 大写序数后缀 ,示例:999TH
659
660
661`th suffix`
662: 小写序数后缀 ,示例:999th
评价此篇文章
