他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

9.9. 日付/時刻関数と演算子

表 9.33は、日付/時刻型の値の処理で使用可能な関数を示しています。詳細は、以下の副節で説明します。 表 9.32は、(+*等の)基本的な算術演算子の振舞いを説明しています。 書式設定関数については9.8を参照してください。 8.5を参照して、日付/時刻データ型についての背景となっている情報に精通していなければなりません。

加えて表 9.1で示す通常の比較演算子が日付/時刻型で利用できます。 日付とタイムスタンプ(時間帯付きあるいは時間帯なし)はすべて互換性がありますが、時刻(時間帯付きあるいは時間帯なし)と時間間隔は同じデータ型の値同士だけが比較可能です。 時間帯なしのタイムスタンプと時間帯付きのタイムスタンプを比較する際には、前者の値はTimeZone設定パラメータで指定された時間帯にあるものと仮定され、後者の値(すでに内部的にはUTCです)と比較するためにUTCに変換されます。 同様に、タイムスタンプと比較する際には、日付の値はTimeZone時間帯の午前零時であると見なされます。

以下のtimeもしくはtimestamp型の入力を受け取る関数および演算子は全て、実際には2つの種類があります。1つはtime with time zone型またはtimestamp with time zone型を取るもので、もう1つはtime without time zone型もしくはtimestamp without time zone型を取るものです。 簡略化のため、これらの種類の違いは個別に示していません。 また、+*演算子は可換な2項をとります(例えばdate + integerinteger + date)。こうした組み合わせは片方のみ示します。

表9.32 日付/時刻演算子

演算子

説明

date + integerdate

日付に日数を加算

date '2001-09-28' + 72001-10-05

date + intervaltimestamp

時刻間隔を日付に加算

date '2001-09-28' + interval '1 hour'2001-09-28 01:00:00

date + timetimestamp

日付に時刻を加算

date '2001-09-28' + time '03:00'2001-09-28 03:00:00

interval + intervalinterval

時間間隔を加算

interval '1 day' + interval '1 hour'1 day 01:00:00

timestamp + intervaltimestamp

時間間隔をタイムスタンプに加算

timestamp '2001-09-28 01:00' + interval '23 hours'2001-09-29 00:00:00

time + intervaltime

時間間隔を時分に加算

time '01:00' + interval '3 hours'04:00:00

- intervalinterval

時間間隔の符号を反転

- interval '23 hours'-23:00:00

date - dateinteger

日付を減算し、経過日数を返す

date '2001-10-01' - date '2001-09-28'3

date - integerdate

日付から日数を減算

date '2001-10-01' - 72001-09-24

date - intervaltimestamp

日付から時間間隔を減算

date '2001-09-28' - interval '1 hour'2001-09-27 23:00:00

time - timeinterval

時分を減算

time '05:00' - time '03:00'02:00:00

time - intervaltime

時分から時刻間隔を減算

time '05:00' - interval '2 hours'03:00:00

timestamp - intervaltimestamp

タイムスタンプから時刻間隔を減算

timestamp '2001-09-28 23:00' - interval '23 hours'2001-09-28 00:00:00

interval - intervalinterval

時間間隔を減算

interval '1 day' - interval '1 hour'1 day -01:00:00

timestamp - timestampinterval

タイムスタンプを減算(justify_hours()と同様に24時間間隔を日数に変換)

timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00'63 days 15:00:00

interval * double precisioninterval

時間間隔にスカラーを乗算

interval '1 second' * 90000:15:00

interval '1 day' * 2121 days

interval '1 hour' * 3.503:30:00

interval / double precisioninterval

時間間隔をスカラーで除算

interval '1 hour' / 1.500:40:00


表9.33 日付/時刻関数演算子

関数

説明

age ( timestamp, timestamp ) → interval

引数間の減算。日数だけでなく年と月を使用した言葉による結果を生成

age(timestamp '2001-04-10', timestamp '1957-06-13')43 years 9 mons 27 days

age ( timestamp ) → interval

