〜 タイム 〜
協定世界時を日本標準時に変換 (要KERNEL32.DLL)

セシウム原子時計が刻む国際原子時(世界時)との差が1秒未満となるよう人工的に維持されている
協定世界時「UTC(niversalime,oordinated)」を
日本標準時「JST(apantandardime)」へ変換するTipsの紹介となりますが、
日本標準時は協定世界時よりも9時間進んでいるだけであり、
単純に協定世界時から9時間加算して返すだけではあまりにも芸がありませんので、
システムタイムを利用パソコンで設定されているタイムゾーンのローカルタイムに置き換えます。
また、変換対象はgettime等で取得する現在日時ではなく、API関数で使用されるSYSTEMTIME構造体で、
API関数SystemTimeToFileTimeで構造体に格納したシステム時刻をファイル時刻へ変換し、
API関数FileTimeToLocalFileTimeでUTCに基づくファイル時刻をローカルのファイル時刻へ変換、
API関数FileTimeToSystemTimeで最終的に元のシステム時刻を格納するSYSTEMTIME構造体に戻します。

具体的に、API関数SystemTimeToFileTimeの第1引数に元のシステム時刻を格納したSYSTEMTIME構造体、
第2引数に変換したファイル時刻を格納するFILETIME構造体のポインタを指定するので、
第1引数は配列4以上の数値型配列変数、第2引数は配列2以上の数値型配列変数を指定します。
尚、今回はFILETIME構造体は操作することがないので余談となりますが、
FILETIME構造体は32ビット2つで、1601年から100ナノ秒単位で表された64ビット値になります。
typedef struct SYSTEMTIME {
WORDwYear;// 年(要素0 >> 0) & 0xFFFF
WORDwMonth;// 月(要素0 >> 16) & 0xFFFF
WORDwWeek;// 曜日(要素1 >> 0) & 0xFFFF
WORDwDay;// 日(要素1 >> 16) & 0xFFFF
WORDwHour;// 時(要素2 >> 0) & 0xFFFF
WORDwMinute;// 分(要素2 >> 16) & 0xFFFF
WORDwSecond;// 秒(要素3 >> 0) & 0xFFFF
WORDwMilli;// ミリ(要素3 >> 16) & 0xFFFF
}
typedef struct FILETIME {
DWORDdwLdate;// 下位32ビット
DWORDdwHdate;// 上位32ビット
}
API関数FileTimeToLocalFileTimeは第1引数・第2引数共にFILETIME構造体のポインタを指定します。 API関数FileTimeToSystemTimeはAPI関数SystemTimeToFileTimeとは逆で、 第1引数に変換元のFILETIME構造体、第2引数に変換後のSYSTEMTIME構造体のポインタを指定します。 以上の指定を行うことでシステム時刻をタイムゾーンに適した時刻に変換できるわけですが、 SYSTEMTIME構造体はWORD(2バイト)毎なので、wpeek命令・関数か、ビット演算しなければなりません。 上で書いた「(要素0 >> 0) & 0xFFFF」のようにして取り出してあげましょう。 「SystemTimeToLocalTime」または「SystemTimeToLocalSystemTime」とでも呼べる処理で、 完全需要無視の、コチラで使うことを前提にしたようなモジュールです。 下記のサンプルは、API関数GetSystemTimeで「UTC標準時を日本時間に直すだけ」のサンプルです。 API関数GetSystemTimeは、引数に受取先SYSTEMTIME構造体のポインタを渡すだけのもので、 現在のシステム時刻を引数の変数に返すというものです。

utctojst 変換前日時, 変換後日時
変換前日時変換前の日時が入った配列変数を指定する。
変換後日時変換後の日時を入れる配列変数を指定する。

getsystemdate 受取先配列
受取先配列現在のグリニッジ標準時を格納する配列変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
	ll_libload kernel, "kernel32.dll"
	ll_getproc GetSystemTime, "GetSystemTime", kernel
	ll_getproc SystemTimeToFileTime, "SystemTimeToFileTime", kernel
	ll_getproc FileTimeToLocalFileTime, "FileTimeToLocalFileTime", kernel
	ll_getproc FileTimeToSystemTime, "FileTimeToSystemTime", kernel

#module
#deffunc utctojst val, val
	mref after, 16 : mref before, 17
	ll_getptr before : ll_ret j.0
	ll_getptr tmp : ll_ret j.1
	ll_getptr after : ll_ret j.2
	prm = j.0, j.1
	ll_callfunc prm, 2, SystemTimeToFileTime@
	prm = j.1, j.1
	ll_callfunc prm, 2, FileTimeToLocalFileTime@
	prm = j.1, j.2
	ll_callfunc prm, 2, FileTimeToSystemTime@
	return

#deffunc getsystemdate val
	mref date, 48
	ll_getptr date : ll_ret i
	ll_callfunc i, 1, GetSystemTime@
	return
#global

	dim st, 4
	getsystemdate st // 現在のシステム時刻を取得
	utctojst st, st  // ローカル時刻に変換
	wpeek tmp, st.0, 0 : date  = "" + tmp
	wpeek tmp, st.0, 2 : date += "/" + tmp
	wpeek tmp, st.1, 2 : date += "/" + tmp
	wpeek tmp, st.2, 0 : time  = "" + tmp
	wpeek tmp, st.2, 2 : time += ":" + tmp
	wpeek tmp, st.3, 0 : time += ":" + tmp
	mes "現在日付:" + date
	mes "現在時刻:" + time
	stop

utctojst 変換前日時, 変換後日時
変換前日時変換前の日時が入った配列変数を指定する。
変換後日時変換後の日時を入れる配列変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#uselib "kernel32.dll"
#func	global GetSystemTime "GetSystemTime" var
#func	global SystemTimeToFileTime "SystemTimeToFileTime" var, var
#func	global FileTimeToLocalFileTime "FileTimeToLocalFileTime" var, var
#func	global FileTimeToSystemTime "FileTimeToSystemTime" var, var

#module
#deffunc utctojst var after, var before, local i
	SystemTimeToFileTime before, i
	FileTimeToLocalFileTime i, i
	FileTimeToSystemTime i, after
	return
#global

	dim st, 4
	GetSystemTime st // 現在のシステム時刻を取得
	utctojst st, st  // ローカル時刻に変換
	mes "現在日付:" + wpeek(st.0, 0) + "/" + wpeek(st.0, 2) + "/" + wpeek(st.1, 2)
	mes "現在時刻:" + wpeek(st.2, 0) + ":" + wpeek(st.2, 2) + ":" + wpeek(st.3, 0)