163

我找到了如何将 DateTime 转换为ISO 8601格式,但没有关于如何在 C# 中进行相反的操作。

我有2010-08-20T15:00:00Z,我想把它变成一个DateTime对象。

我可以自己分离字符串的各个部分,但对于已经成为国际标准的东西来说,这似乎需要做很多工作。

4

7 回答 7

177

此解决方案利用DateTimeStyles枚举,它也适用于 Z。

DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);

这完美地打印了解决方案。

于 2010-08-24T12:02:56.387 回答
41

尽管 MSDN 说“s”和“o”格式反映了标准,但它们似乎只能解析它的有限子集。如果字符串包含时区规范,尤其是它是一个问题。(对于基本的 ISO8601 格式或降低精度的格式都不是这样——但这不完全是你的情况。)这就是为什么我在解析 ISO8601 时使用自定义格式字符串的原因。目前我首选的片段是:

static readonly string[] formats = { 
    // Basic formats
    "yyyyMMddTHHmmsszzz",
    "yyyyMMddTHHmmsszz",
    "yyyyMMddTHHmmssZ",
    // Extended formats
    "yyyy-MM-ddTHH:mm:sszzz",
    "yyyy-MM-ddTHH:mm:sszz",
    "yyyy-MM-ddTHH:mm:ssZ",
    // All of the above with reduced accuracy
    "yyyyMMddTHHmmzzz",
    "yyyyMMddTHHmmzz",
    "yyyyMMddTHHmmZ",
    "yyyy-MM-ddTHH:mmzzz",
    "yyyy-MM-ddTHH:mmzz",
    "yyyy-MM-ddTHH:mmZ",
    // Accuracy reduced to hours
    "yyyyMMddTHHzzz",
    "yyyyMMddTHHzz",
    "yyyyMMddTHHZ",
    "yyyy-MM-ddTHHzzz",
    "yyyy-MM-ddTHHzz",
    "yyyy-MM-ddTHHZ"
    };

public static DateTime ParseISO8601String ( string str )
{
    return DateTime.ParseExact ( str, formats, 
        CultureInfo.InvariantCulture, DateTimeStyles.None );
}

如果您不介意解析无 TZ 字符串(我愿意),您可以添加一个“s”行来大大扩展涵盖的格式更改的数量。

于 2013-07-19T17:46:11.670 回答
25
using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);
于 2010-08-24T12:08:31.017 回答
21

这是一个更适合我的(LINQPad版本):

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00Z",
    @"yyyy-MM-dd\THH:mm:ss\Z",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, 
    out d);
d.ToString()

生产

true
8/20/2010 8:00:00 AM
于 2011-05-13T16:36:49.013 回答
9

完全匹配 ISO 字符串的格式似乎很重要TryParseExact。我猜Exact就是Exact,这个答案对大多数人来说都是显而易见的,但无论如何......

就我而言,Reb.Cabin 的回答不起作用,因为我的输入与下面的“值”略有不同。

价值:2012-08-10T14:00:00.000Z

毫秒内有一些额外的 000,可能还有更多。

但是,如果我添加一些.fff如下所示的格式,一切都很好。

格式化字符串:@"yyyy-MM-dd\THH:mm:ss.fff\Z"

在 VS2010 立即窗口中:

DateTime.TryParseExact(value,@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal, out d);

真的

DateTimeStyles.AssumeLocal根据您的时间所在的区域,您可能还必须使用...

于 2012-08-14T07:15:27.847 回答
5

这在 LINQPad4 中运行良好:

Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00Z"));
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00"));
Console.WriteLine(DateTime.Parse("2010-08-20 15:00:00"));
于 2012-12-18T01:43:57.077 回答
-2

DateTime.ParseExact(...)允许您告诉解析器每个字符代表什么。

于 2010-08-24T12:00:33.233 回答