[DotNet][C#]還在使用-1911算民國年嗎?
主題: |
[DotNet][C#]還在使用-1911算民國年嗎? |
文章簡介: |
介紹TaiwanCalendar類別的使用 |
作者: |
陳乾正 |
版本/產出日期: |
V1.0 / 2015.11.26 |
1. 前言
許久以來,在程式設計遇到西元年轉換民國年最直覺的方式,就是西元年減掉1911,因為西元年與民國年差別,只在於年份與紀元不同,月、日規則則相同,包含閏年調整也是一致,不似陰陽曆(農民曆)有一套複雜的曆法規則;而時至今日,在程式開發上有不斷的進步,多數的開發工具平台,都已提供完整多國語言文化的基礎函式庫可使用,例如,自DotNet Framework 2.0開始,即提供了TaiwanCalendar類別,可做台灣當地的時間處理。
2. 目的
• 瞭解民國年轉換誤用可能發生的陷阱。
• 瞭解DotNet TaiwanCalendar類別使用方式。
3. 開始前準備
本架構建立於以下版本的環境:
• DotNet Framework 2.0 以上版本
• Visual Studio 2005以上版本
4. 閏年蟲
為什麼有閏年蟲呢?
其實,它跟千禧蟲或是民國百年蟲都是類似情形,因為系統程式處理日期數值時,未考慮超出日期範圍時的狀況所致,輕則系統當機、程式無法正常運行、資料錯誤,重則造成重大金融損失,而且前二者是一千年、一百年才會遇到一次,有充份的時間及警覺可做反應,閏年蟲則是每四年就輪迴一次,而且是悄悄的到來,沒有慶祝活動,雖然台灣2/28是有放假的啦,常被人遺忘。
什麼情況會造成閏年蟲?
先前有說到,西元年轉民國年,最直覺簡單的方式,就是西元年減1911,例如:
string salesDate = String.Format(“{0}/{1}/{2}”, DateTime.Now.Year -1911, DateTime.Now.Month, DateTime.Now.Day);
某時候寫程式寫到眼花頭腦不清時,可能會突然靈光一現,為什麼要寫的這麼麻煩,這樣不是更簡潔有力:
string salesDate = DateTime.Now.addYears(-1911).ToString(“yyy/MM/dd”);
正當沾沾自喜時,殊不知已經埋下了一顆未爆彈,第一是閏年的2/29,得到的日期會是2/28,第二是使用DateTime.Now.addYears(-1911)得出的日期再做其他運用,例如取得星期幾、當月第幾週…,都已不準確,因為日期基準已不一樣。
良心的建議,有新系統功能上線前,一定要使用閏年的2/29日期通過測試,確保日期處理無誤。
5. 民國年轉換
使用DotNet TaiwanCalendar類別轉換民國年,只要簡單的將西元年日期做為參數傳入,即可取得民國年的相關數值,例如,年/月/日…,如下:
System.Globalization.TaiwanCalendar tc = new System.Globalization.TaiwanCalendar();
DateTime d = DateTime.Now;
string salesDate = String.Format(“民國{0}年{1}月{2}日”, tc.GetYear(d), tc.GetMonth(d), tc.GetDayOfMonth(d));
可惜的是,ToString()沒有支援Format參數指定輸出格式,不然就更加方便了,省掉自行組字串的步驟。另外要特別注意的是,指定小於西元1912/01/01的日期,會拋出超出日期範圍的例外,因為年份沒有負數的表示法。
如果不想用上述的方式,在每個輸出的地方都寫日期轉換的程式碼,有沒有更簡單的方式?
有的,可以在程式開始執行時,指定執行序的文化與曆法:
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-TW");
Thread.CurrentThread.CurrentCulture.DateTimeFormat.Calendar = new TaiwanCalendar();
當使用DateTime.Now.ToString()時,得到的就是民國年日期,而且是整個系統範圍皆適用。
若需要用到台灣陰陽曆(農民曆)處理,也可使用TaiwanLunisolarCalendar類別來做轉換,使用方式相同。
6. 參考來源
顯示民國年與閏年蟲
http://blog.darkthread.net/post-2012-03-01-leap-year-and-taiwancalendar.aspx
一個步驟,站台全改成民國年