1. 程式人生 > >設定系統日期時間格式

設定系統日期時間格式

此函式用於設定系統的一些本地資訊, 非常有用.

比如日期格式為'yyyy/mm/dd'時, 稍微不注意,有些程式語句會報錯.

以下資料網路收集:

1. SetLocaleInfo()中 LCTYPE values 的具體意義

BOOL SetLocaleInfo(
LCID Locale, 
LCTYPE LCType, 
LPWTSTR lpLCData 
);

其中LCTYPE LCType引數的具體意義如下

Public:

CONSTANT Long LOCALE_SCURRENCY = 20 //本地語言貨幣符號
CONSTANT Long LOCALE_SINTLSYMBOL = 21 //國際貨幣符號
CONSTANT Long LOCALE_SMONDECIMALSEP = 22 //小數分隔符
CONSTANT Long LOCALE_SMONTHOUSANDSEP = 23 //千位分隔符
CONSTANT Long LOCALE_SMONGROUPING = 24 //資料分組方式
CONSTANT Long LOCALE_ICURRDIGITS = 25 //# 本地數字
CONSTANT Long LOCALE_IINTLCURRDIGITS = 26 //# 國際數字
CONSTANT Long LOCALE_ICURRENCY = 27 //貨幣正數表示模式
CONSTANT Long LOCALE_INEGCURR = 28 //貨幣負數表示模式

CONSTANT Long LOCALE_IPOSSIGNPOSN = 82 //貨幣正數符號的位置
CONSTANT Long LOCALE_INEGSIGNPOSN = 83 //貨幣負數符號的位置
CONSTANT Long LOCALE_IPOSSYMPRECEDES = 84 //正數中,貨幣符號位於值之前
CONSTANT Long LOCALE_IPOSSEPBYSPACE = 85 //正數中,貨幣符號與值之間被空格分開
CONSTANT Long LOCALE_INEGSYMPRECEDES = 86 //負數中,貨幣符號位於值之前
CONSTANT Long LOCALE_INEGSEPBYSPACE = 87 //負數中,貨幣符號與值之間被空格分開
CONSTANT Long LOCALE_FONTSIGNATURE = 88 //font signature

CONSTANT Long LOCALE_SENGCURRNAME = 4103 //貨幣的英語名稱
CONSTANT Long LOCALE_SNATIVECURRNAME = 4104 //貨幣的當地語言名稱

CONSTANT Long LOCALE_ILANGUAGE = 1 //語言ID
CONSTANT Long LOCALE_SLANGUAGE = 2 //語言區域名稱
CONSTANT Long LOCALE_SENGLANGUAGE = 4097 //語言英語名稱
CONSTANT Long LOCALE_SABBREVLANGNAME = 3 //語言名稱縮寫
CONSTANT Long LOCALE_SNATIVELANGNAME = 4 //當地語言名稱
CONSTANT Long LOCALE_ICOUNTRY = 5 //國家程式碼
CONSTANT Long LOCALE_SCOUNTRY = 6 //國家本地名稱
CONSTANT Long LOCALE_SENGCOUNTRY = 4098 //國家英語名稱
CONSTANT Long LOCALE_SABBREVCTRYNAME = 7 //國家名稱縮寫
CONSTANT Long LOCALE_SNATIVECTRYNAME = 8 //當地語言國家名稱
CONSTANT Long LOCALE_IDEFAULTLANGUAGE = 9 //預設語言ID
CONSTANT Long LOCALE_IDEFAULTCOUNTRY = 10 //預設國家程式碼
CONSTANT Long LOCALE_IDEFAULTCODEPAGE = 11 //預設的OEM程式碼
CONSTANT Long LOCALE_SLIST = 12 //list item separator
CONSTANT Long LOCALE_IDEFAULTANSICODEPAGE = 4100 //預設的ASCII程式碼
CONSTANT Long LOCALE_IDEFAULTMACCODEPAGE = 4113 //預設的MACINTOH程式碼
CONSTANT Long LOCALE_IMEASURE = 13 //0 = 公制, 1 = 美製
CONSTANT Long LOCALE_SDECIMAL = 14 //decimal separator
CONSTANT Long LOCALE_STHOUSAND = 15 //thousand separator
CONSTANT Long LOCALE_SGROUPING = 16 //digit grouping
CONSTANT Long LOCALE_IDIGITS = 17 //number of fractional digits
CONSTANT Long LOCALE_ILZERO = 18 //leading zeros for decimal
CONSTANT Long LOCALE_SNATIVEDIGITS = 19 //native ascii 0-9


//Windows NT 4.0/2000/XP
CONSTANT Long LOCALE_SISO639LANGNAME = 89 //ISO 語言縮寫名稱
CONSTANT Long LOCALE_SISO3166CTRYNAME = 90 //ISO 國家縮寫名稱
//Windows 2000/XP
CONSTANT Long LOCALE_IDEFAULTEBCDICCODEPAGE = 4114 //預設的EBCDIC程式碼
CONSTANT Long LOCALE_SSORTNAME = 4115 //排序名稱

