如何从ISO 8601格式创建.NET DateTime

Rip*_*ter 115 .net c# datetime iso8601 datetime-parsing

我已经找到了如何将DateTime转换为ISO 8601格式,但没有提到如何在C#中进行反向操作.

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

我可以自己分离字符串的各个部分,但对于已经是国际标准的东西来说,这似乎很多.

Mam*_*a D 131

此解决方案使用DateTimeStyles枚举,它也适用于Z.

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

这完全打印出解决方案.

  • 似乎这个问题被编辑以反映更好的答案,但由于@MamtaD覆盖了原始答案,评论变得非常误导.一开始我不确定答案是否正确,因为顶部的评论,但后来我意识到错误的答案后来被正确的答案取代 (8认同)
  • 有人想详细说明这个`DateTimeStyles.RoundtripKind?`MSDN描述是空白的. (4认同)
  • 小数位数对我不起作用。`2018-06-19T14:56:14.123Z`被解析为本地时间,而不是UTC。我使用`CultureInfo.InvariantCulture`而不是null。 (4认同)
  • 编辑的`DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z",null,DateTimeStyles.RoundtripKind)的解决方案;`似乎很好用. (3认同)

Ale*_*kov 28

虽然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 );
}
Run Code Online (Sandbox Code Playgroud)

如果您不介意解析TZ-less字符串(我这样做),您可以添加"s"行以大大扩展所涵盖的格式更改的数量.

  • 我会在`formats`数组中添加``yyyyMMdd``,以便将精度降低到几天,因为有时RFC 5545 RRULE将依赖DTSTART来提供时间. (2认同)

aba*_*hev 21

using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);
Run Code Online (Sandbox Code Playgroud)

  • Z实际上代表祖鲁时间或UTC.http://en.wikipedia.org/wiki/ISO_8601#UTC (29认同)

Reb*_*bin 17

这是一个更适合我的(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()
Run Code Online (Sandbox Code Playgroud)

产生

true
8/20/2010 8:00:00 AM
Run Code Online (Sandbox Code Playgroud)


Zar*_*dan 12

这在 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"));
Run Code Online (Sandbox Code Playgroud)


Rob*_*ode 5

完全匹配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);
Run Code Online (Sandbox Code Playgroud)

真正

您可能还需要使用DateTimeStyles.AssumeLocal,这取决于您的时间在哪个区域。