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

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

表9.30 日付/時刻演算子

演算子名結果
+ date '2001-09-28' + integer '7'date '2001-10-05'
+ date '2001-09-28' + interval '1 hour'timestamp '2001-09-28 01:00:00'
+ date '2001-09-28' + time '03:00'timestamp '2001-09-28 03:00:00'
+ interval '1 day' + interval '1 hour'interval '1 day 01:00:00'
+ timestamp '2001-09-28 01:00' + interval '23 hours'timestamp '2001-09-29 00:00:00'
+ time '01:00' + interval '3 hours'time '04:00:00'
- - interval '23 hours'interval '-23:00:00'
- date '2001-10-01' - date '2001-09-28'integer '3'(日付)
- date '2001-10-01' - integer '7'date '2001-09-24'
- date '2001-09-28' - interval '1 hour'timestamp '2001-09-27 23:00:00'
- time '05:00' - time '03:00'interval '02:00:00'
- time '05:00' - interval '2 hours'time '03:00:00'
- timestamp '2001-09-28 23:00' - interval '23 hours'timestamp '2001-09-28 00:00:00'
- interval '1 day' - interval '1 hour'interval '1 day -01:00:00'
- timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'interval '1 day 15:00:00'
* 900 * interval '1 second'interval '00:15:00'
* 21 * interval '1 day'interval '21 days'
* double precision '3.5' * interval '1 hour'interval '03:30:00'
/ interval '1 hour' / double precision '1.5'interval '00:40:00'

表9.31 日付/時刻関数

関数名戻り値型説明結果
age(timestamp, timestamp) interval引数間の減算。日数だけでなく年と月を使用した言葉による結果を生成age(timestamp '2001-04-10', timestamp '1957-06-13')43 years 9 mons 27 days
age(timestamp)intervalcurrent_date(午前零時)から減算age(timestamp '1957-06-13')43 years 8 mons 3 days
clock_timestamp() timestamp with time zone現在の日付と時刻(文実行中に変化する)。9.9.4を参照。   
current_date date現在の日付。9.9.4を参照   
current_time time with time zone現在の時刻。9.9.4を参照。   
current_timestamp timestamp with time zone現在の日付と時刻(現在のトランザクションの開始時)。9.9.4を参照。   
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) double precision部分フィールドの取得。9.9.1を参照。 extract(hour from timestamp '2001-02-16 20:38:40')20
extract(field from interval)double precision部分フィールドの取得。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 '2001-02-16 21:28:30')true
isfinite(interval)boolean時間間隔が有限かどうかの検査isfinite(interval '4 hours')true
justify_days(interval) interval30日周期が1月を表すように時間間隔を調整justify_days(interval '35 days')1 mon 5 days
justify_hours(interval) interval24時間を1日とする時間間隔の調整justify_hours(interval '27 hours')1 day 03:00:00
justify_interval(interval) intervaljustify_daysおよびjustify_hoursを使用し、さらに符号による調整を行っての時間間隔の調整justify_interval(interval '1 mon -1 hour')29 days 23:00:00
localtime time現在の時刻。9.9.4を参照。   
localtimestamp timestamp現在の日付と時刻(現在のトランザクションの開始時)。9.9.4を参照。   
make_date(year int, month int, day int) date 年、月、日フィールドから日付を作成 make_date(2013, 7, 15)2013-07-15
make_interval(years int DEFAULT 0, months 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) 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 年、月、日、時、分、秒フィールドから時刻を作成 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 年、月、日、時、分、秒フィールドから時間帯付きの時刻を作成。timezoneが指定されていなければ、現在の時間帯が使われる。 make_timestamptz(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5+01
now() timestamp with time zone現在の日付と時刻(現在のトランザクションの開始時)。 9.9.4を参照。   
statement_timestamp() timestamp with time zone現在の日付と時刻(現在の文の開始時)。 9.9.4を参照。   
timeofday() text現在の日付と時刻(clock_timestampと似ているが、text型文字列として返す)。9.9.4を参照。   
transaction_timestamp() timestamp with time zone現在の日付と時刻(現在のトランザクションの開始時)。 9.9.4を参照。   
to_timestamp(double precision) timestamp with time zoneUnixエポック時間(1970-01-01 00:00:00+00からの経過秒数)をタイムスタンプに変換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';
結果: 2005-04-03 12:00:00-06
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
結果: 2005-04-03 13:00:00-06

その理由はAmerica/Denver時間帯で2005-04-03 02:00に夏時間への変更があるからです。

異なる月では日数が異なりますので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');

結果: 10537200
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
        EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
        / 60 / 60 / 24;

結果: 121.958333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';

結果: 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');

結果: 4 mons

9.9.1. EXTRACT, date_part

EXTRACT(field FROM source)

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

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.12

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

to_timestampで経過秒数をタイムスタンプ値に変換することができます。

SELECT to_timestamp(982384720.12);
Result: 2001-02-17 04:38:40.12+00
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リリースでは有効でありません。

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
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

端数を含んだ秒フィールド(0〜59[7])。

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

SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
Result: 28.5
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と同じです。

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. AT TIME ZONE

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

表9.32 AT TIME ZONEの種類

戻り値説明
timestamp without time zone AT TIME ZONE zone timestamp with time zone与えられた時間帯なしタイムスタンプを指定された時間帯にあるとして取り扱います。
timestamp with time zone AT TIME ZONE zone timestamp without time zone与えられた時間帯付きタイムスタンプを新規の時間帯に、時間帯の指定なく変換します。
time with time zone AT TIME ZONE zone time with time zone与えられた時刻with time zoneを新しい時間帯に変換します。

これらの式では、設定する時間帯zoneは、('America/Los_Angeles'のような)テキスト文字列、または(INTERVAL '-08:00'のような)時間間隔で指定することができます。 テキストの場合、8.5.3に示した方法で時間帯名称を指定することができます。

以下に例を示します(ローカル時間帯を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-05' 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.4. 現在の日付/時刻

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: 2001-12-23

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

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

SELECT LOCALTIMESTAMP;
Result: 2001-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';  -- DEFAULTで使用するのは正しくない

ヒント

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

9.9.5. 遅延実行

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

pg_sleep(seconds)
pg_sleep_for(interval)
pg_sleep_until(timestamp with time zone)

pg_sleepは、seconds秒経過するまで、現在のセッションのプロセスを休止させます。 secondsdouble precision型の値です。そのため、小数単位で休止秒数を指定することができます。 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またはその亜種を呼び出す時、セッションが必要以上のロックを保持していないことを確実にしてください。 さもないと、他のセッションが休止中のプロセスを待機しなければならないかもしれません。そのためシステム全体の速度が低下することになるかもしれません。



[7] オペレーティングシステムでうるう秒が実装されている場合は60まで。