CONSTANT Long LOCALE_INEGNUMBER = 4112 //negative number mode

CONSTANT Long LOCALE_SDATE = 29 //日期分隔符
CONSTANT Long LOCALE_STIME = 30 //時間風隔符
CONSTANT Long LOCALE_SSHORTDATE = 31 //短日期格式
CONSTANT Long LOCALE_SLONGDATE = 32 //長日期格式
CONSTANT Long LOCALE_STIMEFORMAT = 4009 //時間格式
CONSTANT Long LOCALE_IDATE = 33 //短日期格式的排列順序
CONSTANT Long LOCALE_ILDATE = 34 //長日期格式的排列順序
CONSTANT Long LOCALE_ITIME = 35 //時間格式標示符號
CONSTANT Long LOCALE_ITIMEMARKPOSN = 4011 //時間標記符位置
CONSTANT Long LOCALE_ICENTURY = 36 //世紀識別符 (短日期)
CONSTANT Long LOCALE_ITLZERO = 37 //時間數字前面前導0
CONSTANT Long LOCALE_IDAYLZERO = 38 //日期數字前面前導0 (短日期)
CONSTANT Long LOCALE_IMONLZERO = 39 //月份數字前面前導0 (短日期)
CONSTANT Long LOCALE_S1159 = 40 //AM 指示符
CONSTANT Long LOCALE_S2359 = 41 //PM 指示符
CONSTANT Long LOCALE_ICALENDARTYPE = 4105 //日曆型別指示符
CONSTANT Long LOCALE_IPAPERSIZE = 4106 //0 = letter, 1 = a4, 2 = legal, 3 = a3
CONSTANT Long LOCALE_IOPTIONALCALENDAR = 4107 //其它日曆型別指示符
CONSTANT Long LOCALE_IFIRSTDAYOFWEEK = 4108 //一週中的第一天指示符
CONSTANT Long LOCALE_IFIRSTWEEKOFYEAR = 4109 //一年中的第一週指示符
CONSTANT Long LOCALE_SDAYNAME1 = 42 //星期一的長名稱
CONSTANT Long LOCALE_SDAYNAME2 = 43 //星期二的長名稱
CONSTANT Long LOCALE_SDAYNAME3 = 44 //星期三的長名稱
CONSTANT Long LOCALE_SDAYNAME4 = 45 //星期四的長名稱
CONSTANT Long LOCALE_SDAYNAME5 = 46 //星期五的長名稱
CONSTANT Long LOCALE_SDAYNAME6 = 47 //星期六的長名稱
CONSTANT Long LOCALE_SDAYNAME7 = 48 //星期天的長名稱
CONSTANT Long LOCALE_SABBREVDAYNAME1 = 49 //星期一的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME2 = 50 //星期二的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME3 = 51 //星期三的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME4 = 52 //星期四的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME5 = 53 //星期五的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME6 = 54 //星期六的縮寫名稱
CONSTANT Long LOCALE_SABBREVDAYNAME7 = 55 //星期日的縮寫名稱
CONSTANT Long LOCALE_SMONTHNAME1 = 56 //一月的長名稱
CONSTANT Long LOCALE_SMONTHNAME2 = 57 //二月的長名稱
CONSTANT Long LOCALE_SMONTHNAME3 = 58 //三月的長名稱
CONSTANT Long LOCALE_SMONTHNAME4 = 59 //四月的長名稱
CONSTANT Long LOCALE_SMONTHNAME5 = 60 //五月的長名稱
CONSTANT Long LOCALE_SMONTHNAME6 = 61 //六月的長名稱
CONSTANT Long LOCALE_SMONTHNAME7 = 62 //七月的長名稱
CONSTANT Long LOCALE_SMONTHNAME8 = 63 //八月的長名稱
CONSTANT Long LOCALE_SMONTHNAME9 = 64 //九月的長名稱
CONSTANT Long LOCALE_SMONTHNAME10 = 65 //十月的長名稱
CONSTANT Long LOCALE_SMONTHNAME11 = 66 //十一月的長名稱
CONSTANT Long LOCALE_SMONTHNAME12 = 67 //十二月的長名稱
CONSTANT Long LOCALE_SMONTHNAME13 = 4110 //十三月的長名稱 (如果存在)
CONSTANT Long LOCALE_SABBREVMONTHNAME1 = 68 //一月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME2 = 69 //二月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME3 = 70 //三月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME4 = 71 //四月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME5 = 72 //五月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME6 = 73 //六月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME7 = 74 //七月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME8 = 75 //八月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME9 = 76 //九月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME10 = 77 //十月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME11 = 78 //十一月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME12 = 79 //十二月的縮寫名稱
CONSTANT Long LOCALE_SABBREVMONTHNAME13 = 4111 //十三月的縮寫名稱 (如果存在)
CONSTANT Long LOCALE_SPOSITIVESIGN = 80 //positive sign
CONSTANT Long LOCALE_SNEGATIVESIGN = 81 //negative sign

CONSTANT Long LOCALE_SYEARMONTH = 4102 //year month format string
CONSTANT Long LOCALE_IDIGITSUBSTITUTION = 4116 //0 = none, 1 = context, 2 = native digit

2. Delphi獲得與設定系統時間格式

在Delphi中,特別是在寫管理系統軟體時,經常要用到 FormatDateTime 以將 TDateTime 格式的日期時間轉換成字串形式的值顯示或儲存起來,或者用 StrToDateTime將字串形式的日期時間轉換成 TDateTime 然後再做其他操作。
在進行時間或日期的轉換時,會使用系統當前設定的時間日期格式。而如果時間日期格式與字串中的表示方式不相符,會使轉換過程失敗。例如當前短日期格式設定為'yyyy/MM/dd',而要轉為 '2006-10-20'這樣的字串為日期,就會報錯,說這不是一個有效的日期。
所以在進行轉換前,要確保系統的日期時間格式與程式中使用的相符。一種方法是在安裝時由安裝程式設定,或者明確告訴使用者必須設定成要求格式。另一種就是程式在啟動時,自動設定為需要的格式,退出程式時再恢復原來的設定。


需要用到的有兩個Windows API,一個是 GetLocaleInfo,一個是 SetLocaleInfo

查API說明:
int GetLocaleInfo(
LCID Locale, // locale identifier ,設定資訊的範圍,是系統級,還是當前使用者
LCTYPE LCType, // type of information,設定資訊的型別
LPTSTR lpLCData, // address of buffer for information,設定成的值,必須用 pchar的格式傳進去
int cchData // size of buffer
);

BOOL SetLocaleInfo(
LCID Locale, // locale identifier,同上
LCTYPE LCType, // type of information to set
LPCTSTR lpLCData // pointer to information to set
);

兩個函式的引數很類似,其中 Locale可以取兩個值:LOCALE_SYSTEM_DEFAULT,表示要操作的是系統預設的設定; LOCALE_USER_DEFAULT,表示要操作的是當前使用者的設定。還可以取其他值,用於具體修改某種語言區域的設定。一般取 LOCALE_USER_DEFAULT。
LCType,表示要操作資訊的型別,也就是要操作的是哪一種設定。可用的值有很多,Delphi的聯機幫助,或者查MSDN,都有一個大列表。但跟日期時間格式相關的一共有這幾個:
LOCALE_SSHORTDATE :短日期格式
LOCALE_SLONGDATE :長日期格式
LOCALE_STIMEFORMAT:時間格式
另外 LOCALE_STIME 表示時間分隔符,LOCALE_SDATE 表示日期分隔符。可以單獨使用,也可以在使用 LOCALE_SSHORTDATE 和 LOCALE_STIMEFORMAT 的同時一併修改,所以不需要單獨操作。
使用GetLocaleInfo或SetLocaleInfo時,每次只能操作一個型別。比如要同時設定短日期格式、長日期格式、時間格式,就必須分別用三個型別代號呼叫三次 SetLocaleInfo。
還要一個要注意的問題是,設定日期時間格式後,應該向當前系統的啟用視窗廣播發送 WM_SETTINGCHANGE 訊息,否則即使修改了,程式裡還是不能用的。
以下是獲取和設定的程式片斷。

1.//獲取時間日期格式

procedure GetDateTimeFormat();
var
buf:pchar;
i:integer;
GPrevShortDate,GPrevLongDate,GPrevTimeFormat:string;
begin
getmem(buf,100);
i:=100; //i必須在呼叫前賦值為buf緩衝區的長度。如果設為0或負值,將取不到設定的值
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SSHORTDATE,buf,i); //取當前使用者設定,短日期格式。
GPrevShortDate:=string(buf);
i:=100;
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SLONGDATE,buf,i); //取長日期格式
GPrevLongDate:=string(buf);
i:=100;
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_STIMEFORMAT,buf,i); //取時間格式
GPrevTimeFormat:=string(buf);
FreeMem(buf);
end;
2.//設定時間格式

procedure SetDateTimeFormat();
var
p:DWORD;
begin
SetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SSHORTDATE,pchar('yyyy-MM-dd')); //短日期
SetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SLONGDATE,pchar('yyyy''年''M''月 ''d''日'''));
SetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_STIMEFORMAT,pchar('H:mm:ss')); //設定時間 
SendMessageTimeOut(HWND_BROADCAST,WM_SETTINGCHANGE,0,0,SMTO_ABORTIFHUNG,10,p);
//設定完成後必須呼叫,通知其他程式格式已經更改,否則即使是程式自身也不能使用新設定的格式
end;

在程式初始化時呼叫GetDateTimeFormat,將取出的設定儲存起來,然後用SetDateTimeFormat設定需要的格式。在程式退出時再次呼叫SetDateTimeFormat將儲存的值寫回去。