分析 .NET 中的日期和时间字符串

分析字符串以将其转换为 DateTime 对象需要指定日期和时间如何表示为文本的信息。 不同的文化对日、月和年的使用有不同的顺序。 有些时间表示形式使用 24 小时制,另一些表示形式则指定“AM”和“PM”。某些应用程序只需要日期。 其他人只需要时间。 还有一些人员需要同时指定日期和时间。 将字符串转换为 DateTime 对象的方法使你能够提供有关所需格式的详细信息以及应用程序需要的日期和时间的元素。 有三个子任务可以正确地将文本转换为 DateTime

  1. 必须指定表示日期和时间的文本的预期格式。
  2. 可以为日期时间的格式指定文化。
  3. 可以指定在日期和时间中设置文本表示形式的缺失组件的方式。

ParseTryParse方法转换日期和时间的许多常见表示形式。 和ParseExactTryParseExact方法转换符合日期和时间格式字符串指定的模式的字符串表示形式。 有关详细信息,请参阅 标准日期和时间格式字符串 以及 自定义日期和时间格式字符串的文章

当前 DateTimeFormatInfo 对象可更好地控制文本应如何解释为日期和时间。 DateTimeFormatInfo描述日期和时间分隔符、月、天和纪元的名称以及“AM”和“PM”指定格式的属性。 CultureInfoCultureInfo.CurrentCulture返回值具有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 早七个小时的时间。 如果省略了时间字符串表示形式中的偏移量,解析将返回一个DateTime对象,其Kind属性设置为DateTimeKind.Unspecified。 如果指定偏移量,则分析将返回一个 DateTime 对象,其 Kind 属性设置为 DateTimeKind.Local. 其值也会调整为计算机的本地时区。 可以通过在解析方法中使用 DateTimeStyles 值来修改此行为。

格式提供程序还用于解释不明确的数值日期。 目前还不清楚字符串“02/03/04”所表示日期的哪些组成部分是月份、日和年。 组件按照格式提供程序中相似日期格式的顺序进行解释。

Parse

下面的示例演示如何使用 DateTime.Parse 方法将 a string 转换为 DateTime. 此示例使用与当前线程相关联的文化信息。 如果输入字符串无法被与当前区域性相关的CultureInfo解析,则会引发FormatException

注释

这些示例在 适用于 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。 它创建一个CultureInfo代表de-DE文化。 该 CultureInfo 对象可确保成功分析此特定字符串。 此过程排除了在 CurrentCultureCurrentThread 中的任何设置。

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 '{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 还使用定义一个或多个自定义日期和时间格式的其他字符串或字符串数组参数。

另请参阅