C# 如何从ISO 8601格式创建.NET日期时间
我已经找到了如何将DateTime转换成一种格式,但没有找到如何在C#中实现相反的方法 我有C# 如何从ISO 8601格式创建.NET日期时间,c#,.net,datetime,iso8601,datetime-parsing,C#,.net,Datetime,Iso8601,Datetime Parsing,我已经找到了如何将DateTime转换成一种格式,但没有找到如何在C#中实现相反的方法 我有2010-08-20T15:00:00Z,我想把它变成DateTime对象 我可以自己分离字符串的各个部分,但对于已经是国际标准的东西来说,这似乎需要做很多工作。DateTime.ParseExact(…)允许您告诉解析器每个字符代表什么。此解决方案利用枚举,并且它也适用于Z DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System
2010-08-20T15:00:00Z
,我想把它变成DateTime
对象
我可以自己分离字符串的各个部分,但对于已经是国际标准的东西来说,这似乎需要做很多工作。
DateTime.ParseExact(…)
允许您告诉解析器每个字符代表什么。此解决方案利用枚举,并且它也适用于Z
DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
这完美地打印了解决方案 这里有一个更适合我的(版本):
using System.Globalization;
DateTime d;
DateTime.TryParseExact(
"2010-08-20T15:00:00",
"s",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out d);
产生
true
8/20/2010 8:00:00 AM
要使
TryParseExact
正常工作,精确匹配ISO字符串的格式似乎很重要。我想准确就是准确,这个答案对大多数人来说是显而易见的,但无论如何
在我的例子中,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);
真的
您可能必须使用
datetimestyle.AssumeLocal
,这取决于您的时间所在的区域…这在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"));
尽管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”行,以大大扩展覆盖格式更改的数量 @Aidin:2010年8月24日12:00的可能副本:02@Aidin:是的,这是一个副本。唯一不同的是格式。其余的都是一样的。@abatishchev,这就是为什么它不是复制品。“副本”中的答案不处理8601。是的,这不是副本。这个问题特定于解析ISO 8601格式。在LinqPad:(@Reb:“2010-08-20T15:00:00”和“s”,如果末尾没有“Z”,则会生成False和d~~>“1/1/0001 12:00:00 AM:”)在我的所有样本中都会显示Z(碰巧来自不同的GPS单位和GPX文件),在另一个ISO 8601参考中发现“Z”代表时区——就像时区一样。Z实际上代表祖鲁时间或UTC。已编辑的解决方案
DateTime d2=DateTime.Parse(“2010-08-20T15:00:00Z”,null,datetimestyle.RoundtripKind)
似乎工作得很好。任何人想要详细说明此DateTimeStyles.RoundtripKind?
MSDN说明是空白的。似乎编辑此问题是为了反映更好的答案,但由于@MamtaD重写了原始答案,因此评论变得非常误导。一开始,由于上面的注释,我不确定答案是否正确,但后来我意识到不正确的答案被正确的答案替换为正确的答案不适用于分数位数的我<代码>2018-06-19T14:56:14.123Z被解析为本地时间,而不是UTC。我使用CultureInfo.InvariantCulture
而不是null。有关DateTimeStyles.RoundTripKind
的更多信息,请参阅我将在格式
数组中添加“yyyyymmdd”
,以将精度降低到天,当RFC 5545 RRULE依赖DTSTART来提供时间时,有时会出现这种情况。使用K
可以将不同的时区句柄组合在一起。我在上有一个更广泛的变体,但它太广泛了(接受有效的ISO 8601但在更常见的配置文件中未使用的内容),但它确实显示了K
如何将大小减少三分之一。目前,在我的单元测试中使用它来验证我预期的所有日期字符串都是Iso8601格式的。谢谢为什么返回的时间戳不是UTC格式?!由于“AssumeUniversal”的“不变文化”不应该这样做,这在很大程度上违反了最小惊讶原则,因为世界各地的DST差异如此之大,因此如果您开始在具有不同设置的服务器上运行代码,返回您当地的主要时区可能会引入错误!这对我来说很管用,但我还必须将AssumeUniversal
更改为AdjustToUniversal
。
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 );
}