Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

DATEDIFF

2 つの日付の間に指定された datepart のために整数の差を返す、日付/時刻関数です。

Synopsis

DATEDIFF(datepart,startdate,enddate)

引数

datepart 日付または時刻部分の名前 (または省略形)。この名前は大文字でも小文字でも指定できます。引用符で囲んでも囲まなくてもかまいません。datepart はリテラルまたはホスト関数として指定できます。
startdate 間隔の開始の日付/時刻。さまざまな標準形式で日付、時刻、または日付/時刻を指定できます。
enddate 間隔の終了の日付/時刻。 さまざまな標準形式で日付、時刻、または日付/時刻を指定できます。startdateenddate から減算され、2 つの日付の間にある datepart 間隔が決定されます。

概要

DATEDIFF 関数は、2 つの指定された日付間の、指定された datepart の差の整数値を返します。日付の範囲は、startdate から始まり、enddate で終了します (enddatestartdate より前の場合、DATEDIFF は負の INTEGER 値を返します)。

DATEDIFF は、startdateenddate の間の、指定単位での合計数を返します。例えば、2 つの日付/時刻値の間の分数を評価して日付コンポーネントや時刻コンポーネントの値を求め、1 日の差ごとに 1440 分を加算します。DATEDIFF は、startdateenddate の間で交差する、指定された日付部分の境界のカウントを返します。例えば、連続する年を指定する 2 つの日付 (例 : 2010-09-23 と 2011-01-01) の場合、この 2 つの日付間の実際の期間が 365 日を超えているか、未満であるかに関係なく、年の DATEDIFF は 1 が返されます。同様に、12:23:59 と 12:24:05 の間の分数は、その 2 つの値が実際には 6 秒しか離れていないとしても、1 となります。

DATEDIFF では、Sybase および Microsoft SQL Server との互換性が提供されています。同様の日付/時刻比較演算は、TIMESTAMPDIFF ODBC スカラ関数を使用して実行することもできます。

この関数は、ObjectScript から DATEDIFF()Opens in a new tab メソッド呼び出しを使用して呼び出すこともできます。

$SYSTEM.SQL.DATEDIFF(datepart,startdate,enddate)

無効な datepartstartdate、または enddateDATEDIFF() メソッドに指定すると、<ZDDIF> エラーが発生します。

Datepart 引数

datepart 引数は、以下の日付/時刻コンポーネントの 1 つで、正式な名前 (日付部分列) または省略形 (省略形列) のいずれかになります。これらの datepart コンポーネント名と省略形では、大文字と小文字は区別されません。

日付部分 省略形
year yyyy, yy
month mm, m
week wk, ww
weekday dw
day dd, d
dayofyear dy
hour hh
minute mi, n
second ss, s
millisecond ms

weekday および dayofyear datepart の値は、day datepartの値と機能的に同じです。

DATEDIFFTIMESTAMPDIFF では、四半期 (3 か月の期間) は処理されません。

秒の小数部を含む startdate および enddate を指定した場合は、以下の例で示すように、1000 分の 1 秒 (0.001) 単位で表された秒の小数部数として差を取得できます。

SELECT DATEDIFF('ms','62871,56670.10','62871,56670.27'),     /* returns 170 */
       DATEDIFF('ms','62871,56670.1111','62871,56670.27222') /* returns 161.12 */

datepart は、引用符付き文字列として、または引用符なしで指定できます。以下のように構文に変化があると、実行される操作も少し異なります。

  • 引用符あり:DATEDIFF('month','2004-02-25',$HOROLOG)datepart は、クエリ・キャッシュの作成時にリテラルとして扱われます。Caché SQL は、リテラル置換を実行します。これにより、より一般的で再利用可能なクエリ・キャッシュが生成されます。

  • 引用符なし:DATEDIFF(month,'2004-02-25',$HOROLOG)datepart は、クエリ・キャッシュの作成時にキーワードとして扱われます。リテラル置換はありません。これにより、より特化したクエリ・キャッシュが生成されます。

日付式の形式

startdate および enddate 引数は、異なるデータ型形式で指定できます。

