TIPS-.NET DateTime Formating

在VB/VBScript時代,講到日期時間輸出的格式化,大家都知道要用Format(for VB)或FormatDateTime(fro VBScript)。到了.NET時代,有些VB.NET開發者會繼續沿用Format函數。事實上,DateTime Class本身就提供輸出格式化的支援,不用另外呼叫函數處理,而且對C#或VB.NET都通用。

以將日期時間轉成字串為例,DateTime.Now.ToString()大家都會,但有個缺點。未指定任何參數的ToString(),輸出的日期時間格式將會依當時Windows的國別設定而定! 這種因地制宜的做法可以讓Windows Form的User倍感親切,也可算優點,但日期格式的不一致,常會因顯示長度不一造成版面配置的困擾,也是資料庫日期格式轉換出鎚的重要來源。所以我比較習慣應用系統內部使用統一的格式,不要受OS層次響。如果User要做到個人化,再由統一格式轉換過去。我最慣用的格式是"2007/04/30 21:30:00",沒有千禧問題,字串長度永遠固定,24小時制則不必在AM/PM vs 上午/下午間掙札,用來最順手。

不過這個格式並不在.NET預設的標準日期時間格式之列,要產生這個格式,需要自己用yyyy, mm, dd去定義。.NET所提供的客製化日期時間格式字串十分完整,所以用DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")就可以產生我們要的結果,連string.Format函數都用不到。

除了由DateTime -> String的轉換,若要把奇奇怪怪的日期時間字串換回DateTime,.NET也提供了同樣強大的客製彈性! 簡單來說,你可以怎麼把DateTime轉成String,就可以再怎麼把String轉成DateTime,只要提供同樣的日期時間格式字串就得了。例如:
string s="04/30, 2007 @ 09:30"; //某個變態想出來的怪格式
DateTime d=DateTime.ParseExact(s, "MM/dd, yyyy @ HH:mm", null); //照樣解得回來

很酷吧!

最後補充一點,DateTime.ParseExact的第三個參數是IFormatProvider,在以上的例子中用不到,傳null就可以了。但如果你有用到AM/PM(中文是上午、下午)、星期、月份全名... 等等各國表示不同的資料,IFormatProvider就會有影響。

例如: 在中文OS下
DateTime.ParseExact("09:20:00 AM","HH:mm:ss tt", null) 會產生 String was not recognized as a valid DateTime.的訊息。

以上的問題出在中文OS的國別設定中預設用中文表示上下午,導致ParseExact看不懂AM/PM。因此我們得改在IFormatProvider傳入使用AM/PM表示上下午的CultureInfo,en-US當然可以,不過我倒較常用InvariantCulture。改寫成以下方式就OK囉!
DateTime.ParseExact("09:20:00 AM","HH:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture)

Published 30 April 2007 04:08 PM 由 Jeffrey
Filed under: ,


意見

# miniMouse said on 26 July, 2007 01:59 AM

受用無窮,

感謝分享此解法!

# poormusic said on 01 September, 2007 08:57 AM

謝謝你~ ^^

困擾了好久  原來有這個方法

# Soong said on 21 January, 2008 06:53 AM

一直在迷茫。哈哈谢谢。简单方便

# LTH said on 15 May, 2008 08:59 PM

Great!

# cloudolphin said on 10 June, 2008 11:53 AM

感謝 , 不過最近遇到一個更昏的問題

如果上午12:59:xx分用addminutes(1)...會得到上午01:00:xx

這種方式如果要讓他可以自動變成13:00:xx...

不知道有沒有內建功能可以處理呢?...謝謝

# Jeffrey said on 10 June, 2008 10:44 PM

to cloudolphin, ToString("HH:mm:ss"), 兩個大寫H就代表用24小時制,如下例:

       DateTime d = DateTime.ParseExact("12:59:00", "HH:mm:ss", null);

       Console.Write(d.AddMinutes(1).ToString("HH:mm:ss"));

# cloudolphin said on 14 June, 2008 05:26 AM

to Jeffrey

非常感謝^^

原來當初我時間在parse的時候沒有指定24小時制

所以後來再AddMinutes(1)輸出24小時就變成我原本那樣

-__________-

# kennyshu said on 14 October, 2008 09:27 AM

Is there any simple/easy way to get the total hours of a specific month?

# kennyshu said on 14 October, 2008 10:36 AM

I have got the anwser of getting the total hours of the month.  Here is my draft code:

DateTime dtFirstDayOfTheMonth = new DateTime(dt.Year, dt.Month, 1);

DateTime dtLastDayOfTheMonth = new DateTime(dt.Year, dt.Month + 1, 1).AddDays(-1);

TimeSpan tsDays = dtLastDayOfTheMonth - dtFirstDayOfTheMonth;

return (tsDays.Days + 1) * 24;

# cola said on 04 November, 2008 10:15 PM

寫的真好, 我全篇都有看懂

好感動Q_Q

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 

請輸入以上的數字:

搜尋

Go

<April 2007>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345
 
RSS
【工商服務】
最新回應


BlogLook Score and Rank

Syndication