日付/時刻演算と期間
日付/時刻の値は、増分、減分、および減算を行うことができます。 このような演算には、期間と呼ばれる 10 進数を使用する場合もあります。
期間
期間 とは、時間のインターバルを表す数値です。
- 1 非 10 進数の計算に日付とタイム・スタンプが含まれる場合、デフォルトは DAYS です。
- 2 非 10 進数の計算に時刻が含まれる場合、デフォルトは SECONDS です。
- ラベル付き期間
- 特定の時間単位を表すもので、数値 (式の結果でも可) の後に 7 つの期間キーワード (YEARS、MONTHS、DAYS、HOURS、MINUTES、SECONDS、または MICROSECONDS) のいずれかを付けたものです。 (これらのキーワードの単数形 YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、および MICROSECOND も可能です。) 指定した値は、DECIMAL(15,0) の数値へ割り当てられる場合と同様に変換されます。ただし、DECIMAL(27,12) を使用する SECONDS は別で、ここには 0 から 12 桁までの小数秒を組み込むことができます。 ラベル付き期間は、算術演算子の 1 つのオペランドとしてのみ使用でき、このときの他方のオペランドは DATE、TIME、または TIMESTAMP です。 したがって、式 HIREDATE + 2 MONTHS + 14 DAYS は有効ですが、式 HIREDATE + (2 MONTHS + 14 DAYS) は有効ではありません。 どちらの式でも 2 MONTHS と 14 DAYS がラベル付き期間です。
- 日付期間
- DECIMAL(8,0) の数値として表現される年数、月数、および日数。 正しく解釈されるには、この数値は yyyymmdd というフォーマットにする必要があります (yyyy は年数、mm は月数、dd は日数を表します)。 (このフォーマットの期間は、DECIMAL データ・タイプを示します。) 式 HIREDATE - BRTHDATE のように、ある日付値から別の日付値を減算した結果が日付期間です。
- 時刻期間
- DECIMAL(6,0) の数値として表現される時間数、分数、および秒数。 正しく解釈されるには、この数値は hhmmss. というフォーマットにする必要があります (hh は時間数、mm は分数、ss は秒数を表します)。 (このフォーマットの期間は、DECIMAL データ・タイプを示します。) ある時刻値から別の時刻値を減算した結果が時刻期間です。
- タイム・スタンプ期間
- DECIMAL(14+s,s) の数値 (s は小数秒の桁数で、0 から 12 の範囲) として表現される、年数、月数、日数、時間数、分数、秒数、および小数秒数。 正しく解釈されるには、この数値を yyyymmddhhmmss.nnnnnnnnnnnn というフォーマットにする必要があります (yyyy、mm、dd、hh、mm、ss、および nnnnnnnnnnnn はそれぞれ、年数、月数、日数、時間数、分数、秒数、および小数秒数を表します)。 あるタイム・スタンプ値から別のタイム・スタンプ値を減算した結果が、タイム・スタンプ期間で、このスケールは、タイム・スタンプ・オペランドの最大のタイム・スタンプ精度と一致します。
SQL における日付/時刻の算術演算
- 一方のオペランドが日付である場合、もう一方のオペランドは日付期間、または YEARS、MONTHS、DAYS のラベル付き期間であることが必要です。
- 一方のオペランドが時刻である場合、もう一方のオペランドは時刻期間、または HOURS、MINUTES、SECONDS のラベル付き期間であることが必要です。
- 一方のオペランドがタイム・スタンプである場合、もう一方のオペランドは期間でなければなりません。 この場合、期間のどのタイプでも有効です。
- 加算演算子のどちらのオペランドにも、パラメーター・マーカーは使用できません。
- 第 1 オペランドがタイム・スタンプの場合、第 2 オペランドは、日付、タイム・スタンプ、日付のストリング表記、タイム・スタンプのストリング表記、または期間であることが必要です。第 2 オペランドがタイム・スタンプのストリング表記である場合、第 1 オペランドと同じ精度のタイム・スタンプに暗黙的に変換されます。
- 第 2 オペランドがタイム・スタンプの場合、第 1 オペランドは、日付、タイム・スタンプ、日付のストリング表記、またはタイム・スタンプのストリング表記であることが必要です。第 1 オペランドがタイム・スタンプのストリング表記である場合、第 2 オペランドと同じ精度のタイム・スタンプに暗黙的に変換されます。
- 第 1 オペランドが日付の場合、第 2 オペランドは日付、日付期間、日付のストリング表記、または YEARS、MONTHS、DAYS のラベル付き期間であることが必要です。
- 第 2 オペランドが日付の場合、第 1 オペランドは、日付または日付のストリング表記であることが必要です。
- 第 1 オペランドが時刻の場合、第 2 オペランドは、時刻、時刻期間、時刻のストリング表記、または HOURS、MINUTES、SECONDS のラベル付き期間であることが必要です。
- 第 2 オペランドが時刻の場合、第 1 オペランドは、時刻または時刻のストリング表記であることが必要です。
- 減算演算子のどちらのオペランドにも、パラメーター・マーカーは使用できません。
日付の算術演算
日付は、減算、増分、および減分を行うことができます。
- ある日付 (DATE2) を別の日付 (DATE1) から減算した結果は、これら 2 つの日付の間の年数、月数、日数を示す日付期間です。
結果のデータ・タイプは DECIMAL(8,0) です。
DATE1 が DATE2 以上の場合、DATE1 から DATE2 が減算されます。
これに対し、DATE1 が DATE2 より小さい場合は、DATE2 から DATE1 が減算され、結果の符号が負になります。
演算 RESULT = DATE1 - DATE2 の実行ステップを、以下に順に示します。
If DAY(DATE2) <= DAY(DATE1) then DAY(RESULT) = DAY(DATE1) - DAY(DATE2).If DAY(DATE2) > DAY(DATE1) then DAY(RESULT) = N + DAY(DATE1) - DAY(DATE2) where N = the last day of MONTH(DATE2). MONTH(DATE2) is then incremented by 1.If MONTH(DATE2) <= MONTH(DATE1) then MONTH(RESULT) = MONTH(DATE1) - MONTH(DATE2).If MONTH(DATE2) > MONTH(DATE1) then MONTH(RESULT) = 12 + MONTH(DATE1) - MONTH(DATE2). YEAR(DATE2) is then incremented by 1.YEAR(RESULT) = YEAR(DATE1) - YEAR(DATE2).例えば、DATE('3/15/2000') - '12/31/1999' の結果は 00000215 になります。 (すなわち、0 年 2 カ月 15 日の期間です。)
- 日付に期間を加算したり、日付から期間を減算したりすると、結果自体は日付となります。
(この演算では、月はカレンダーのページに相当します。
つまり、日付に月を加算することは、その日付のページから順にカレンダーをめくっていくようなものです。)
結果は、0001 年 1 月 1 日以後 9999 年 12 月 31 日以前の日付となる必要があります。
年の期間を加算または減算する場合、影響を受けるのは日付の年の部分だけです。 月も日も変更されませんが、その結果がうるう年でない年の 2 月 29 日となった場合は別です。 その場合は日が 28 に変更され、SQLCA の警告標識が日付調整の発生を示すように設定されます。
同様に、月の期間を加算または減算する場合、影響を受けるのは月の部分だけです。 ただし、必要に応じて年の部分にも影響が及びます。 日付の日の部分は変更されませんが、結果が無効な場合 (例えば 9 月 31 日など) は別です。 その場合は日がその月の最後の日に設定され、SQLCA の警告標識が日付調整の発生を示すように設定されます。
日の期間を加算または減算すると、日付の中の日の部分は当然影響を受けますが、月および年も影響を受ける可能性があります。
日付期間も、正負にかかわらず、日付に対して加減算が行えます。 ラベル付き期間の場合と同じように、結果は有効な日付となり、月末の調整が必要になれば SQLCA の警告標識が設定されます。
正の日付期間が日付に加算されるとき、または負の日付期間が日付から減算されるときは、日付は、指定した年数、月数、日数の順で増分されます。 したがって、X が正の DECIMAL(8,0) の数値であるとき、DATE1 + X は以下の式と同等です。DATE1 + YEAR(X) YEARS + MONTH(X) MONTHS + DAY(X) DAYS.正の日付期間を日付から減算するとき、または負の日付期間を日付に加算するとき、日付は、指定した日数、月数、年数の順で減分されます。 したがって、X が正の DECIMAL(8,0) の数値であるとき、DATE1 - X は以下の式と同等です。DATE1 - DAY(X) DAYS - MONTH(X) MONTHS - YEAR(X) YEARS.期間を日付に加算するとき、特定の日付に 1 カ月を加算すると、1 カ月後の同じ日付になります。 ただし、1 カ月後にその日付が存在しない場合は扱いが異なります。 その場合、日付は 1 カ月後の最後の日に設定されます。 例えば、1 月 28 日に 1 カ月を加えると 2 月 28 日になります。 1 月 29、30、または 31 日に 1 カ月を加えると通常の年では 2 月 28 日、うるう年では 2 月 29 日になります。
注: 特定の日付に 1 カ月以上の月数を加算し、その結果から同じ月数を減算した場合、最終的な日付が元の日付と同じになるとは限りません。
時刻の算術演算
時刻は、減算、増分、または減分を行うことができます。
- ある時刻 (TIME2) を別の時刻 (TIME1) から減算した結果は、それら 2 つの時刻の間の時間数、分数、秒数を示す時刻期間です。
結果のデータ・タイプは DECIMAL(6,0) です。
TIME1 が TIME2 より大か等しい場合、TIME1 から TIME2 が減算されます。
これに対し、TIME1 が TIME2 より小さい場合は、TIME2 から TIME1 が減算され、結果の符号が負になります。 演算 RESULT = TIME1 - TIME2 の実行ステップを、以下に順に示します。If SECOND(TIME2) <= SECOND(TIME1) then SECOND(RESULT) = SECOND(TIME1) - SECOND(TIME2).If SECOND(TIME2) > SECOND(TIME1) then SECOND(RESULT) = 60 + SECOND(TIME1) - SECOND(TIME2). MINUTE(TIME2) is then incremented by 1.If MINUTE(TIME2) <= MINUTE(TIME1) then MINUTE(RESULT) = MINUTE(TIME1) - MINUTE(TIME2).If MINUTE(TIME1) > MINUTE(TIME1) then MINUTE(RESULT) = 60 + MINUTE(TIME1) - MINUTE(TIME2). HOUR(TIME2) is then incremented by 1.HOUR(RESULT) = HOUR(TIME1) - HOUR(TIME2).例えば、TIME('11:02:26') - '00:32:56' の結果は 102930 になります。 (10 時間 29 分、30 秒の期間です。)
- 時刻に期間を加算したり、時刻から期間を減算したりすると、結果自体は時刻となります。
時間数のオーバーフローやアンダーフローは捨てられ、これにより常に結果が時刻となります。
時間数で指定する期間を加算または減算する場合、影響を受けるのは時間数の部分だけです。
分数と秒数は変更されません。
同様に、分数で指定する期間を加算または減算する場合、影響を受けるのは分の部分だけです。 ただし、必要に応じて時間数の部分にも影響が及びます。 時刻の秒の部分は変更されません。
秒の期間を加算または減算すると、時刻の中の秒の部分は当然影響を受けますが、分および時も影響を受ける可能性があります。
時刻期間も、正負にかかわらず、時刻との加減算を行えます。 結果は、指定した時間数、分数、秒数の順に増分または減分された時刻となります。TIME1 + X(「X」は DECIMAL(6,0)) は次の式と同等です。TIME1 + HOUR(X) HOURS + MINUTE(X) MINUTES + SECOND(X) SECONDS値に秒の小数点部分が含まれる SECOND または SECONDS のラベル付き期間を減算する場合、その減算は最大で小数点以下 12 桁の秒が含まれる時刻値であるかのように実行されますが、戻させる結果では秒数の小数点部分は切り捨てられます。
注: 時刻 '24:00:00' は有効な値として受け付けられますが、時刻の加減算の結果として戻されることはありません。 これは、期間オペランドがゼロであっても同じです (例えば、時刻 ('24:00:00')±0 秒 ='00:00:00' となります)。
タイム・スタンプの算術演算
タイム・スタンプは、減算、増分、または減分を行うことができます。
- あるタイム・スタンプ (TS2) を別のタイム・スタンプ (TS1) から減算した結果がタイム・スタンプ期間で、それら 2 つのタイム・スタンプの間の年数、月数、日数、時間数、分数、秒数、および小数秒数で示されます。
結果のデータ・タイプは DECIMAL(14+s,s) です。s は、TS1 と TS2 の最大タイム・スタンプ精度です。TS1 が TS2 以上の場合、TS1 から TS2 が減算されます。 これに対し、TS1 が TS2 より小さい場合は、TS2 から TS1 が減算され、結果の符号が負になります。 演算 RESULT = TS1 - TS2 の実行ステップを、以下に順に示します。
If SECOND(TS2,s) <= SECOND(TS1,s) then SECOND(RESULT,s) = SECOND(TS1,s) - SECOND(TS2,s).If SECOND(TS2,s) > SECOND(TS1,s) then SECOND(RESULT,s) = 60 + SECOND(TS1,s) - SECOND(TS2,s). MINUTE(TS2) is then incremented by 1.タイム・スタンプの分の部分は、時刻の減算規則で指定されたように減算されます。If HOUR(TS2) <= HOUR(TS1) then HOUR(RESULT) = HOUR(TS1) - HOUR(TS2).If HOUR(TS2) > HOUR(TS1) then HOUR(RESULT) = 24 + HOUR(TS1) - HOUR(TS2) and DAY(TS2) is incremented by 1.タイム・スタンプの日付の部分は、日付の減算規則での説明と同じようにして減算されます。
- 日付 (D1) をタイム・スタンプ (TS1) から減算した結果は、TIMESTAMP(D1) を TS1 から減算した結果と同じです。同様に、あるタイム・スタンプ (TS1) を日付 (D2) から減算した結果は、TS1 を TIMESTAMP(D2) から減算した結果と同じです。
- タイム・スタンプに期間を加算したり、タイム・スタンプから期間を減算したりすると、その結果自体がタイム・スタンプとなります。結果のタイム・スタンプの精度は、タイム・スタンプ・オペランドの精度と一致します。
日付の算術計算部分は既に説明したとおりに実行されますが、時間数のオーバーフローとアンダーフローは結果の日付の部分に繰り上げまたは繰り下げられ、有効な日付の範囲内に収められます。
時刻の算術計算部分は、期間に秒数の小数点部分も考慮されるという点を除いては時刻の算術計算と同様です。
したがって、タイム・スタンプ TIMESTAMP1 からの期間 X (X は DECIMAL(14+s,s) の数値) の減算は、以下の式と同等です。
TIMESTAMP1 - YEAR(X) YEARS - MONTH(X) MONTHS - DAY(X) DAYS - HOUR(X) HOURS - MINUTE(X) MINUTES - SECOND(X, s) SECONDSゼロ以外の位取りの期間、または値に秒の小数点部分が含まれる SECOND または SECONDS のラベル付き期間を減算する場合、その減算は最大で小数点以下 12 桁の秒が含まれるタイム・スタンプ値であるかのように実行されます。結果値は、タイム・スタンプ・オペランドのタイム・スタンプの精度を持つタイム・スタンプ値に割り当てられ、その結果として秒の小数部分の桁は切り捨てられます。