startdate 引数と enddate 引数は、以下のいずれかの形式で指定できます。

  • Caché %Date 論理値 (+$H)。$HOROLOG 形式とも呼ばれます。

  • Caché %TimeStamp (%Library.TimeStampOpens in a new tab) 論理値 (YYYY-MM-DD HH:MM:SS.FFF)。ODBC 形式とも呼ばれます。

  • Caché %String (または互換性のある) 値。

Caché %String (互換性のある) 値は、以下のいずれかの形式になります。秒の小数部は指定、省略のどちらでもかまいません。

  • 99999,99999 ($HOROLOG 形式)。$HOROLOG 特殊変数は秒の小数部を返しません。ただし、秒の小数部を含む値を $HOROLOG 形式で指定することはできます。99999,99999.999

  • Sybase/SQL-Server-date Sybase/SQL-Server-time

  • Sybase/SQL-Server-time Sybase/SQL-Server-date

  • Sybase/SQL-Server-date (既定時刻は 00:00:00)

  • Sybase/SQL-Server-time (既定日付は 01/01/1900)

Sybase/SQL-Server-date は、以下の 5 形式のいずれかです。

mm/dd/[yy]yy
dd Mmm[mm][,][yy]yy
dd [yy]yy Mmm[mm]
yyyy Mmm[mm] dd
yyyy [dd] Mmm[mm]

最初の構文形式では、区切りはスラッシュ (/)、ハイフン (-)、またはピリオド (.) のいずれかにできます。

Sybase/SQL-Server-time は、以下の 3 形式のいずれかです。

HH:MM[:SS[:FFF]][{AM|PM}]
HH:MM[:SS[.FFF]]
HH['']{AM|PM}

年が 2 桁で表示される場合、または日付が完全に省略される場合、Caché はスライディング・ウィンドウを確認して日付を解釈します。スライディング・ウィンドウのシステム全体の既定は 1900 です。したがって、既定では 2 桁の年は 20 世紀であると想定されます。詳細は、以下の例を参照してください。

SELECT DATEDIFF('year','10/11/14','09/14/2015'),
       DATEDIFF('year','12:00:00','2004-07-09 12:00:00')

このスライディング・ウィンドウの既定は、%DATE ユーティリティによりシステム全体または現在のプロセスを対象として設定できます。これについては、"InterSystems のドキュメントの使用法" の “旧ドキュメント” の章でのみ説明しています。2 桁の年で指定された日付を解釈するためのスライディング・ウィンドウの設定については、ObjectScript の $ZDATE$ZDATEH$ZDATETIME、および $ZDATETIMEH 関数のドキュメントを参照してください。

秒の小数部

DATEDIFF は、startdateenddate の小数桁数の精度に関係なく、秒の小数部をミリ秒 (3 桁の整数) として返します。3 桁を超える小数部の桁は、小数部のミリ秒として表されます。詳細は、以下の例を参照してください。

SELECT DATEDIFF('ms','12:00:00.1','12:00:00.2'),
       DATEDIFF('ms','12:00:00.10009','12:00:00.20007')

一部の NLS ロケールでは、小数部の区切りを、ピリオドではなくコンマ (ヨーロッパ形式) で指定します。現在のロケールがそれに該当する場合、DATEDIFF はローカル日付形式でピリオドまたはコンマのいずれかを、秒の小数部の区切り文字として受け取ります。$HOROLOG 形式の日付、または ODBC 形式の日付では、コンマを秒の小数部の区切りとして使用することはできません。これを実行しようとすると、SQLCODE -8 が生成されます。それらの形式はどちらも、現在の NLS のロケールに関係なく、ピリオドが必要です。

TimeFormat に依存しない時差

DATEDIFF は、現在のプロセスのための TimeFormat が秒を返さないように設定されている場合でも、秒およびミリ秒単位で時差を返します。詳細は、以下の例を参照してください。

  SET tfmt=##class(%SYS.NLS.Format).GetFormatItem("TimeFormat")
  DO ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",1)
     WRITE "datetime values (with seconds) are: ",!,
           $ZDATETIME("62871,56670.10",1,-1),"  ",$ZDATETIME("62871,56673.27",1,-1),!
  &sql(SELECT DATEDIFF('ss','62871,56670.10','62871,56673.27') INTO :x)
     WRITE "DATEDIFF number of seconds is: ",x,!!
  DO ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",2)
     WRITE "datetime values (without seconds) are: ",!,
           $ZDATETIME("62871,56670.10",1,-1),"  ",$ZDATETIME("62871,56673.27",1,-1),!
  &sql(SELECT DATEDIFF('ss','62871,56670.10','62871,56673.27') INTO :x)
     WRITE "DATEDIFF number of seconds is: ",x,!
  DO ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",tfmt)

範囲と値のチェック

DATEDIFF は、入力値に対して以下のチェックを実行します。

  • DATEDIFF 処理を実行するには、startdateenddate の指定された部分がすべて有効である必要があります。

  • 日付文字列は完全であると同時に、要素数、各要素の桁数、および区切り文字に適切な形式が使用されている必要があります。年は 4 桁で指定される必要があります。入力値の日付部分を省略した場合、DATEDIFF は既定で '1900–01–01' になります。無効な日付値を指定すると、SQLCODE -8 エラーになります。

  • 日付/時刻値は、有効な範囲内にある必要があります。年は 0001 から 9999、月は 1 から 12、日は 1 から 31、時間は 00 から 23、分は 0 から 59、秒は 0 から 59 がそれぞれ有効範囲です。月の日数は、該当月と該当年に合ったものでなければなりません。例えば、日付 '02–29' が有効なのは、指定された年がうるう年の場合のみです。無効な日付値を指定すると、SQLCODE -8 エラーになります。

  • 10 よりも小さい日付値 (月および日) の先頭の 0 は、記載、省略のどちらでもかまいません。その他の非標準的な整数値は許可されません。例えば、07 または 7 は有効な日値ですが、007、7.0、または 7a は無効です。

  • 時刻値は、全体または一部を省略できます。startdate または enddate で不完全な時刻が指定されている場合、指定されていない部分に対して 0 が指定されます。

  • 10 よりも小さい時間値の先頭の 0 は記載する必要があります。この先頭の 0 を省略すると、SQLCODE -8 エラーになります。

エラー処理

  • 埋め込み SQL では、入力変数として無効な datepart を指定した場合は、SQLCODE -8 エラー・コードが発行されます。リテラルとして無効な datepart を指定した場合は、<SYNTAX> エラーが発生します。入力変数またはリテラルとして無効な startdate または enddate を指定した場合は、SQLCODE -8 エラー・コードが発行されます。

  • ダイナミック SQL では、無効な datepartstartdate、または enddate を指定した場合は、DATEDIFF 関数は NULL 値を返します。SQLCODE エラーは発行されません。

以下の例では、2 つのタイムスタンプ間に 353 日間の差 (D) があるので、353 を返します。

SELECT DATEDIFF(D,'1999-01-01 00:00:00','1999-12-20 12:00:00')

以下の例では、それぞれの DATEDIFF が 1 を返します。これは、日付の年部分の差が 1 であるためです。2 つの日付の間の実際の期間は考慮されません。

SELECT DATEDIFF('yyyy','1910-08-21','1911-08-21') AS ExactYear,
       DATEDIFF('yyyy','1910-06-30','1911-01-01') AS HalfYear,
       DATEDIFF('yyyy','1910-01-01','1911-12-31') AS Nearly2Years,
       DATEDIFF('yyyy','1910-12-31 11:59:59','1911-01-01 00:00:00') AS NewYearSecond

上記の例は、datepart に省略形を使用しています。ただし、以下の例のように、正式な名前を指定することもできます。

SELECT DATEDIFF('year','1968-09-10 13:19:00','1999-12-20 00:00:00')

以下の埋め込み SQL の例では、ホスト変数を使用して前述の例と同じ DATEDIFF 処理を実行しています。

  SET x="year"
  SET date1="1968-09-10 13:19:00"
  SET date2="1999-12-20 00:00:00"
  &sql(SELECT DATEDIFF(:x,:date1,:date2)
       INTO :diff)
  WRITE diff

以下の例では、サブクエリを使用して、生年月日が現在の日付から 1500 日以内であるレコードが返されるようにします。

SELECT Name,Age,DOB
FROM (SELECT Name,Age,DOB, DATEDIFF('dy',DOB,$HOROLOG) AS DaysTo FROM Sample.Person)
WHERE DaysTo <= 1500
ORDER BY Age

関連項目

FeedbackOpens in a new tab