如何将以下字符串解析为DateTime?

3

我从一些 JSON API 返回的数据中看到了一个非常奇怪的日期格式,这是我从未见过的。

"Tue Aug 04 2015 00:17:38 GMT+0000 (UTC)"

使用以下方法解析时,会生成以下错误:

System.FormatException: 字符串未被识别为有效的 DateTime。

可以理解这个错误。

DateTime.Parse(x.process_date.Value)

有没有遇到过复杂的日期格式,知道如何解析的人?


假设它总是相同的格式,那么在解析之前将字符串更改为不同的格式怎么样? - Alkasai
我的意思是,当然这不是不可能的,但那不是非常干净的方法。我相信在.NET中有一种将这种类型的东西转换的方法。 - Louie Bacaj
1个回答

7
您可以使用DateTime.ParseExact方法(或DateTime.TryParseExact,以便清晰地处理解析失败),来完成此操作。这些方法允许您显式指定格式字符串。
类似以下代码可能有效:
var dateString = "Tue Aug 04 2015 00:17:38 GMT+0000 (UTC)";
var format = "ddd MMM dd yyyy HH:mm:ss GMT+0000 (UTC)";

var parsed = DateTime.ParseExact(
    dateString, 
    format, 
    System.Globalization.CultureInfo.InvariantCulture);

或者,使用TryParseExact
DateTime parsed;
if (DateTime.TryParseExact(
   dateString, 
   format, 
   System.Globalization.CultureInfo.InvariantCulture, 
   DateTimeStyles.None, 
   out parsed) 
{
   // parsing was successful
}
else
{
   // parsing failed
}

以下是使用的格式字符串的详细说明:
- `ddd` - 缩写的星期几名称。 - `MMM` - 缩写的月份名称。 - `dd` - 日期,从 01 到 31 号。 - `yyyy` - 四位数的年份。 - `HH:mm:ss` - 小时,使用24小时制,范围从00到23;分钟,从00到59;秒钟,从0到59(由“:”字符分隔)。 - `GMT+0000 (UTC)` - 固定文本,格式字符串假定始终存在。这相当脆弱,如果API返回不同的文本,可能会导致解析失败。考虑截断此文本,或使用提供有关时区的良好支持的NodaTime
你可能需要稍微调整此格式字符串以适用于你的用途-例如,从你的问题中并不清楚你是否使用12小时制还是24小时制。
有关如何构建格式字符串的更多信息,请参阅MSDN上的Custom Date and Time Format Strings
或者,您可以放弃使用System.DateTime而选择NodaTime。我对NodaTime的了解较少,但在StackOverflow上这里和NodaTime的网站上都有很好的文档。

1
还要注意,如果最后一位发生变化,您可能需要考虑使用Kzzz修饰符,或者简单地剪切一些文本,即剪切(UTC)并解析GMT+0000。在剪切时要小心不要丢失信息,但我猜(UTC)是多余和冗余的,如果您尊重GMT+0000部分的话。 - holroy
@holroy,你可以硬编码它来查找TueAug2015以及GMT+0000,但这似乎不是一个好主意 :) - Rawling
@Rawling,如果您查看答案和我的评论,您会注意到我只是在提到最后一部分。您所提到的三个元素已经是动态的了,而Donut给出的日期格式字符串中的后半部分GMT+0000(UTC)是硬编码的。OP需要查看他的数据集以查看它们是否在更改,然后决定如何处理这后半部分。如果它们正在更改,Donut的答案将抛出异常(我相当确定他知道这一点)。 - holroy
@holroy 是的,我同意你的看法 :) 如果你要硬编码最后一部分,那么它可能不会比硬编码其他部分更好。 - Rawling
1
顺便提一下,我已经更新了我的答案,以引起注意,格式字符串的最后一部分非常脆弱。 - Donut
这就是为什么我喜欢Stack Overflow... @Donut你的答案非常好而且简洁,谢谢! - Louie Bacaj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接