RSS

民國年與西元年之間的轉換與顯示

23 Mar

很幸運我最近剛開始寫到日期字串處理的時候就碰到閏年的問題,因為今年正好是閏年。

當程式裡需要將民國年的字串轉換成DateTime格式的時候,我使用了土法煉鋼的方式,Date.Parse().AddYear(1911),先轉換再加1911年。還好沒幾天馬上碰到101/2/29!當Date.Parse(String)的時候,其實是將字串轉換為西元年,西元101年當然沒有2/29號…因此會出現”字串未被辨認為有效的 DateTime”Exception。而且這麼做在民國99年(含)以前出來的日期也全部錯誤。先將字串的年份加上1911也許是可行的方法,但是會有多餘的型態轉換,而且不夠彈性。

.NET本身就有對應世界各國日曆格式的方式,可以使用Date.Parse(String, IFormatProvider)Date.ToString(IFormatProvider),IFormatProvider參數可以是CultureInfoDateTimeFormatInfo,在其中指定DateTimeFormatInfo.Calendar屬性為TaiwanCalendar,就可以正確的轉換與顯示民國年。

另外需要注意的是,DateTime.Year屬性所傳回的是西曆年份,如果要套用不同的日曆格式,要使用所指定曆法的GetYear方法。在DateTime.Year裡有MSDN的範例說明。

以下是一個簡單的範例,可以比較錯誤與正確的轉換方式和結果:

Dim dtTest As New DataTable
dtTest.Columns.Add("時間字串")
dtTest.Columns.Add("Date.Parse()")
dtTest.Columns.Add("Date.Parse().AddYears(1911)")
dtTest.Columns.Add("西元")
dtTest.Columns.Add("民國")
'欲轉換為DateTime格式的民國年字串
Dim taiwanDates As String() = {"89/9/8", "99/2/4", "100/12/11", "101/1/23", "101/2/28", "101/2/29"}
Dim wrongDate As String
Dim wrongTaiwanDate As String
Dim correctDate As String
Dim correctTaiwanDate As String
'要套用在Parse()和ToString()的日曆格式
Dim taiwanCultureInfo As CultureInfo
taiwanCultureInfo = New CultureInfo("zh-TW")
taiwanCultureInfo.DateTimeFormat.Calendar = New TaiwanCalendar()

For Each theDate As String In taiwanDates
'錯誤的時間值:Date.Parse(theDate)
'Date.Parse()沒有指定所輸入的字串日歷格式
    Try
        wrongTaiwanDate = Date.Parse(theDate).Date.ToString("d")
    Catch ex As Exception
        wrongDate = ex.Message
    End Try

    Try
        wrongDate = Date.Parse(theDate).AddYears(1911).Date.ToString("d")
    Catch ex As Exception
        wrongTaiwanDate = ex.Message
    End Try
'正確的時間值:Date.Parse(theDate, taiwanCultureInfo)
    correctDate = Date.Parse(theDate, taiwanCultureInfo).Date.ToString("d")
'在ToString()中指定輸出的日歷格式
'本範例中日歷格式使用民國日歷
    correctTaiwanDate = Date.Parse(theDate, taiwanCultureInfo).Date.ToString("d", taiwanCultureInfo)

    dtTest.Rows.Add(theDate, _
                    wrongTaiwanDate, _
                    wrongDate, _
                    correctDate, _
                    correctTaiwanDate)
Next
時間字串 Date.Parse() .AddYears(1911) 西元 民國
89/9/8 1989/9/8 3900/9/8 2000/9/8 89/9/8
99/2/4 1999/2/4 3910/2/4 2010/2/4 99/2/4
100/12/11 0100/12/11 2011/12/11 2011/12/11 100/12/11
101/1/23 0101/1/23 2012/1/23 2012/1/23 101/1/23
101/2/28 0101/2/28 2012/2/28 2012/2/28 101/2/28
101/2/29 字串未被辨認為有效的 DateTime。 字串未被辨認為有效的 DateTime。 2012/2/29 101/2/29
Advertisements
 
Leave a comment

Posted by on March 23, 2012 in .NET, VB

 

Tags:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: