我已经找到了如何将DateTime转换为ISO 8601格式,但是在C#中如何进行相反操作却一无所获。
我有2010-08-20T15:00:00Z
,我想将其变成一个DateTime
对象。
我可以自己将字符串的各个部分分开,但是对于已经是国际标准的东西来说,这似乎需要大量工作。
我已经找到了如何将DateTime转换为ISO 8601格式,但是在C#中如何进行相反操作却一无所获。
我有2010-08-20T15:00:00Z
,我想将其变成一个DateTime
对象。
我可以自己将字符串的各个部分分开,但是对于已经是国际标准的东西来说,这似乎需要大量工作。
Answers:
该解决方案利用了DateTimeStyles枚举,并且还与Z一起使用。
DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
这样可以完美打印解决方案。
DateTime d2= DateTime.Parse("2010-08-20T15:00:00Z", null, DateTimeStyles.RoundtripKind);
似乎效果很好。
DateTimeStyles.RoundtripKind?
MSDN描述进行详细说明的人都是空白。
2018-06-19T14:56:14.123Z
被解析为本地时间,而不是UTC。我使用CultureInfo.InvariantCulture
而不是null。
DateTimeStyles.RoundTripKind
,请参见stackoverflow.com/q/39572395/2014893
尽管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”行以大大扩展涵盖格式更改的次数。
"yyyyMMdd"
的在formats
阵列的准确性降低到天,因为这是有时当一个RFC 5545 RRULE将依靠DTSTART提供时间的情况下。
K
使您可以将不同的时区处理放在一起。我在stackoverflow.com/a/31246449/400547上有一个更广泛的变体,但是它是否太宽泛(接受有效的ISO 8601但未在更常见的配置文件中使用的东西),但确实显示了如何K
通过第三。
using System.Globalization;
DateTime d;
DateTime.TryParseExact(
"2010-08-20T15:00:00",
"s",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out d);
这是一个对我更好的软件(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
完全匹配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
,这取决于您的时间在哪个区域。
AssumeUniversal
为AdjustToUniversal
。
在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"));