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?

$HOROLOG

現在のプロセスのローカルな日付と時刻を含みます。

Synopsis

$HOROLOG
$H

概要

$HOROLOG には現在のプロセスの日付と時刻を記述します。以下の値を扱うことができます。

  • 現在のローカル日付とローカル時刻

  • タイム・ゾーンのオフセットに合わせて調整した現在のローカル日付とローカル時刻。

  • ユーザ指定のインクリメントされない日付。時刻は引き続き現在のローカル時刻です。

$HOROLOG は、コンマで区切られた 2 つの整数値から成る文字列を含みます。これらの 2 つの整数は、Caché に格納する形式で現在のローカル日付とローカル時刻を表します。これらの整数はカウンタで、外部でユーザが読み取れる日付と時刻ではありません。$HOROLOG は、次の形式で現在の日付と時刻を返します。

ddddd,sssss

最初の整数 ddddd は、1840 年 12 月 31 日からの現在の経過日数です。つまり、日 1 は 1841 年 1 月 1 日です。Caché は任意の開始ポイントからのカウンタを使用して日付を表すので、2000 年問題の影響は受けません。この日付整数の最大値は 2980013 で、9999 年 12 月 31 日に対応します。

2 番目の整数 sssss は現在の時刻で、その日の午前 0 時 00 分からの秒数で表されます。システムは、0 から 86399 秒で時間フィールドをインクリメントします。深夜 12 時に 86399 に到達すると、システムは時間フィールドを 0 にリセットしてから、日付フィールドを 1 つインクリメントします。$HOROLOG では秒の小数部分が切り捨てられ、整数秒のみで表されます。

以下のように、Horolog()Opens in a new tab メソッドを呼び出すことで、同じ現在の日付と時刻を取得することができます。

   WRITE $SYSTEM.SYS.Horolog()

詳細は、"インターシステムズ・クラス・リファレンス" の %SYSTEM.SYSOpens in a new tab を参照してください。

日付と時刻の分割

$HOROLOG の日付部分または時刻部分のみを取得するには、区切り文字としてコンマを指定して、$PIECE 関数を使用します。

   SET dateint=$PIECE($HOROLOG,",",1)
   SET timeint=$PIECE($HOROLOG,",",2)
   WRITE !,"Date and time: ",$HOROLOG
   WRITE !,"Date only: ",dateint
   WRITE !,"Time only: ",timeint

$HOROLOG 値の日付部分のみを取得する場合は、次のプログラミング方法を使用することもできます。

   SET dateint=+$HOROLOG
   WRITE !,"Date and time: ",$HOROLOG
   WRITE !,"Date only: ",dateint

プラス記号 (+) によって、$HOROLOG 文字列が数値として解析されます。数値以外の文字 (コンマ) が検出されると、残りの文字列は切り捨てられ、数値部分が返されます。これが、文字列の日付整数部分です。

日付/時刻関数の比較

現在の日付と時刻は、さまざまな方法で返すことができますが、その違いを以下に示します。

  • $HOROLOG には、ローカル調整された日付と時刻が Caché ストレージ形式で格納されます。ローカル・タイム・ゾーンは、$ZTIMEZONE 特殊変数の現在の値で決まり、サマータイムなどのローカル時刻調整に合わせて調整されます。これは、整数秒のみを返し、小数部分は切り捨てられます。

  • $NOW は、現在のプロセスのローカルな日付と時刻を返します。$NOW は、日付と時刻を Caché ストレージ形式で返します。これには、秒の小数部が含まれます。小数桁数は、現在のオペレーティング・システムでサポートされている最大精度の桁数です。

    • $NOW は、$ZTIMEZONE 特殊変数の値からローカル・タイム・ゾーンを決定します。ローカル時刻は、サマータイムなどのローカル時刻調整に合わせて調整されません。したがって、ローカルな時刻に対応しない場合があります。

    • $NOW(tzmins) は、指定された tzmins タイム・ゾーン・パラメータに対応する時刻と日付を返します。$ZTIMEZONE の値は無視されます。

  • $ZTIMESTAMP には、秒の小数部を含む UTC (協定世界時) の日付と時刻が Caché ストレージ形式で格納されます。秒の小数部は、Windows システムでは有効桁数 3 桁で、UNIX® システムでは有効桁数 6 桁で表されます。

日付・時刻の変換

$ZDATE 関数を使用して、外部でユーザが読み取れる形式に $HOROLOG の日付部分を変換できます。$ZTIME 関数を使用して、外部でユーザが読み取れる形式に $HOROLOG の時刻部分を変換できます。$ZDATETIME 関数を使用して、日付と時刻の両方を変換できます。$HOROLOG を使用した場合、これらの関数の時刻値の precision を設定すると、秒の小数部として常にゼロが返されます。

$ZDATEH 関数を使用して、外部でユーザが読み取れる形式に $HOROLOG の日付部分を変換できます。$ZTIMEH 関数を使用して、外部でユーザが読み取れる形式に $HOROLOG の時刻部分を変換できます。$ZDATETIMEH 関数を使用して、$HOROLOG 値の日付と時刻の両方を変換できます。

日付と時刻の設定

$HOROLOG は、%SYSTEM.ProcessOpens in a new tab クラスの FixedDate()Opens in a new tab メソッドを使用して、現在のプロセスのユーザ指定の日付に設定することができます。SET コマンドを使用して、$HOROLOG を変更することはできません。変更を試みると、<SYNTAX> エラーが返されます。

   DO ##class(%SYSTEM.Process).FixedDate(12345)  // set $HOROLOG date
   WRITE !,$ZDATETIME($HOROLOG,1,1,9)," $HOROLOG changed date"
   WRITE !,$ZDATETIME($NOW(),1,1,9)," $NOW() no date change"
   WRITE !,$ZDATETIME($ZDATETIMEH($ZTIMESTAMP,-3),1,1,9)," $ZTS UTC-to-local",
           " no date change"
   DO ##class(%SYSTEM.Process).FixedDate(0)    // restore $HOROLOG
   WRITE !,$ZDATETIME($HOROLOG,1,1,9)," $HOROLOG current date"

FixedDate()$HOROLOG 値を変更しますが、$NOW または $ZTIMESTAMP の値は変更しないことに注意してください。

タイム・ゾーン

既定では、$HOROLOG はローカル・タイム・ゾーンの日付と時刻を記述します。この既定のタイム・ゾーンはオペレーティング・システムで指定します。Caché では、この既定の設定を使用して $ZTIMEZONE の既定値を設定します。

$ZTIMEZONE を変更すると、現在のプロセスの $HOROLOG の値に影響します。これは、$HOROLOG の時間部分を変更し、またこの変更が $HOROLOG の日付部分を変更します。$ZTIMEZONE はグリニッジ子午線からのタイム・ゾーンの固定オフセットです。サマータイムなどの季節的なローカル時刻調整には対応していません。

サマータイム

$HOROLOG は、基本となるオペレーティング・システムが提供するアルゴリズムに基づいて、季節的な時刻調整に対応します。$ZTIMEZONE 値を適用すると、Caché はオペレーティング・システムのローカル時刻を使用して、サマータイムなどの季節的な時刻調整に使用するために (必要に応じて) $HOROLOG を調整します。

現在の日付または指定した日時に対してサマータイムが適用されているかどうかを確認するには、IsDST()Opens in a new tab メソッドを使用します。以下の例は、現在の日時のサマータイム (DST) の状態を返します。この状態はプログラムの実行中に変化する可能性があるため、この例では 2 回確認しています。

CheckDST
  SET x=$SYSTEM.Util.IsDST()
  SET local=$ZDATETIME($HOROLOG)
  SET x2=$SYSTEM.Util.IsDST()
  GOTO:x'=x2 CheckDST
  IF x=1 {WRITE local," DST in effect"}
  ELSEIF x=0 {WRITE local," DST not in effect"}
  ELSE {WRITE local," DST setting cannot be determined"}

季節的な時刻調節の適用は、(少なくとも) 以下の 3 つの考慮事項によって異なります。

  • オペレーティング・システム : タイム・ゾーンが同一でも、コンピュータが異なれば、指定した日付に対する $HOROLOG も異なる可能性があります。これは、オペレーティング・システムによって、使用する時刻調整の適用アルゴリズムが異なるためです。サマータイムの開始日と終了日 (およびその他の時刻調整) を管理する制度が変更されているので、古いオペレーティング・システムには現在の実態が反映されていない可能性があります。したがって、過去の $HOROLOG 値を使用する計算では、その時点で効力のあった開始日と終了日ではなく、現在の開始日と終了日を使用して調整が行われる可能性があります。

  • 各国政策の変更 : 季節的な時刻調整は、大半の欧州諸国では 1916 年、米国では 1918 年に採用されて以来、数多くの変更が行われてきました。サマータイムはさまざまな地域で、政府方針により採用され、廃止され、再び採用されています。サマータイムの開始日および終了日も何度となく変更されています。米国では、最近だけでも 1966 年、1974 ~ 1975 年、1987 年、および 2007 年に国内政策が変更されています。また、地域の法的処置により、国内政策が採用されることもあれば、不採用になることもあります。例えば、アリゾナ州ではサマータイムは導入されていません。

  • 地理的条件 : サマータイム。DST の開始日にローカル時計を進め (“Spring ahead”)、DST の終了日に遅らせます (“Fall back”)。したがって、タイムゾーンが同一でも、北半球と南半球とではサマータイムの開始日と終了日が逆になることが普通です。また、赤道付近の国々や、アジアおよびアフリカの大半の国では、サマータイムは導入されていません。

ローカル時刻調整のしきい値

