在 .NET 中剖析日期和時間字串

剖析字串以將之轉換成 DateTime 物件時,會要求您指定如何將日期與時間以文字表示的相關資訊。 不同的文化特性會針對日期、月份與年份使用不同的順序。 某些時間表示法使用 24 小時制,其他則指定 "AM" 和 "PM"。某些應用程式僅需要日期。 其他則僅需要時間。 而有部份則需要同時指定日期與時間。 將字串轉換為 DateTime 物件的方法,可讓您提供所預期格式以及應用程式所需日期與時間元素的相關詳細資訊。 將文字正確轉換為 DateTime 有三項子工作:

  1. 您必須指定表示日期與時間的文字預期格式。
  2. 您可以指定日期時間格式的文化特性。
  3. 您可以指定文字表示法中遺漏的元件在日期與時間中設定的方式。

ParseTryParse 方法會轉換許多常見的日期和時間表示法。 ParseExactTryParseExact 方法會轉換符合日期和時間格式字串所指定模式的字串表示。 如需詳細資訊,請參閱標準日期和時間格式字串以及自訂日期和時間格式字串相關文章。

目前的 DateTimeFormatInfo 物件提供了將文字解譯為日期與時間的更多控制方式。 DateTimeFormatInfo 的屬性描述了日期和時間分隔符號、月、日和紀元的名稱,還有 "AM" 和 "PM" 指定的格式。 CultureInfo.CurrentCulture 所傳回的 CultureInfo 具有代表目前文化特性的 CultureInfo.DateTimeFormat 屬性。 若需要特定文化特性或自訂設定,您可以指定剖析方法的 IFormatProvider 參數。 針對 IFormatProvider 參數,指定代表文化特性的 CultureInfo 物件,或指定 DateTimeFormatInfo 物件。

表示日期或時間的文字可能會遺失一些資訊。 例如,大多數人會假設日期「3 月 12 日」表示目前的年份。 同樣地,「2018 年 3 月」表示 2018 年的 3 月份。 代表時間的文字也經常僅包含小時、分鐘和 AM/PM 指定。 剖析方法會使用合理的預設值,以處理此種遺失資訊:

  • 當只有表示時間時,日期部分會使用目前的日期。
  • 當只有表示日期時,時間部分則為午夜。
  • 當日期中沒有指定年份時,會使用目前的年份。
  • 當沒有指定月份日期時,會使用月份的第一天。

如果字串中有日期,則日期必須包含月份,和日期或年份兩者其中之一。 如果有時間,則時間必須包含小時,和分鐘或 AM/PM 指示項兩者其中之一。

您可以指定 NoCurrentDateDefault 常數來覆寫這些預設值。 當您使用該常數時,任何遺失的年份、月份或日期屬性都會設定為值 1最後一個範例會使用 Parse 來示範此行為。

除了日期和時間元件外,日期和時間的字串表示可以包含表示時間與國際標準時間 (UTC) 差的位移。 例如,字串 "2/14/2007 5:32:00 -7:00" 定義的時間比 UTC 早 7 個小時。 如果時間的字串表示中省略了位移,剖析就會傳回 DateTime 物件及其設為 DateTimeKind.UnspecifiedKind 屬性。 如果指定了時差,剖析會傳回 DateTime 物件,其 Kind 屬性設定為 DateTimeKind.Local。 其值也會調整為您電腦的當地時區。 您可以搭配剖析方法使用 DateTimeStyles 值來修改此行為。

格式提供者也可以用來解譯不明確的數值日期。 "02/03/04" 字串並未明確表示代表月份、日期和年份的日期元件。 元件會根據格式提供者中的相似日期格式順序來解譯。

剖析

下面的範例會示範如何使用 DateTime.Parse 方法將 string 轉換成 DateTime。 本範例會使用與目前執行緒相關聯的文化特性。 如果與目前文化特性相關聯的 CultureInfo 無法剖析輸入字串,則會擲回 FormatException

提示

本文中所有的 C# 範例皆可在您的瀏覽器中執行。 按 [執行] 按鈕以查看輸出。 您也可以編輯它們以進行實驗。

注意

這些範例可在 C#Visual Basic 兩者的 GitHub 文件存放庫中取得。