current_date(午前零時時点)から引数を減算

age(timestamp '1957-06-13')62 years 6 mons 10 days

clock_timestamp ( ) → timestamp with time zone

現在の日付と時刻(文実行中に変化する)。9.9.5を参照。

clock_timestamp()2019-12-23 14:39:53.662522-05

current_datedate

現在の日付。9.9.5を参照

current_date2019-12-23

current_timetime with time zone

現在の時刻。9.9.5を参照。

current_time14:39:53.662522-05

current_time ( integer ) → time with time zone

精度を限定した現在の時刻。9.9.5を参照。

current_time(2)14:39:53.66-05

current_timestamptimestamp with time zone

現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

current_timestamp2019-12-23 14:39:53.662522-05

current_timestamp ( integer ) → timestamp with time zone

精度を限定した現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

current_timestamp(0)2019-12-23 14:39:53-05

date_bin ( interval, timestamp, timestamp ) → timestamp

指定した起源に合わせて指定の時間間隔に切り捨てます。9.9.3を参照してください。

date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00')2001-02-16 20:35:00

date_part ( text, timestamp ) → double precision

タイムスタンプの部分フィールドの取得(extractと同じ)。9.9.1を参照。

date_part('hour', timestamp '2001-02-16 20:38:40')20

date_part ( text, interval ) → double precision

時間間隔の部分フィールドの取得(extractと同じ)。9.9.1を参照。

date_part('month', interval '2 years 3 months')3

date_trunc ( text, timestamp ) → timestamp

指定された精度で切り捨て。9.9.2参照。

date_trunc('hour', timestamp '2001-02-16 20:38:40')2001-02-16 20:00:00

date_trunc ( text, timestamp with time zone, text ) → timestamp with time zone

指定された時間帯において指定された精度で切り捨て。9.9.2参照

date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney')2001-02-16 13:00:00+00

date_trunc ( text, interval ) → interval

指定された精度で切り捨て。9.9.2参照。

date_trunc('hour', interval '2 days 3 hours 40 minutes')2 days 03:00:00

extract ( field from timestamp ) → numeric

タイムスタンプの部分フィールドの取得。9.9.1を参照。

extract(hour from timestamp '2001-02-16 20:38:40')20

extract ( field from interval ) → numeric

時間間隔の部分フィールドの取得。9.9.1を参照。

extract(month from interval '2 years 3 months')3

isfinite ( date ) → boolean

日付が有限(+/-無限でない)かどうかの検査

isfinite(date '2001-02-16')true

isfinite ( timestamp ) → boolean

タイムスタンプが有限(+/-無限でない)かどうかの検査

isfinite(timestamp 'infinity')false

isfinite ( interval ) → boolean

時間間隔が有限かどうかの検査(今の所常に真)

isfinite(interval '4 hours')true

justify_days ( interval ) → interval

30日周期が1月を表すように時間間隔を調整

justify_days(interval '35 days')1 mon 5 days

justify_hours ( interval ) → interval

24時間を1日とする時間間隔の調整

justify_hours(interval '27 hours')1 day 03:00:00

justify_interval ( interval ) → interval

justify_daysおよびjustify_hoursを使用し、さらに符号による調整を行っての時間間隔の調整

justify_interval(interval '1 mon -1 hour')29 days 23:00:00

localtimetime

現在の時刻。9.9.5を参照。

localtime14:39:53.662522

localtime ( integer ) → time

精度を限定した現在の時刻。9.9.5を参照。

localtime(0)14:39:53

localtimestamptimestamp

現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

localtimestamp2019-12-23 14:39:53.662522

localtimestamp ( integer ) → timestamp

精度を限定した現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

localtimestamp(2)2019-12-23 14:39:53.66

make_date ( year int, month int, day int ) → date

年、月、日フィールドから日付を作成(負の年はBCを意味します)

make_date(2013, 7, 15)2013-07-15

make_interval ( [ years int [, months int [, weeks int [, days int [, hours int [, mins int [, secs double precision ]]]]]]] ) → interval

