解析自定义日期格式(c#)

解析自定义日期格式(c#),c#,parsing,datetime,C#,Parsing,Datetime,我使用的api为我提供了一个日期。此日期的类型为string,格式如下: 2009年11月16日星期一19:15:09+0000 提供此值时,DateTime.TryParse()失败。有人能给我指出正确的方向吗?尝试传递一个合适的格式字符串。TryParse方法之一接受一个IFormatProvider,它也可以作为DateTimeFormatInfo类提供。以下链接包含所有必要的详细信息: 你的几乎是:ddd,MMM dd yyyy HH':'mm':'ss zzz yyy 唯一的问题是时

我使用的api为我提供了一个日期。此日期的类型为
string
,格式如下:

2009年11月16日星期一19:15:09+0000


提供此值时,
DateTime.TryParse()
失败。有人能给我指出正确的方向吗?

尝试传递一个合适的格式字符串。

TryParse方法之一接受一个IFormatProvider,它也可以作为DateTimeFormatInfo类提供。以下链接包含所有必要的详细信息:

你的几乎是:ddd,MMM dd yyyy HH':'mm':'ss zzz yyy


唯一的问题是时区偏移,zzz在小时和分钟之间包含一个冒号。使用zz'00'可能会侥幸逃脱,尽管这是一种欺骗。

因为DateTime.TryParse(String,DateTime)方法尝试使用当前区域性的格式规则解析日期和时间的字符串表示形式,尝试跨不同区域性解析特定字符串可能会失败或返回不同的结果。如果要跨不同的语言环境分析特定的日期和时间格式,请使用该方法或该方法的某个重载,并提供格式说明符。

使用
DateTimeOffset
类来处理偏移量

[TestMethod]
public void test()
{
  string s = "Mon Nov 16 19:15:09 +0000 2009";

  var result = DateTimeOffset.ParseExact(
    s, 
    "ddd MMM dd HH:mm:ss zzz yyyy", 
    System.Globalization.CultureInfo.InvariantCulture);

  Assert.AreEqual(16, result.Day);
  Assert.AreEqual(11, result.Month);
  Assert.AreEqual(2009, result.Year);
  Assert.AreEqual(19, result.Hour);
  Assert.AreEqual(15, result.Minute);
  Assert.AreEqual(9, result.Second);
  Assert.AreEqual(0, result.Offset.Hours);    
}
更改字符串中的偏移量-例如“0600”,然后将偏移量断言更改为匹配,它将起作用

如果必须的话,您可以将其转换为
日期时间
,但会丢失偏移量信息;因此,您必须决定是将其保留为原始本地时间(
19:15:09
),还是将其转换为某个标准时间(例如,如果偏移量为
+06:00
,则转换为
13:19:05 UTC

如果您需要将其转换为您自己的本地时间,这会很有趣,因为这将取决于2009年当年的DST规则,这可能会引起真正的头痛

所以,如果你打算
DateTime
,我建议你转换成世界时,然后再从那里开始。将此添加到测试中:

Console.WriteLine(result);
//little bit long winded - but you need the 'Universal' Kind for reliability
Console.WriteLine(
  DateTime.SpecifyKind(
    new DateTime(result.ToUniversalTime().Ticks), 
    DateTimeKind.Utc)
);    
这将产生:

11/16/2009 19:15:09+06:00

11/16/2009 13:15:09


如果您得到保证,字符串可能会有重复。您可以将其格式化为可接受的字符串,并将其解析为DateTime。请参阅接受字符串的备注。很好,从未想过您可以反向使用DateTime格式。@Ingó:没错,这一细节的痛苦已经从以前的项目中铭刻在我的脑海中。日期和时间太麻烦了!请注意,有一个很好的名为NodaTime的库,它可以使时区的复杂性变得明确(从而更容易得到正确的结果):