$HOROLOG では、システム時計を参照して午前 0 時からの秒数を計算します。このため、サマータイムの開始や終了時など、ローカル時刻調整しきい値を超えたときにシステム時計が自動的に再設定されると、$HOROLOG の時刻値も該当する秒数だけ前または後に突然変更されます。したがって、2 つの $HOROLOG 時刻値を比較した場合、2 つの値の間の期間にローカル時刻調整しきい値が含まれていると、予期しない結果が生じることがあります。

$NOW ではローカル時刻調整に合わせた調整を行いません。日付および時刻の値を比較する際に、2 つの値の間の期間にローカル時刻調整しきい値が含まれている場合には、これを使用することをお勧めします。

1840 年より前の日付

$HOROLOG を使用して、1840 年から 9999 年までの範囲外の日付を直接表すことはできません。ただし、Caché SQL のユリウス日付機能を使用することで、この範囲外の日付を表すことができます。ユリウス日付は、紀元前 4711 年 (BCE) からカウントした符号なし整数として表されます。ユリウス日付には時刻コンポーネントはありません。

Caché の $HOROLOG 日付を Caché のユリウス日付に変換するには、TO_CHAR SQL 関数、または %SYSTEM.SQLOpens in a new tab クラスの TOCHAR()Opens in a new tab メソッドを使用します。Caché のユリウス日付を Caché の $HOROLOG 日付に変換するには、TO_DATE SQL 関数、または %SYSTEM.SQLOpens in a new tab クラスの TODATE()Opens in a new tab メソッドを使用します。

以下の例は、現在の $HOROLOG 日付を取り、これをユリウス日付に変換しています。$HOROLOG の前のプラス記号 (+) により、Caché ではこれが数値として扱われるので、コンマの位置で切り捨てられ、時刻整数が削除されます。

  WRITE !,"Horolog date = ",+$H
  SET x=$SYSTEM.SQL.TOCHAR(+$HOROLOG,"J")
  WRITE !,"Julian date = ",x

以下の例は、ユリウス日付を取り、これを Caché の $HOROLOG 日付に変換しています。

  SET x=$SYSTEM.SQL.TODATE(2455030,"J")
  WRITE !,"$HOROLOG date = ",x," = ", $ZDATE(x,1)

ただし、1721100 未満のユリウス日付値は変換できず、<ILLEGAL VALUE> エラーが生成されます。

ユリウス日付に関する詳細は、"Caché SQL リファレンス" の "TO_DATE" および "TO_CHAR" を参照してください。

$HOROLOG の最初の日付の詳細は、“ヒストリカル・ノート” のセクションを参照してください。

以下の例は、$HOROLOG の現在の内容を表示します。

   WRITE $HOROLOG

これは、62210,49170 の形式で値を返します。

以下の例は $ZDATE を使用して、$HOROLOG のデータ・フィールドをデータ形式に変換します。

   WRITE $ZDATE($PIECE($HOROLOG,",",1))

04/29/2011 の形式で値を返します。

次の例では、$HOROLOG の時刻部分が 12 時間 (a.m. または p.m.) 表示の時間:分:秒形式の時刻に変換されます。

CLOCKTIME    
  NEW
  SET Time=$PIECE($HOROLOG,",",2)
  SET Sec=Time#60
  SET Totmin=Time\60
  SET Min=Totmin#60
  SET Milhour=Totmin\60
  IF Milhour=12 { SET Hour=12,Meridian=" pm" }
  ELSEIF Milhour>12 { SET Hour=Milhour-12,Meridian=" pm" }
  ELSE { SET Hour=Milhour,Meridian=" am" }
  WRITE !,Hour,":",Min,":",Sec,Meridian
  QUIT

ヒストリカル・ノート

メリーランド州シルバースプリングで開催された M テクノロジ学会大会で発行された “M Computing” のコラム “Just Ask!” (1993 年 9 月号) で、James M. Poitras 氏は $HOROLOG の最初の日付の選択について次のように記述しています。


    "Starting in early 1969, our group created the Chemistry Lab
     application at Massachusetts General Hospital (MGH), which was
     the first package in the MGH MUMPS with Global Data Storage and
     many of the features of the language today..."

    "When we started programming, there were no utility programs of
     any type. We had to write them all: time, date, verify database,
     global tally, print routine, etc. I ended up writing initial
     versions of most of these.

    "When I decided on specifications for the date routine, I
     remembered reading of the oldest (one of the oldest?)
     U.S. citizen, a Civil War veteran, who was 121 years old at the
     time. Since I wanted to be able to represent dates in a
     Julian-type form so that age could be easily calculated and to be
     able to represent any birth date in the numeric range selected, I
     decided that a starting date in the early 1840s would be 'safe'.
     Since my algorithm worked most logically when every fourth year
     was a leap year, the first year was taken as 1841. The zero point
     was then December 30, 1840...

    "That's the origin of December 31, 1840 or January 1, 1841. I
      wasn't party to the MDC (M Development Committee) negotiations,
      but I did explain the logic of my choice to members of the
      Committee." 

関連項目

FeedbackOpens in a new tab