プログラミング工房 > HSP > サンプルモジュール > 

UTC文字列とローカル時間文字列を相互変換

(2012/05/28更新)


参考ページ

このモジュールを作るにあたっては、msdnおよび「s-kitaの日記 - Win32API システム時刻を設定する」 (s-kitaさん)を参考にさせていただきました。


>> モジュールとテスト用のサンプルスクリプトをダウンロード

/***********************************************************

	"Sat May 12 23:11:33 +0000 2012"のような形式の文字列に
	対応した、UTC <=> ローカル時間相互変換モジュール

		【2012/05/28 更新】

***********************************************************/
#ifndef __GM_UTC_AND_LOCAL_TIME__
	#define global __GM_UTC_AND_LOCAL_TIME__

	#include "kernel32.as"
	#include "gm_datetime_str.hsp"

#module
	#const	SIZE_SYSTEMTIME	16
/*
* 日時文字列をSYSTEMTIME構造体へ変換(サブルーチン)
 */
#deffunc _str_to_systemtime str str_, array ret_systemtime_, var ret_bias_

	str_date_time	= str_
	split	str_date_time, " ", day_of_week, month, day, time, bias, year

	// monthを数字に
	month	= month_name_to_digit(month)
	// timeを分割して数字に
	split	time, ":", hour, minute, second

	sdim	ret_systemtime_, SIZE_SYSTEMTIME
	wpoke	ret_systemtime_, 0, int(year)
	wpoke	ret_systemtime_, 2, int(month)
	wpoke	ret_systemtime_, 4, int(dayofweek_name_to_digit(day_of_week))
	wpoke	ret_systemtime_, 6, int(day)
	wpoke	ret_systemtime_, 8, int(hour)
	wpoke	ret_systemtime_, 10, int(minute)
	wpoke	ret_systemtime_, 12, int(second)
	wpoke	ret_systemtime_, 14, 0	; milisecond

	sign	= strmid(bias, 0, 1)
	hour	= int(strmid(bias, 1, 2))
	minute	= int(strmid(bias, 3, 2))
	minutes	= hour * 60 + minute
	if (sign = "+") {
		ret_bias_	= minutes
	}
	else {
		ret_bias_	= -(minutes)
	}

	return
#global

#module
/*
* SYSTEMTIME構造体を日時文字列へ変換(サブルーチン)
 */
#deffunc _systemtime_to_str array systemtime_, int bias_, var ret_str_

	ret_str_	= digit_to_dayofweek_name(str(wpeek(systemtime_, 4))) + " "	; 曜日
	ret_str_	+= digit_to_month_name(str(wpeek(systemtime_, 2))) + " "	; 月
	ret_str_	+= strf("%02d", wpeek(systemtime_, 6)) + " "	; 日
	ret_str_	+= strf("%02d", wpeek(systemtime_, 8)) + ":"	; 時
	ret_str_	+= strf("%02d", wpeek(systemtime_, 10)) + ":"	; 分
	ret_str_	+= strf("%02d", wpeek(systemtime_, 12)) + " "	; 秒
	if (bias_ >= 0) {
		ret_str_	+= "+"
	}
	else {
		ret_str_	+= "-"
	}
	bias		= abs(bias_)
	bias_hour	= (bias / 60)
	bias_minite	= (bias \ 60)
	ret_str_	+= strf("%02d", bias_hour) + strf("%02d", bias_minite) + " "
	ret_str_	+= strf("%04d", wpeek(systemtime_, 0)); 年

	return
#global

#module
;	; SystemTimeToTzSpecificLocalTime 戻り値
;	#const	TIME_ZONE_ID_INVALID	0xFFFFFFFF
;	#const	TIME_ZONE_ID_UNKNOWN	0
;	#const	TIME_ZONE_ID_STANDARD	1
;	#const	TIME_ZONE_ID_DAYLIGHT	2
;
	#const	SIZE_SYSTEMTIME				16
	#const	SIZE_TIME_ZONE_INFORMATION	172
	#const	SIZE_FILETIME				8
	#const	BIAS_MINUTE_UTC				0
/*
* UTC -> ローカル時間
 */
#deffunc str_utc_to_local_time str str_utc_, var ret_str_local_time_ 

	str_utc		= str_utc_
	ret_str_local_time_	= ""

	/* SYSTEMTIME 構造体へ変換 */
	split	str_utc, " ", day_of_week, month, day, time, bias, year
	if (bias ! "+0000") {	; UTCではない
		return
	}
	; monthを数字に
	month	= month_name_to_digit(month)
	; timeを分割して数字に
	split	time, ":", hour, minute, second

	sdim	system_time, SIZE_SYSTEMTIME
	wpoke	system_time, 0, int(year)
	wpoke	system_time, 2, int(month)
	wpoke	system_time, 4, int(dayofweek_name_to_digit(day_of_week))
	wpoke	system_time, 6, int(day)
	wpoke	system_time, 8, int(hour)
	wpoke	system_time, 10, int(minute)
	wpoke	system_time, 12, int(second)
	wpoke	system_time, 14, 0

	/* ローカル時間へ変換 */
	sdim	localtime, SIZE_SYSTEMTIME
	SystemTimeToTzSpecificLocalTime 0, varptr(system_time), varptr(localtime)

	/* 変換後の日時を文字列に */
	ret_str_local_time_	= digit_to_dayofweek_name(str(wpeek(localtime, 4))) + " "	; 曜日
	ret_str_local_time_	+= digit_to_month_name(str(wpeek(localtime, 2))) + " "	; 月
	ret_str_local_time_	+= strf("%02d", wpeek(localtime, 6)) + " "	; 日
	ret_str_local_time_	+= strf("%02d", wpeek(localtime, 8)) + ":"	; 時
	ret_str_local_time_	+= strf("%02d", wpeek(localtime, 10)) + ":"	; 分
	ret_str_local_time_	+= strf("%02d", wpeek(localtime, 12)) + " "	; 秒

	sdim	tzi, SIZE_TIME_ZONE_INFORMATION ; TIME_ZONE_INFORMATION 構造体用
	GetTimeZoneInformation	varptr(tzi) ; タイムゾーン情報を取得

	; 時差の値を文字列化
	bias	= lpeek(tzi, 0);	: mes	"bias: "+bias
