如何用DateTime.TryParseExact转换"20170721T114700Z"?请修正代码
解析ISO 8601格式时间的问题修复与说明
首先,咱们来拆解你这段代码里的问题,然后给出正确的实现方式:
原代码存在的问题
- 未定义匹配的格式字符串:你用了
DateTimeFormats.IndexDateTimeFormat这个变量,但没有给出它的定义——大概率这个格式字符串和输入的"20170721T114700Z"不匹配,这是解析失败的核心原因; - 错误的格式提供器:第三个参数传
null会使用当前线程的区域文化设置,而这种ISO 8601风格的时间格式是无区域的,必须用CultureInfo.InvariantCulture才能避免因系统区域差异导致解析失败; - 未处理UTC标记
Z:DateTimeStyles.None不会把输入末尾的Z识别为UTC时间标记,解析后的DateTime对象的Kind会是Unspecified,不符合输入的UTC时间原意。
修正后的代码
下面是两种可行的修正方案,都能正确解析目标时间字符串:
方案1:转义字面量字符
using System.Globalization; // 记得引入这个命名空间 DateTime dateTime = DateTime.Now; string rawValue = "20170721T114700Z"; // 格式字符串完全匹配输入:yyyyMMdd对应日期,'T'是字面量分隔符,HHmmss对应时间,'Z'是字面量UTC标记 string format = "yyyyMMdd'T'HHmmss'Z'"; // 使用不变文化,同时指定AdjustToUniversal将Z识别为UTC时间 if (DateTime.TryParseExact(rawValue, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out dateTime)) { // 这里dateTime.Kind会是Utc,值为2017-07-21 11:47:00 UTC // rest of the code... }
方案2:直接识别UTC标记
如果你想让Z被自动识别为UTC标记(而非单纯字面量),可以用不带单引号的格式字符串,同样配合AdjustToUniversal:
using System.Globalization; DateTime dateTime = DateTime.Now; string rawValue = "20170721T114700Z"; // 格式字符串中Z直接作为UTC标记使用 string format = "yyyyMMddTHHmmssZ"; if (DateTime.TryParseExact(rawValue, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out dateTime)) { // 解析结果和方案1一致,dateTime.Kind为Utc // rest of the code... }
关键说明
CultureInfo.InvariantCulture的必要性:这种ISO格式是国际通用的,不受区域文化影响,用不变文化能保证在任何系统环境下都能正确解析;DateTimeStyles.AdjustToUniversal的作用:它会将输入的时间(带有Z标记)转换为UTC时间,并将DateTime.Kind设置为Utc,确保时间的时区信息正确;- 格式字符串的严格匹配:
TryParseExact要求格式字符串和输入字符串的每个字符完全对应,所以必须确保格式里的日期、分隔符、时间、标记都和输入一致。
内容的提问来源于stack exchange,提问作者Sameera
相关产品推荐
相关产品推荐

