程式要轉換時間找不到時區,第三方api回傳的時區資訊是 MET( Middle European Time ), ,找了方法除了寫程式去處理例外、用第三方元件,最可靠的應該是自己新增登錄檔了。
之前碰到的,程式要轉換時間找不到時區,第三方api回傳的時區資訊是 MET( Middle European Time ), ,找了方法除了寫程式去處理例外、用第三方元件,最可靠的應該是自己新增登錄檔了。
找不到時區的錯誤:
自行新增登錄檔,他位於 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\這個資料夾裡面,到這個資料夾下就可以看到很多時區的資訊。
隨便點一個來看看 …
仿照他做一個新的,Display、Dlt和Std是描述,是字串值,直接編輯,沒問題。
再來三個MUI開頭的值,是用tzres.dll中的resource檔,後面的數字是resource的key值,目前沒辦法新增,但這個不影響轉換,只影響時區資訊的顯示,
例如:
在cmd中打上指令tzutil /l (列出本機上所有時區資訊),可以看到我新增的兩個時區VIncent time、Vincent Test Time中面的描述跟上面的Central Europe Standard Time一樣,就是因為MUI開頭的值,後面dll的字串值用的跟Central Europe Standard Time相同,好在他不影響轉換的計算,所以沒關係。
resource的key和value可以參考下面這個網站(這win10的,win7以前的要找自己另外找,不過大同小異啦,就是比win10少了一些而已)
http://windows10dll.nirsoft.net/tzres_dll.html
真正會影響計算的值是TZI,他的值和資料結構如下:
typedef struct _REG_TZI_FORMAT
{
LONG Bias;
LONG StandardBias;
LONG DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;
WORD佔2Byte,SYSTEMTIME總共2*8 = 16Byte,LONG佔4Byte,所以TZI_FORMAT佔了4*3 + 16*2 = 44 Byte符合上面值共44Byte,
計算可以看這個網頁,各欄位的詳細定義 TIME_ZONE_INFORMATION structure
看起來要計算很麻煩,但其實可以不用計算,因為大部份時區都有,所以直接找一個位於相同時區的,將他的TZI值照著寫進去就可以了。
上面這些東西最初是從這裡來的,也可以直接去看這個網頁 Exploring Windows Time Zones with System.TimeZoneInfo [Josh Free]
最後 ... 在上面第二張圖中,其實可以看到有些時區還有子資料夾[Dynamic DST],這個應該是記錄歷史的日光節約時間的,有變更都是windows update做的,我的目的只是要現在轉換成功,而且我做的這個,剛好沒有日光節約的間,有日光節約時間轉換也ok,(應該主要是參照TZI這個值來算,是不是歷史的會去套用到這個資料夾下的機碼我就沒有測試了),先不理他…。
打完收功!