string dateInput = "Jan 1, 2009";
var parsedDate = DateTime.Parse(dateInput);
Console.WriteLine(parsedDate);
// Displays the following output on a system whose culture is en-US:
//       1/1/2009 00:00:00
Dim MyString As String = "Jan 1, 2009"
Dim MyDateTime As DateTime = DateTime.Parse(MyString)
Console.WriteLine(MyDateTime)
' Displays the following output on a system whose culture is en-US:
'       1/1/2009 00:00:00

您也可以明確地定義剖析字串時所使用的文化特性格式設定慣例。 您將指定由 CultureInfo.DateTimeFormat 屬性傳回的其中一個標準 DateTimeFormatInfo 物件。 下列範例使用格式提供者將德文字串剖析成 DateTime。 它會建立代表 de-DE 文化特性的 CultureInfoCultureInfo 物件可確保成功剖析此特定字串。 這個處理程序會排除 CurrentThreadCurrentCulture 中的任何設定。

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo);
Console.WriteLine(dateTime);
// The example displays the following output:
//       6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo)
Console.WriteLine(MyDateTime)
' The example displays the following output:
'       6/12/2008 00:00:00

不過,您可以使用 Parse 方法的多載來指定自訂格式提供者。 方法 Parse 不支援剖析非標準格式。 若要剖析以非標準格式表示的日期和時間,請改用 ParseExact 方法。

下列範例使用 DateTimeStyles 列舉,以指定不應將目前的日期和時間資訊新增至 DateTime 的未指定欄位中。

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo,
                                DateTimeStyles.NoCurrentDateDefault);
Console.WriteLine(dateTime);
// The example displays the following output if the current culture is en-US:
//      6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo,
                           DateTimeStyles.NoCurrentDateDefault)
Console.WriteLine(MyDateTime)
' The example displays the following output if the current culture is en-US:
'       6/12/2008 00:00:00

ParseExact

DateTime.ParseExact 方法會將符合其中一個指定字串模式的字串轉換為 DateTime 物件。 當不是指定形式之一的字串傳遞至此方法時,就會擲回 FormatException。 您可以指定標準日期和時間格式指定名稱之一,或指定自訂格式指定名稱的組合。 使用自訂格式指定名稱,讓您能夠建構自訂的辨識字串。 如需指定名稱的說明,請參閱標準日期和時間格式字串以及自訂日期和時間格式字串相關文章。

在下列範例中,DateTime.ParseExact 方法收到了要剖析的字串物件,後面依序接著格式指定名稱和 CultureInfo 物件。 此 ParseExact 方法只能剖析遵循 en-US 文化特性中完整日期模式的字串。

var cultureInfo = new CultureInfo("en-US");
string[] dateStrings = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in dateStrings)
{
    try
    {
        var dateTime = DateTime.ParseExact(dateString, "D", cultureInfo);
        Console.WriteLine(dateTime);
    }
    catch (FormatException)
    {
        Console.WriteLine("Unable to parse '{0}'", dateString);
    }
}
// The example displays the following output:
//       Unable to parse ' Friday, April 10, 2009'
//       4/10/2009 00:00:00
Dim MyCultureInfo As New CultureInfo("en-US")
Dim MyString() As String = {" Friday, April 10, 2009", "Friday, April 10, 2009"}
For Each dateString As String In MyString
    Try
        Dim MyDateTime As DateTime = DateTime.ParseExact(dateString, "D",
                                                     MyCultureInfo)
        Console.WriteLine(MyDateTime)
    Catch e As FormatException
        Console.WriteLine("Unable to parse '{0}'", dateString)
    End Try
Next
' The example displays the following output:
'       Unable to parse ' Friday, April 10, 2009'
'       4/10/2009 00:00:00

ParseParseExact 方法的每個多載也都有 IFormatProvider 參數,可提供有關設定字串格式的特定文化特性資訊。 此 IFormatProvider 物件是代表標準文化特性的 CultureInfo 物件,或 CultureInfo.DateTimeFormat 屬性所傳回的 DateTimeFormatInfo 物件。 ParseExact 也會使用可定義一或多個自訂日期和時間格式的額外字串或字串陣列引數。

另請參閱