大家都知道很多大主機(COBOL)的日期表示的年是用民國年,而且是只有兩位數,新舊平台之間的資料需要做轉換,例如 98 → 2009。
最近在修改一個程式bug發現一件非常有趣的一件事,關於民國百年的資料轉換,舉個例子,從舊平台資料MQ回到新平台日期為 00980911,這樣的資料一路PASS到前端的Java Script後如何轉換為西元年呢?
程式原本這樣寫
// PAY_DATE_POL =" 00980911"
var year = (eval(PAY_DATE_POL.substring(0, 4)) + 1911).toString();
這樣寫有什麼問題嗎? 好像沒問題,但事實上問題可大的呢,以下做幾項測試
x = eval("0098")+1911; // x 結果等於 2009,正確
x = eval("0099")+1911; // x 結果等於 2010,正確
x = eval("0100")+1911; // x 結果等於 1975,錯誤
x = eval("0101")+1911; // x 結果等於 1976,錯誤
.
.
.
x = eval("0107")+1911; // x 結果等於 1982,錯誤
x = eval("0108")+1911; // x 結果等於 2019,正確
x = eval("0109")+1911; // x 結果等於 2020,正確
這段程式若沒改會一路從民國100年錯到107年,以上結果可以自行上網測試看看 http://www.w3schools.com/js/tryit.asp?filename=tryjs_variables
原因為何?
詳細再追下去,錯的地方在 eval("0100") 計算出來結果居然是 64,以此類推
eval("0100") = 64
eval("0101") = 65
eval("0102") = 66
eval("0103") = 67
.
.
.
顯然Java Script 程式語言跟你有溝通有障礙,突然不懂程式在搞什麼鬼了><
但是突然間在 eval("0108") 計算結果又變回了 108,呵…夠好玩了吧
現在焦點應該要放在什麼情況下 "0100" 會變成 64 ?
公佈答案,主要原因是程式把 "0100" 解讀成八進位的數值了,而不是我們熟悉的十進位
0 x 8^3 + 1 x 8^2 + 0 x 8^1 + 0 x 8^0 = 64
那麼 "0108" 又變回 108 的原因就是八進位根本不可能有8嘛,所以程式又自動認定成十進位了,原來都是Java Script一廂情願的認知結果
所以其實Java Script語言,資料型態這部分並不是非常嚴謹的,相較於其他的正規語言,如: C/C++、java 來說,在寫Java Script時很容易就會掉進陷阱而不自知。
所以建議一,可以的話就在舊主台就把資料轉換為四位的西元年。
或者建議二,在java中用就把資料轉換為西元年,再丟到前端的jsp。
再不然建議三,在Java Script 一定要用parseInt()函數,強制指定認定十進位
x = parseInt("0100",10); // parseInt(string, radix)
這樣 x 的結果就會是正確的 100 囉^^
C/C++ 也會把 0100 認定為 64