現在の日付と時刻を得る
1 2 3 4 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- TIME DEC GET CURRENT DATE AND TIME + GR0 <-- TIME(0CYYDDDF) + GR1 <-- DATE(HHMMSSTH) |
TIMEマクロは、現在の日付と時刻を求めます。DECが基本的な返答形式で、GR0に時刻をHHMMSSTH(時分秒)で返します。Tは1/10秒、Hは1/100秒を示します。他にもいくつかの形式がありますので必要に応じて使い分けます。日付は、GR1にパック10進数0CYYDDDFで返ります。Cは世紀を表す数字で21世紀(2000~2099年)は1です。2008年なら1900年を起点に108年と見ればよいわけです。DDDは1月1日からの通算日付でジュリアンDATEと呼ばれます。Fはパック10進数の符号です。
TIMEは、現在の日付と時刻を得るための基本的なAPIですが、日付を月日で得られないためプログラム側でYYDDD形式をYYMMDD形式に変換する必要があります。
現在の日付と時刻を得る(新形式)
1 2 3 4 5 6 7 8 9 10 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- TIME DEC,TIMEAREA, GET CURRENT DATE AND TIME + DATETYPE=YYYYMMDD, (NEW FORMAT, MVS ONLY) + LINKAGE=SYSTEM : TIMEAREA DC 4F'0' 16BYTES TIME MACRO AREA ORG TIMEAREA DC XL8'00' HHMMSSTHMIJU0000 DC XL4'00' YYYYMMDD ORG , |
こちらは、新形式のTIMEマクロです。現時刻と日付は、レジスターではなく指定した16バイトの領域に符号無しパック10進数で返されます。時刻には1/100秒未満も返され、返答域のMIJUはそれぞれ1/1000、1/10000、1/100000、1/1000000秒に対応します。マクロ名は同じTIMEですが、LINKAGEパラメーターで新旧形式が区別されます。
TOD時計
TOD時計(TOD Clock)は、ハードウェアのタイマー機構の1つです。実際の時刻を示し、すべてのCPUで共用されます。TOD時計は、64ビットの2進数カウンターでビット51が1マイクロ秒(1/1000000秒)を示します。1マイクロ秒毎に、ビット51に1が加算されます。1マイクロ秒未満のビット52~63は、ハードウェア性能によって分解能が変わるため時刻表示には使われません。しかし、どのモデルであってもビット51は正しく1マイクロ秒毎に加算されるように設定されます。また、ビット31は1.048576秒毎に加算され、ほぼ1秒を示します。そのため、プログラムによってはTOD時計の先頭ワードのみを参照すれば、現在の日付と時刻を得るのに十分な精度が得られます。
1 2 3 4 5 |
0 63 +----------------------------------------------------------------------+ | 00000000 00000000 00000000 00000000 00000000 00000000 0000 | +-*--------------------------------------------------------*-----------+ ビット0 ビット51 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- STCK CLOCK1 EXTRACT CURRENT CLOCK STCKE CLOCK2 EXTRACT CURRENT CLOCK : CLOCK1 DC D'0' TOD CLOCK VALUE CLOCK2 DC 2D'0' EXTEND TOD CLOCK VALUE ORG CLOCK2 DC XL1'00' ZEROS DC XL13'00' 104BITS TOD CLOCK DC XL2'00' PROGRAMMABLE FIELD ORG , : TIME STCK,CLOCK1 EXTRACT TODCLOCK BY TIME SVC |
STCKはCPU命令です。現在のTOD時計の値をダブルワードの領域に格納します。STCKEはSTCKの拡張版で、ESA/390アーキテクチャー以降104ビットに拡張されたTOD時計の値を16バイトの領域に格納します。104ビットに拡張されたTOD時計も先頭のビット0~ビット51までは同じです。ビット51は1マイクロ秒を示します。将来の新CPUモデルでは2043年にTOD時計が一周してビット0が繰り上がると、STCKE命令で格納される先頭バイトに格納されるようになっています。プログラムは、引き続き1900年を起点にする標準エポックで計時が可能になります。2043年以降も使われるプログラムを作るなら、STCKE命令による拡張されたTOD時計のフォーマットと返答領域について知っておく必要があります。
TOD時計の値はTIMEマクロでも得ることは可能ですが、わざわざAPIコールをする必要はありません。STCK命令で直接求められます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- STCK DOUBLE EXTRACT CURRENT CLOCK STCKCONV DATETYPE=YYYYMMDD, CONVERT CLOCK VALUE + STCKVAL=DOUBLE, TO YYYYMMDDHHMMSSTHMIJU + CONVVAL=EDITAREA UNPK CHARAREA+0(9),EDITDATE(5) MAKE IT READABLE UNPK CHARAREA+8(13),EDITTIME(7) : : DOUBLE DC D'0' DOUBLE WORD WORKAREA EDITAREA DC XL16'00' FORMATTED CLOCK VALUE ORG EDITAREA DC XL8'00' HHMMSSTHMIJU0000(UNSIGNED PACK) DC XL4'00' YYYYMMDD (UNSIGNED PACK) DC XL4'00' --- RESERVED --- ORG , CHARAREA DC CL20' ',X'00' C'YYYYMMDDHHMMSSTHMIJU' |
TOD時計の値は、そのままではただの2進数カウンターに過ぎないので、表示に使うにはYYYYMMDDとHHMMSS形式に変換する必要があります。「OS/390アセンブラーハンドブック」でもTOD時計値の変換方法を解説していますが、現在では自作する必要はありません。クロック値を変換するサービスが用意されており、STCKCONVマクロ命令で呼び出すことができます。STCKVALに代えてSTCKEVALパラメーターを使えば拡張TOD時計値をサポートしますので、2043年以降もプログラム修正の必要がありません。
TIMEマクロを使うかSTCK命令を使うかはプログラム・デザイン次第ですが、日付や秒程度の分解能でかまわない時刻であればTIMEマクロが手軽です。デバッグや性能測定のためのログ情報などであれば、1/100秒程度ではメインフレームの場合分解能が低すぎるので1/1000000秒まで測定できるTOD時計値が適しています。頻繁に現時刻を取得するなら、STCKとSTCKEならただの機械命令ですからパフォーマンス面では軍配が上がります。将来性を考えてSTCKEを使用する場合は、時刻データの格納領域長は16バイト必要になります。