無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

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

表9-27 は、日付/時刻型の値の処理で使用可能な関数を示しています。詳細は、以下の副節で説明します。 表9-26 は、( + * 等の)基本的な算術演算子の振舞いを説明しています。書式設定関数については 項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 型を取るものです。省略のため、これらの種類の違いは個別に示していません。また、 + * 演算子は交代演算子を持ちます(例えばdate + integerとinteger + date)。こうした組み合わせは片方のみ示します。

表 9-26. 日付/時刻演算子

演算子名 結果
+ 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-27. 日付/時刻関数

関数名 戻り値型 説明 結果
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') 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
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 ) 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
localtime time 現在の時刻。 項9.9.4 を参照。    
localtimestamp timestamp 現在の日付と時刻(現在のトランザクションの開始)。 項9.9.4 を参照。    
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 を参照。    

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

(

start1

, 

end1

) OVERLAPS (

start2

, 

end2

)
(

start1

, 

length1

) OVERLAPS (

start2

, 

length2

)

この式は、2つの時間間隔が重なる(その終端で定義されます)時に真を返します。重ならない場合は偽を返します。終端は日付、時刻、タイムスタンプ、もしくは、日付/時刻/タイムスタンプに続く時間間隔で指定されます。値の組み合わせが与えられた際、開始と終了のいずれを先に記述しても構いません。 OVERLAPS は与えられた値の内、若いものを開始として扱います。各時間間隔は、 start <= time < end といった半開区間として見なされます。ただし、 start end が同じ値の場合には単一の時間点となります。これは、例えば終了点のみが同じである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 の値を加える時(または timestamp with time zone の値から interval の値を差し引く時)日にちの部分は、日にちの数で示された 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' をもたらします。一方同じ初期 timestamp with time zone interval '24 hours' を加えると、 timestamp with time zone '2005-04-03 13:00-06' という結果になります。その理由は CST7CDT 時間帯で 2005-04-03 02:00 に夏時間への変更があるからです。

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

9.9.1. EXTRACT , date_part

EXTRACT(

field

 FROM 

source

)

extract 関数は、日付/時刻の値から年や時などの部分フィールドを抽出します。 source timestamp 型、 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世紀です。 この定義に納得できなければ、苦情をバチカンローマ聖パウロ大聖堂のローマ法王に伝えてください。

PostgreSQL リリース8.0以前では、世紀の番号付けの慣習に従っていませんでした。単に年を100で除算したものを返していました。

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からの秒数(負の数の場合もあり)。 date timestamp 型の値において、ローカルタイムの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

以下に、この経過秒数をタイムスタンプ値に変換する方法を示します。

SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720.12 * INTERVAL '1 second';

( to_timestamp 関数は上記の変換をカプセル化します。)

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

ミレニアム(1千年期間)

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

Result: 

3

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

PostgreSQL リリース8.0以前では、ミレニアムの番号付けの慣習に従っていませんでした。単に年フィールドを1000で割った値を返していました。

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、 [1] )。

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 はうるう秒を制御しないため UT1 を使用。)

timezone_hour

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

timezone_minute

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

week

その日の年間通算での週を計算します。( ISO 8601の)定義では週は月曜日から始まり、その年の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 関数は元々演算処理の目的でした。日付/時刻の値を表示する目的での書式については 項9.8 を参照してください。

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

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

)

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

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

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

例:

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

9.9.3. AT TIME ZONE

AT TIME ZONE 構文を使用することにより、タイムスタンプを異なる時間帯に変換することができます。 表9-28 にその種類を示します。

表 9-28. AT TIME ZONE Variants

戻り値 説明
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 は、( 'PST' のような)テキスト文字列、または( INTERVAL '-08:00' のような)時間間隔で指定することができます。 テキストの場合、 項8.5.3 に示した方法で時間帯名称を指定することができます。

以下に例を示します(ローカル時間帯を PST8PDT と想定しています)。

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';

Result: 

2001-02-16 19:38:40-08


SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';

Result: 

2001-02-16 18:38:40

最初の例は、時間帯のないタイプスタンプを使用し、それをMST時間(UTC-7)として解釈し、UTCタイムスタンプを生成します。それから、UTCタイムスタンプが、表示用にPST(UTC-7)に置き換えられます。2番目の例は、EST(UTC-5)で指定されたタイムスタンプを使用し、MST(UTC-7)でのローカル時間に変換しています。

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

9.9.4. Current Date/Time

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_TIME CURRENT_TIMESTAMP LOCALTIME 、および 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

これらの関数は、現在のトランザクションの開始時刻を返します。 この値は、トランザクションが実行されている間は変化しません。 これは、次の機能を検討した結果です。 単一トランザクションで、 "current" 時間を一貫性を持った表現を行うことができるようにすることを目的とし、このため、同一トランザクションで何回変更を行っても同一のタイムスタンプを生成します。

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

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';  -- incorrect for use with DEFAULT

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

9.9.5. 遅延実行

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

pg_sleep(

seconds

)

pg_sleep は、 seconds 秒経過するまで、現在のセッションのプロセスを休止させます。 seconds double precision 型の値です。 そのため、小数単位で休止秒数を指定することができます。以下に例を示します。

SELECT pg_sleep(1.5);

注意: 休止時間の有効な分解能はプラットフォームに依存します。0.01秒が一般的な値です。遅延は少なくとも指定した通り行われます。サーバの負荷が要因となり、より長くなる可能性があります。

警告

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

注意

[1]

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


powered by SEO.CUG.NET