FormatDateTime 在有些機器上無法傳回民國年!? |
尚未結案
|
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
|
Jasonwong
版主 發表:49 回覆:931 積分:581 註冊:2006-10-27 發送簡訊給我 |
|
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
|
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
引言: [地區選項]的 "位置" 是 "中文(台灣)" 沒錯。 [地區選項]的每個頁夾我都檢查好幾次了。OK, 這樣的話, 應該就是他的日期真的設錯了. 請先確認他的西元年是不是正確的, 若用 e 會顯示 2003 年的話, 用 yyyy 會顯示 3914 年的, 請你確認一下! procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(FormatDateTime('[e, yyyy]', now)); end;正常的話, 會出現 [92, 2003], 若該電腦的日期是錯的, 會出現 [2003, 3914], 這樣了解嗎? 只要將該電腦的日期設正確就沒有問題了!! 發生的原因就會是在 [地區選項][日期]是設在民國, 但年份設為 2003 就會發生這個問題的! |
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
|
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
引言: 可是我試過,不管控制台的地區選項裡面設定成 "中華民國曆"、"西曆(英文)"、還是 "西曆(中文)",同樣的程式在我的電腦跑出來的結果都是一樣的,也就是三種月曆的設定,使用 FormatDateTime('eee', Now) 傳回的結果都是 '092',並沒有不同喔。 p.s. 那幾台有問題的電腦的日期時間是正確的,並沒有多加 1911 的情況。不, 我是要請你試的是 : ShowMessage(FormatDateTime('[e, yyyy]', now)); 另外再請你試試 ShowMessage(FormatDateTime('[g e]', now)); 看一下結果到底是什麼!! |
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
引言: 我覺得 ddy 可能是對的,還是用自己寫的函數來轉換好了。 Anyway 我還是會把您提供的上面兩道敘述試看看,等試出來後,結果再貼上來。只是可能要等一下下,因為有問題的機器在客戶那兒。ok, 等待你測試的結果. 補充一下, FormatDateTime 是沒有 eee 的參數哦, 只有 ee 的參數, 是針對 Taiwan, Japan, Korea 才有的地區年份哦, eee 是沒有意義的, 你可以自己試一下就知道了, 在 delphi help 中也是如此說明的!! 也就是說沒有 eee, 你說會回傳 '092' 應該不可能的, 應該只會回傳對應 ee 的 92 而已! 或者你試試看 eeee 會不會回傳 '0092'.. 之所以會請你測試 e, y 這樣同時出現的狀況, 才能知道是那裡的問題, 若是只憑 e 得到 2003 的話, 應該是電腦的時間有問題才對, 這是因為電腦內有其他的程式在取得系統日期時, 要使用西元曆, 但並沒有確認 locale 的設定直接修改為 2003, 也就造成了西元 3914 的現象的, 不過你也確認過了該電腦的日期是正確的, 所以弟才會建議你進行測試, anyway, 看測試後的結果再來看看問題在那裡!! 另外地區選項中的日期設定無論為"中華民國曆"、"西曆(英文)"、還是 "西曆(中文)"都不會影響 e, y 的顯示結果的, 所以改這個是完全沒有影響的! 以下為節錄 delphi help 中的 e 說明: ----------------------------- e (Windows only) Displays the year in the current period/era as a number without a leading zero (Japanese, Korean and Taiwanese locales only). ee (Windows only) Displays the year in the current period/era as a number with a leading zero (Japanese, Korean and Taiwanese locales only). |
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
ok, 各種測試結果如下:
(左邊是格式字串,右邊是結果)
'eee , yyyy' ==> '3 , 2003' 'g , e' ==> ' , 3' 'ee/mm/dd' ==> '03/07/08' 'yyyy/mm/dd' ==> '2003/07/08'顯然地,民國年在這台機器上都無法轉換成功。'eee' 的效果跟單個 'e' 是一樣的,都會顯示 2003 的最右邊的數字 '3'(不會補0)。而 'g' 則完全無作用,傳回一個空白字元。 Any idea ? 發表人 - darkside 於 2003/07/08 10:39:03 |
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
可否再請你試一下這段程式碼? 這就是會出現 locale 的 era string 的 windows api 的部分, 請先試一下看看!
procedure TForm1.Button2Click(Sender: TObject); var SystemTime: TSystemTime; FormatStr: string; Buffer: array[0..255] of Char; year, month, day: Word; begin FormatStr:='gg'; DecodeDate(Now, year, month, day); SystemTime.wYear:= year; SystemTime.wMonth:=month; SystemTime.wDay := day; GetDateFormat(GetThreadLocale, DATE_USE_ALT_CALENDAR, @SystemTime, PChar(FormatStr), Buffer, SizeOf(Buffer)); ShowMessage(Buffer); end; |
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
關於這個問題, 我提供一下我的經驗 ...
確實會有些機器會造成日期格式的不確定, 尤其是作過 XP SP1, 或安裝 Office (2000, XP 版)更是如此.
我公司有二台 OS (XP pro)及硬/軟體都一樣, 但是就是 ERA Year 硬是不同.
所以:
1. 不要太相信抓到的 ERA Year , 為此我改了好多元件
2. 不要用 FormatDateTime 或 DateToStr 之類 Date/Time 與 String 的轉換 function, 因為轉出來的不一定會是你要的(和 control panel 的地區設定有關), 你也不可能一台台改吧!
3. 使用 DecodeDate 或 EncodeDate 處理 Date/Time (一律是西元年)如果要轉成民國再減 1911 就是了
------
將問題盡快結案也是一種禮貌! |
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
我想客戶已經快被我煩死了,我也不好意思一直要客戶幫我測東西。
即使測出來了,若是作業環境的設定問題,或安裝了某些軟體所造成,若要一台一台機器檢查修改,也不切實際。雖然很想了解原因,但還是作罷。
因此我決定自己寫轉換函式,先把程式中所有 FormatDateTime('ee....) 的指令改呼叫自己的。 很感謝 Tim Huang 兄的熱心協助,以及其他人的建議。 順殯把我寫的函式貼上來,需要的人可以省一點功夫。支援民國前的年份。
(* 將日期轉成民國年格式的字串 ADate 輸入的日期 YearDigits 輸出的民國年要幾位數 Separator 日期分隔字元 *) function DateToRocStr(const ADate: TDateTime; YearDigits: Integer; Separator: string): string; var wYear, wMonth, wDay: word; iYear: Integer; sYear, sMonth, sDay: string; begin Assert((YearDigits > 0) and (YearDigits < 5)); DecodeDate(ADate, wYear, wMonth, wDay); if wYear < 1900 then begin Result := StrRepeat(' ', YearDigits) Separator ' ' Separator ' '; exit; end; iYear := wYear - 1911; sYear := StrRight('00000' IntToStr(iYear), YearDigits); if iYear < 1 then // 民國前? begin Dec(iYear); sYear := StrRight(' ' IntToStr(iYear), YearDigits); end; sMonth := Copy(IntToStr(wMonth 100), 2, 2); sDay := Copy(IntToStr(wDay 100), 2, 2); Result := sYear Separator sMonth Separator sDay; end; |
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
雖已討論結束, 我也來參一腳
darkside的碼解決了問題, 但對於太多已寫完的程式要去改成呼叫此function,事實上是有困難的 因此以下直接覆蓋掉sysutils中之DateTimeToStr及FormatDateTime,只要將此unit放在uses中之最後, 就可解決 這只是show一個想法, 實際要覆蓋的function 不只這兩個
function DateTimeToStr(DateTime: TDateTime): string; begin Result:=ConvertToTwDate(ShortdateFormat,DateTime); end; function FormatDateTime(const sFormat: string; DateTime: TDateTime): string; var yr:word; begin Result:=ConvertToTwDate(sFormat,DateTime); end; function ConvertToTwDate(sFormat:string;DateTime:TDateTime):string; var yr:word; begin //note:一般民國年均是 以年/月/日之方式, 不考慮年在後 Result:=sysutils.FormatDateTime(sFormat,DateTime); //先呼叫原function if pos('e/', sFormat) > 0 then begin Fetch(Result,'/'); yr:=YearOf(DateTime)-1911; if pos('eee/',sformat) > 0 then Result:=format('%3.3d', [yr] ) '/' result else if pos('ee/', sFormat) > 0 then Result:=format('-',[yr]) '/' result else Result:=format('%d',[yr]) '/' result; end; end; |
darkside
一般會員 發表:15 回覆:42 積分:16 註冊:2002-03-11 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |