在台灣使用 .NET Framework C# 的開發人員對於這樣的轉換都應該內化為基本操作知識,也就是當有西元年轉為民國年的需求時,都要能夠馬上使用正確的方式來取得正確的資料內容,而並不是直接使用減去 1911 的方式來結案。
為什麼呢?
你使用任何一個閏年(台灣每次總統大選年、夏季奧運舉辦年、美國總統就職的那一年)去取得 2 月 29 日,然後直接用減去 1911 的方式來看結果,我想大部分的人就會知道答案了,如果你還是不懂,那就繼續看下去。
以下是使用 LINQPad 來做示範(或是你也可以使用 CShell,或是也可以使用線上的 .NET Fiddle 來操作)
建立一個 2012.02.29 的日期,然後直接使用減去 1911 的方式來取得民國年,下圖的執行結果裡原本應該是民國 101 年 2 月 29 日卻變成了 28 日,這就是為什麼不要用西元年減去 1911 的方式來取得民國年的原因。
或許有人會說也才這麼一天會出問題,以特例的方式做處理不就好了…
有以上想法的朋友,如果你才接觸程式開發沒多久的話,那……還有救,觀念趕快導正過來就好,如果你已經是資深(或是名片上、職稱上號稱的)程式開發人員,我必須語重心長的告訴你「快點 BR 吧」。
如果你覺得只要將月份與日期單獨取出然後將年份單獨減去 1911 的話,這做法也行,只不過這方法治標不治本。
System.Globalization.TaiwanCalendar
應該要怎麼做才能正確的從西元年轉換取得民國年呢?
請使用 TaiwanCalendar 類別
http://msdn.microsoft.com/zh-tw/library/system.globalization.taiwancalendar
所以上面的程式就應該使用 TaiwanCalendar 來處理,如下:
擴充方法
覺得每次要從西元年轉換取得民國年很麻煩的話,那就直接做成擴充方法,這樣就可以地把西元年轉換為民國年,
public static class DateTimeExtensions
{
/// <summary>
/// To the full taiwan date.
/// </summary>
/// <param name="datetime">The datetime.</param>
/// <returns></returns>
public static string ToFullTaiwanDate(this DateTime datetime)
{
TaiwanCalendar taiwanCalendar = new TaiwanCalendar();
return string.Format("民國 {0} 年 {1} 月 {2} 日",
taiwanCalendar.GetYear(datetime),
datetime.Month,
datetime.Day);
}
/// <summary>
/// To the simple taiwan date.
/// </summary>
/// <param name="datetime">The datetime.</param>
/// <returns></returns>
public static string ToSimpleTaiwanDate(this DateTime datetime)
{
TaiwanCalendar taiwanCalendar = new TaiwanCalendar();
return string.Format("{0}/{1}/{2}",
taiwanCalendar.GetYear(datetime),
datetime.Month,
datetime.Day);
}
}
執行結果
.NET Fiddle 線上直接預覽
https://dotnetfiddle.net/TIOFdG
如果你想要在取得民國年格式字串的時候傳入自定義的字串格式,那麼可以參考 demo 的作法:
西元年轉換取得民國年的問題每隔四年就會在 Google 成為熱門搜尋的焦點,這是存在已久而且是老掉牙的題目了,除了台灣之外,還有許多國家也是有不同的曆法換算問題,所以都要特別注意。
台灣農民曆
農民曆的作法比較特別,要使用另一個曆法的類別「TaiwanLunisolarCalendar」
MSDN - TaiwanLunisolarCalendar 類別
農民曆的算法相當特殊,農曆不像一般西元年有閏年,但是卻有閏月,例如閏五月、閏八月,還有其他一些特別的地方需要注意,不過會需要處理農曆的機會並不多,但還是要特別注意,以下內容來自於 MSDN 說明,
TaiwanLunisolarCalendar 類別衍生自 EastAsianLunisolarCalendar 類別,表示陰曆。 EastAsianLunisolarCalendar 類別除了陽曆年和陰曆月份之外,也支援 60 年為一週期的農曆年。 此曆法中的每一個陽曆年都會有關聯的農曆年 (六十年為一週期)、天干和地支,而且這些曆法可以在一年的任何月份之後多加閏月。
閏月可能發生在一年當中的任何一個月份之後。 例如,EastAsianLunisolarCalendar.GetMonth(DateTime) 方法傳回介於 1 與 13 之間的數字,指出與指定日期關聯的月份。 如果一年當中的第八個月到第九個月之間有閏月,GetMonth 方法會傳回 8,代表第八個月,傳回 9 代表閏八月,然後傳回 10 代表第九個月。
目前,CultureInfo 類別 (Class) 支援的任何文化特性 (Culture) 都未使用 TaiwanLunisolarCalendar。 因此,這個類別只可以用來計算台灣陰陽曆的日期。
每一個 CultureInfo 物件都支援一套曆法。 Calendar 屬性傳回預設文化特性 (Culture) 的曆法,而 OptionalCalendars 屬性則傳回陣列,其包含文化特性所支援的所有曆法。 若要變更 CultureInfo 所使用的日曆,應用程式就必須將 CultureInfo.DateTimeFormat 的 Calendar 屬性設定為新的 Calendar。
有關農民曆的處理,可以參考以下連結內的作法,
TaiwanLunisolarCalendar 拿農曆日期的方法(包含生肖天干地支顯示) - Python_NoteBook
延伸閱讀:
[C#] DateTime輸出民國年 - 愛流浪的小風- 點部落
相關連結
[C#][VB.NET]西元轉民國 - 小歐ou | 菜鳥自救會- 點部落
以上
沒有留言:
張貼留言