;	sdim	std_name, 64
;	memcpy	std_name, tzi, 64, 0, 4
;	std_name	= cnvwtos(std_name)	: mes	"std_name: "+std_name
;	; StandardDateは省略
;	std_bias	= lpeek(tzi, 84)	: mes	"std_bias: "+std_bias
;	sdim	dl_name, 64
;	memcpy	dl_name, tzi, 64, 0, 88
;	dl_name	= cnvwtos(dl_name)	: mes	"dl_name: "+dl_name
;	; DaylightDateは省略
;	dl_bias	= lpeek(tzi, 168)	: mes	"dl_bias: "+dl_bias+"\n"
	bias	-= (bias * 2)	; 符号を反転
	if (bias >= 0) {
		str_bias	= "+"
	}
	else {
		str_bias	= "-"
	}
	bias	= abs(bias)
	bias_hour	= (bias / 60)
	bias_minite	= (bias \ 60)
	str_bias	+= strf("%02d", bias_hour) + strf("%02d", bias_minite)
	ret_str_local_time_	+= str_bias + " "

	ret_str_local_time_	+= strf("%04d", wpeek(localtime, 0)); 年

	return
/*
* ローカル時間 -> UTC
 */
#deffunc str_local_time_to_utc str str_local_time_, var ret_str_utc_

	; 日時文字列をSYSTEMTIME構造体へ変換
	sdim	systemtime, SIZE_SYSTEMTIME
	_str_to_systemtime	str_local_time_, systemtime, bias

	; SYSTEMTIME構造体をFILETIME構造体へ変換
	sdim	local_filetime, SIZE_FILETIME
	SystemTimeToFileTime	varptr(systemtime), varptr(local_filetime)

	; FILETIME構造体に変換されたローカルタイムをUTCに変換
	sdim	utc_filetime, SIZE_FILETIME
	LocalFileTimeToFileTime	varptr(local_filetime), varptr(utc_filetime)

	; FILETIME構造体(UTC)をSYSTEMTIME構造体へ変換
	sdim	systemtime, SIZE_SYSTEMTIME
	FileTimeToSystemTime	varptr(utc_filetime), varptr(systemtime)

	; SYSTEMTIME構造体を日時文字列へ変換
	_systemtime_to_str	systemtime, BIAS_MINUTE_UTC, ret_str_utc_

	return

#global

#endif

/*
%dll
gm_utc_and_local_time.hsp
%date
2012/05/28
%author
chrono
%port
Win
%note
利用しているDLL	: kernel32.dll
利用しているモジュール	: gm_datetime_str.hsp

;----------
%index
str_utc_to_local_time
UTCを表す文字列をローカル時間のものに変換
%prm
p1, p2
p1="??? ??? ?? ??:??:?? +0000 ????"	: UTCを表す文字列、またはそれ
を格納した変数。(例: "Thu May 17 20:11:33 +0000 2012")
p2=var	: 変換後のローカル時間文字列を受け取るための文字列変数
%inst
"Thu May 17 20:11:33 +0000 2012"のようなフォーマットのUTCを表す
文字列を、命令を実行するPCに設定されているタイムゾーンのローカル
時間を表すもの(例: "Fri May 18 05:11:33 +0900 2012")に変換します。
%type
ユーザ定義命令
%sample
#include "gm_utc_and_local_time.hsp"
#define	STR_DATE	"Thu May 17 20:11:33 +0000 2012"
	mes	STR_DATE
	str_utc_to_local_time	STR_DATE, str_local_time
	mes	str_local_time
%href
str_local_time_to_utc

;----------
%index
str_local_time_to_utc
ローカル時間を表す文字列をUTCのものに変換
%prm
p1, p2
p1="??? ??? ?? ??:??:?? ????? ????"	: ローカル時間を表す文字列、
またはそれを格納した変数。(例: "Fri May 18 05:11:33 +0900 2012")
p2=var	: 変換後のUTC文字列を受け取るための文字列変数
%inst
"Fri May 18 05:11:33 +0900 2012"のようなフォーマットの、特定の
タイムゾーンのローカル時間を表す文字列を、UTCを表すもの
(例: "Thu May 17 20:11:33 +0000 2012")に変換します。
%type
ユーザ定義命令
%sample
#include "gm_utc_and_local_time.hsp"
#define	STR_DATE	"Fri May 18 05:11:33 +0900 2012"
	mes	STR_DATE
	str_local_time_to_utc	STR_DATE, str_utc
	mes	str_utc
%href
str_utc_to_local_time

%*/