年、月、週、日、時間、分、秒フィールドから時間間隔を作成

make_interval(days => 10)10 days

make_time ( hour int, min int, sec double precision ) → time

時、分、秒フィールドから時刻を作成

make_time(8, 15, 23.5)08:15:23.5

make_timestamp ( year int, month int, day int, hour int, min int, sec double precision ) → timestamp

年、月、日、時、分、秒フィールドから時刻を作成(負の年はBCを意味します)

make_timestamp(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5

make_timestamptz ( year int, month int, day int, hour int, min int, sec double precision [, timezone text ] ) → timestamp with time zone

年、月、日、時、分、秒フィールドから時間帯付きの時刻を作成(負の年はBCを意味する)。 timezoneが指定されていなければ、現在の時間帯が使われる。 例ではセッションの時間帯がEurope/Londonであると仮定。

make_timestamptz(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5+01

make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York')2013-07-15 13:15:23.5+01

now ( ) → timestamp with time zone

現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

now()2019-12-23 14:39:53.662522-05

statement_timestamp ( ) → timestamp with time zone

現在の日付と時刻(現在の文の開始時)。9.9.5を参照。

statement_timestamp()2019-12-23 14:39:53.662522-05

timeofday ( ) → text

現在の日付と時刻(clock_timestampと似ているが、text型文字列として返す)。9.9.5を参照。

timeofday()Mon Dec 23 14:39:53.662522 2019 EST

transaction_timestamp ( ) → timestamp with time zone

現在の日付と時刻(現在のトランザクションの開始時)。9.9.5を参照。

transaction_timestamp()2019-12-23 14:39:53.662522-05

to_timestamp ( double precision ) → timestamp with time zone

Unixエポック時間(1970-01-01 00:00:00+00からの経過秒数)をtimestamp with time zoneに変換

to_timestamp(1284352323)2010-09-13 04:32:03+00


これらの関数に加え、OVERLAPS SQL演算子がサポートされています。

(start1, end1) OVERLAPS (start2, end2)
(start1, length1) OVERLAPS (start2, length2)

この式は、2つの時間間隔(その両端で定義されます)が重なる時に真を返します。重ならない場合は偽を返します。 両端は2つの日付、時刻、タイムスタンプとして、もしくは、日付/時刻/タイムスタンプとそれに続く時間間隔として指定できます。 値の組み合わせで指定する場合、開始と終了のいずれを先に記述しても構いません。OVERLAPSは与えられた値のうち、早い方を開始として扱います。 各時間間隔は、start <= time < endという半開区間として見なされます。ただし、startendが同じ値の場合には単一の時間点となります。 これは、例えば端点のみが共通である2つの時間間隔は、重ならないということを意味します。

SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: true

timestamp with time zoneの値にintervalの値を加える時(またはintervalの値を引く時)、日にちの部分は、timestamp with time zoneの日付を指定された日数だけ先に進める、もしくは後に戻し、時刻は同じに保ちます。 (セッションの時間帯がDSTを認識する設定の場合)夏時間の移行に跨っての変化に関しては、interval '1 day'interval '24 hours'に等しいとは限りません。 例えば、セッションの時間帯が America/Denverに設定されている時には以下のようになります。

SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day';
Result: 2005-04-03 12:00:00-06
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
Result: 2005-04-03 13:00:00-06

その理由はAmerica/Denver時間帯で2005-04-03 02:00:00に夏時間への変更され、1時間スキップされたためです。

異なる月では日数が異なりますのでageで返されるmonthsフィールドにはあいまいさがあります。 PostgreSQLのやり方は月をまたがる2つの日付の計算において、日付の早いほうの月を使用します。 例えば、age('2004-06-01', '2004-04-30')は4月を使用して1 mon 1 dayを得ます。5月は31日あり、4月は30日のため、もし5月を使用するなら結果は1 mon 2 daysとなるでしょう。

日付とタイムスタンプの引き算は複雑になることがあります。 引き算をする概念的に単純な方法は、それぞれの値を秒数にEXTRACT(EPOCH FROM ...)で変換してから、結果を引き算する方法です。この結果は2つの値の間の数になります。 これは各月の日数、時間帯の変更、夏時間の調整に対して調整されるでしょう。 -演算子での日付やタイムスタンプの引き算は値の間の(24時間の)日数と時間/分/秒を、同様に調整して返します。 age関数は年、月、日、時間/分/秒をフィールド毎に引き算し、負のフィールドの値を調整します。 以下の問い合わせは上の各方法の違いを説明する例です。 例の結果はtimezone = 'US/Eastern'で生成されました。2つの日付の間には夏時間の変更があります。

SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
       EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
Result: 10537200.000000
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
        EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
        / 60 / 60 / 24;
Result: 121.9583333333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
Result: 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
Result: 4 mons

9.9.1. EXTRACT, date_part

EXTRACT(field FROM source)

extract関数は、日付/時刻の値から年や時などの部分フィールドを抽出します。 sourcetimestamp型、time型、またはinterval型の評価式でなければなりません(date型の式はtimestamp型にキャストされますので、同様に使用可能です)。 fieldはsourceの値からどのフィールドを抽出するかを選択する識別子もしくは文字列です。 extract関数はnumeric型の値を返します。 以下に有効なフィールド名を示します。

century

世紀

SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
Result: 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 21

当時の人々にはそのような意識はありませんでしたが、最初の世紀は0001-01-01 00:00:00 ADから始まります。 この定義は全てのグレゴリオ暦を使用する国で適用されています。 0という値の世紀はありません。-1世紀の次は1世紀です。 この定義に納得できなければ、苦情をバチカンローマ聖ペテロ大聖堂のローマ法王に伝えてください。

day

timestamp値については、(月内の)日付フィールド(1–31)。interval値については日数。

SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 16

SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
Result: 40
decade

年フィールドを10で割ったもの

SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 200
dow

日曜日(0)から土曜日(6)までの曜日

SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 5

extract関数の曜日番号はto_char(...,'D')関数のそれとは異なる点に注意してください。

doy

年内での通算日数(1–365/366)

SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 47
epoch

timestamp with time zone型の値においては、1970-01-01 00:00:00 UTCからの秒数(負の数はその前)。datetimestamp型の値においては、時間帯と夏時間を考慮しないローカルタイムの1970-01-01 00:00:00からの秒数。interval型の値ではその時間間隔における合計の秒数。

SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
Result: 982384720.120000

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12');
Result: 982355920.120000

SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
Result: 442800.000000

to_timestampで経過秒数をtimestamp with time zoneに変換することができます。

SELECT to_timestamp(982384720.12);
Result: 2001-02-17 04:38:40.12+00

to_timestampdateあるいはtimestampの値から取り出したエポックに適用すると、誤解を招く結果が得られるかもしれないことに注意してください。結果は実質的に元の値がUTCで与えられていると見なしますが、実際は違うかもしれません。

hour

時フィールド(0–23)

SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 20
isodow

月曜日(1)から日曜日(7)までの曜日

SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
Result: 7

日曜日を除きdowと同一です。 これはISO 8601曜日番号付けに一致します。

isoyear

日付に当てはまるISO 8601週番号年(intervalには適用できない)。

SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
Result: 2005
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
Result: 2006

すべてのISO 8601週番号年は1月4日を含む週の月曜日から開始されます。従って、1月上旬、または12月下旬でISO年がグレゴリオ年と異なる可能性があります。 より詳細はweekフィールドを参照してください。

このフィールドは8.3より前のPostgreSQLリリースでは有効でありません。

julian

日付あるいタイムスタンプに関連するユリウス日(Julian Date)(時間間隔には適用されない)。 ローカル午前零時ではないタイムスタンプは小数となります。 詳細はB.7をご覧ください。

SELECT EXTRACT(JULIAN FROM DATE '2006-01-01');
Result: 2453737
SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00');
Result: 2453737.50000000000000000000
microseconds

端数部分も含む秒フィールドに、1,000,000を乗じた値。秒の整数部を含むことに注意。

SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
Result: 28500000
millennium

ミレニアム(千年期)

SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 3

1900年代の年は第2ミレニアムです。第3ミレニアムは2001年1月1日から始まりました。

milliseconds

端数部分も含む秒フィールドに、1000を乗た値。秒の整数部を含むことに注意してください。

SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
Result: 28500.000
minute

分フィールド (0–59)

SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 38
month

timestamp型の値に対しては年内の月番号(1–12)。interval型の値に対しては月数を12で割った余り(0–11)。

SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 2

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
Result: 3

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
Result: 1
quarter

その日付が含まれる年の四半期(1–4)

SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 1
second

端数を含んだ秒フィールド

SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 40.000000

SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
Result: 28.500000
timezone

秒単位のUTCからの時間帯オフセット。正の値はUTCより東の時間帯に対応し、負の値はUTCより西の時間帯に対応。 (技術的に言えば、PostgreSQLはうるう秒を制御しないためUTCを使用していない。)

timezone_hour

時間帯オフセットの時の成分。

timezone_minute

時間帯オフセットの分の成分。

week

ISO 8601週番号。 定義ではISO週は月曜日から始まり、その年の1月4日を含む週をその年の第1週としています。 つまり、年の最初の木曜日がある週がその年の第1週となります。

ISO週番号システムでは、1月の早い日にちは前年の第52週もしくは第53週となることがあり、12月の遅い日にちには次年の最初の週の一部となることがあります。 例えば、2005-01-01は2004年の第53週であり、2006-01-01は2005年の第52週の一部です、一方2012-12-31は2013年の第1週の一部となります。 整合性のある結果を得るため、isoyearフィールドとweekを併用することを推奨します。

SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 7
year

年フィールド。AD零年が存在しないことは忘れないでください。このためADの年からBCの年を減ずる時には注意が必要です。

SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 2001

注記

入力値が+/-無限大の場合、extractは単調増加するフィールド(epochjulianyearisoyeardecadecenturymillennium)に対し、+/-無限大を返します。 その他のフィールドに対してはNULLが返されます。 PostgreSQLの9.6より前のバージョンでは、入力が無限大のすべての場合に対してゼロを返していました。

extract関数は主に演算処理を意図しています。 日付/時刻の値を表示する目的での書式については9.8を参照してください。

date_part関数は伝統的なIngres上で設計されたもので、標準SQLextract関数と等価です。

date_part('field', source)

ここでfieldパラメータが名前ではなく文字列値である必要があることに注意してください。 date_partで有効なフィールド名はextractと同じです。 歴史的な理由により、date_part関数はdouble precision型の結果を返します。 場合によってはこれによって精度が失われることがあります。 extractを代わりに使うことをお勧めします。

SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16

SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4

9.9.2. date_trunc

date_trunc関数は概念的に数値に対するtrunc関数と類似しています。

date_trunc(field, source [, time_zone ])

sourceは、データ型timestamptimestamp with time zoneもしくはintervalの評価式です。 (date型とtime型の値はそれぞれ自動的にtimestampもしくはintervalにキャストされます。) fieldは、入力値の値をどの精度で切り捨てるかを選択します。 同様に戻り値はtimestamptimestamp with time zoneもしくはinterval型で、指定した精度より下のすべてのフィールドがゼロに設定(日と月については1に設定)されます。

fieldの有効値には次のものがあります。

microseconds
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium

入力値がtimestamp with time zone型の値なら、特定の時間帯を考慮して切り捨てが行われます。たとえば、を切り捨てると値はその時間帯での真夜中になります。 デフォルトでは切り捨ては現在のTimeZoneの設定に従いますが、別の時間帯を指定することができるようにオプションのtime_zone引数が提供されています。 時間帯名は8.5.3に記述されている方法で指定できます。

timestamp without time zoneあるいはintervalの入力を処理している間は時間帯は指定できません。 これらは額面通りの値で扱われます。

例(現地タイムゾーンはAmerica/New_Yorkと仮定します):

SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00

SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05

SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00

9.9.3. date_bin

関数date_binは、指定した原点に揃えて入力のタイムスタンプを指定した時間間隔(stride)に分類します。

date_bin(stride, source, origin)

sourcetimestampあるいはtimestamp with time zone型の値式です。 (date型の値はtimestampに自動キャストされます。) strideinterval型の値式です。 戻り値は同様に、timestampあるいはtimestamp with time zone型で、sourceが置かれた箱の開始位置に印を付けています。

例を示します。

SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01');
Result: 2020-02-11 15:30:00

SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30');
Result: 2020-02-11 15:32:30

完全な単位(1分、1時間など)の場合は、これは類似のdate_truncの呼び出しと同じ結果を与えます。 違いは、date_binは任意の間隔へと切り捨てられることです。

stride間隔はゼロより大きくなければならず、かつ月単位あるいはそれよりも大きくてはいけません。

9.9.4. AT TIME ZONE

AT TIME ZONE構文を使用することにより、time stamp without time zoneからtime stamp with time zoneへ、あるいはtime with time zoneの値を異なる時間帯に変換することができます。 表 9.34にその種類を示します。

表9.34 AT TIME ZONEの種類

演算子

説明

timestamp without time zone AT TIME ZONE zonetimestamp with time zone

与えられた時間帯なしタイムスタンプを指定された時間帯にあるとして時間帯ありタイムスタンプに変換します。

timestamp '2001-02-16 20:38:40' at time zone 'America/Denver'2001-02-17 03:38:40+00

timestamp with time zone AT TIME ZONE zonetimestamp without time zone

与えられた時間帯付き時刻を、時刻がその時間帯にあるものとして時間帯なしタイムスタンプに変換します。

timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver'2001-02-16 18:38:40

time with time zone AT TIME ZONE zonetime with time zone

与えられた時刻with time zoneを新しい時間帯に変換します。 判断するためのデータがないので、現在の有効なUTCオフセットを目的の時間帯のために使用します。

time with time zone '05:34:17-05' at time zone 'UTC'10:34:17+00


これらの式では、設定する時間帯zoneは、('America/Los_Angeles'のような)テキスト値、または(INTERVAL '-08:00'のような)時間間隔で指定することができます。 テキストの場合、8.5.3に示した方法で時間帯名称を指定することができます。 時間間隔を使うのはUTCからの固定のオフセットを持つ時間帯でのみ有用なので、一般的に非常に有用であるとは言えません。

以下に例を示します(現在の時間帯(TimeZone)をAmerica/Los_Angelesと想定しています)。

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
Result: 2001-02-16 19:38:40-08

SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
Result: 2001-02-16 18:38:40

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
Result: 2001-02-16 05:38:40

最初の例は、時間帯のない値に時間帯を追加し、現在のTimeZone設定を使ってその値を表示します。 2番目の例は、time stamp with time zone値を指定した時間帯に変換し、その値をwithout a time zoneで返しています。 これは、TimeZone設定とは異なる値の格納と表示を可能にします。 3番目の例は、東京時間をシカゴ時間に変換します。

関数timezone(zone, timestamp)は、SQL準拠の構文timestamp AT TIME ZONE zoneと等価です。

9.9.5. 現在の日付/時刻

PostgreSQLは、現在の日付時刻に関した値を返す多くの関数を提供します。 これらの標準SQL関数はすべて、現在のトランザクションの開始時刻に基づいた値を返します。

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)

CURRENT_TIMEおよびCURRENT_TIMESTAMP関数では、時間帯を伴う値を扱います。一方、LOCALTIMEおよびLOCALTIMESTAMP関数では、時間帯を伴わない値を扱います。

CURRENT_TIMECURRENT_TIMESTAMPLOCALTIME、およびLOCALTIMESTAMP関数では、精度のパラメータをオプションで取ることができ、それに合わせて秒フィールドの端数桁を丸める結果をもたらします。 精度のパラメータがない場合、結果は使用可能な最大精度で出力されます。

例:

SELECT CURRENT_TIME;
Result: 14:39:53.662522-05

SELECT CURRENT_DATE;
Result: 2019-12-23

SELECT CURRENT_TIMESTAMP;
Result: 2019-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
Result: 2019-12-23 14:39:53.66-05

SELECT LOCALTIMESTAMP;
Result: 2019-12-23 14:39:53.662522

これらの関数は現在のトランザクションの開始時刻を返すため、その値はトランザクションが実行されている間は変化しません。 これは仕様であると考えられており、その意図は、単一のトランザクションが一貫性のある現在時刻の概念を持ち、同一トランザクション内の複数の変更が同一のタイムスタンプを持つようにすることにあります。

注記

他のデータベースシステムでは、これらの値をより頻繁に増加させることがあります。

PostgreSQLはまた、関数を呼び出した時の実際の現在時刻や現在の文の開始時刻を返す関数も提供します。 非標準SQLの時間関数の全一覧を以下に示します。

transaction_timestamp()
statement_timestamp()
clock_timestamp()
timeofday()
now()

transaction_timestamp()CURRENT_TIMESTAMPと等価ですが、明確に何を返すかを反映する名前になっています。 statement_timestamp()は現在の文の実行開始時刻を返すものです(より具体的にいうと、直前のコマンドメッセージをクライアントから受け取った時刻です)。 statement_timestamp()およびtransaction_timestamp()はトランザクションの最初のコマンドでは同じ値を返しますが、その後に引き続くコマンドでは異なる可能性があります。 clock_timestamp()は実際の現在時刻を返しますので、その値は単一のSQLコマンドであっても異なります。 timeofday()PostgreSQLの歴史的な関数です。 clock_timestamp()同様、実際の現在時刻を返しますが、timestamp with time zone型の値ではなく、整形されたtext文字列を返します。now()transaction_timestamp()と同じもので、伝統的なPostgreSQL関数です。

すべての日付/時刻型はまた、特殊なリテラル値 nowを受け付け、これは現在の日付と時刻(ここでも、トランザクションの開始時刻として解釈されます)を表します。 したがって、下記の3つの実行結果は全て同じものとなります。

SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP 'now';  -- but see tip below

ヒント

たとえばテーブルの列にDEFAULT句を指定するのに、後から評価される値を指定する際に3番目の形式は使わないでください。 システムはnowという定数を解析すると、すぐにそれをtimestampに変換するので、デフォルト値が必要が時には、テーブルが作成された時刻が使われます。 最初の2つの形式は関数呼び出しなので、デフォルト値が使用されるまで評価されません。 ですから、これらの関数は列の挿入時間をデフォルトとする、望ましい振舞いをします。 (8.5.1.4も見てください。)

9.9.6. 遅延実行

以下の関数は、サーバプロセスの実行を遅延させるために使用可能です。

pg_sleep ( double precision )
pg_sleep_for ( interval )
pg_sleep_until ( timestamp with time zone )

pg_sleepは、指定された秒数が経過するまで、現在のセッションのプロセスを休止させます。 pg_sleep_forintervalでより長い休止時間を指定する便利な関数です。 pg_sleep_untilは特定の起床時刻が望まれる場合に便利な関数です。 以下に例を示します。

SELECT pg_sleep(1.5);
SELECT pg_sleep_for('5 minutes');
SELECT pg_sleep_until('tomorrow 03:00');

注記

休止時間の有効な分解能はプラットフォームに依存します。0.01秒が一般的な値です。 休止による遅延は最短で指定した時間と同じになります。 サーバの負荷などが要因となり、より長くなる可能性があります。 特に、pg_sleep_untilは指定した時刻ちょうどに起床する保証はありませんが、それより早く起床することはありません。

警告

pg_sleepまたはその亜種を呼び出す時、セッションが必要以上のロックを保持していないことを確実にしてください。 さもないと、他のセッションが休止中のプロセスを待機しなければならないかもしれません。そのためシステム全体の速度が低下することになるかもしれません。