【问题标题】:How do I convert an ISO8601 TimeSpan to a C# TimeSpan?如何将 ISO8601 TimeSpan 转换为 C# TimeSpan?
【发布时间】:2012-09-10 01:52:47
【问题描述】:

当我尝试执行以下操作(例如)时,我收到了System.FormatException

TimeSpan ts = XmlConvert.ToTimeSpan("P72H");

我已经调查了ISO8601 Standard,它似乎是正确的,但无论我做什么,我都无法让它在不抛出异常的情况下解析小时数。

谢谢!

编辑:

异常详情:

System.FormatException was unhandled by user code
HResult=-2146233033
Message=The string 'P72H' is not a valid TimeSpan value.
Source=System.Xml

【问题讨论】:

  • @Oded 这不是关于 .NET 字符串格式的问题。
  • @Oded 明确一点,我没有从类型不匹配中得到异常,我是从 XmlConvert.ToTimeSpan 方法中得到的。这是一个关于将 ISO8601 标准持续时间字符串转换为 C# 可用格式的问题。
  • @Magnus P72H 表示持续时间为 72 小时

标签: c# xml parsing datetime xml-parsing


【解决方案1】:

您需要在字符串中添加时间分隔符。试试这个:

TimeSpan ts = XmlConvert.ToTimeSpan("PT72H");

查看持续时间规范 - http://www.w3.org/TR/xmlschema-2/#duration

3.2.6.1 词法表示
持续时间的词法表示是 [ISO 8601] 扩展格式 PnYn MnDTnH nMnS,其中 nY 表示年数,nM 表示月数,nD 表示天数,'T' 是日期/时间分隔符,nH 表示数字小时数,nM 分钟数和 nS 秒数。秒数可以包含任意精度的十进制数字。

基于 cmets 编辑/更新

由于W 是 ISO 8601 标准的一部分,为什么字符串 P2M2W5D 不会被视为有效的 TimeSpan 存在一些问题,所以我想添加此更新,以便如果有人遇到它他们不必通读 cmets 即可获得答案。对于有问题的原始字符串P72HP2M2W5D,问题在于该字符串必须符合W3C XML Schema(请参阅XmlConvert.ToTimeSpan 的文档)。当我们查看 W3C XML Schema(上面的链接)时,它引用了 ISO 8601 标准,特别是第 5.5.3.2.1 节,它给出了W 在 XML Schema 中不是有效字符的原因:

由于周没有明确的结转点(52 或 53),因此周应 不能在这些应用程序中使用

【讨论】:

  • @Pheonixblade9 - 因为D是天,所以在指示时间的时候需要加上时间分隔符T
  • 来自 ISO8601 Wikipedia URL:“为了解决歧义,“P1M”是一个月的持续时间,“PT1M”是一分钟的持续时间(注意时间指示符 T,它在时间之前价值)。” P4D 没有歧义,它不包含任何时间分量,但“T”对于具有时间分量的值是必需的。
  • 因为“W”不是 ISO8601 架构的一部分。 P2M5DP2M19D 一样有效,我假设这是您在字符串中使用 2W 的意图。
  • @AlexandruMărculescu - 抱歉,当我回复您的评论并忘记标记您时,我已经筋疲力尽了。您的问题是 W 不是 ISO8601 架构的一部分。如果您的意思是“周”,只需将 2W 转换为 14D 就可以了。
  • @CristiDiaconescu - 抱歉,我的评论不清楚(请注意关于困倦程度的后续评论)实际问题是字符串必须符合 W3C XML Schema(请参阅MSDN XmlConvert.ToTimeSpan)然后答案中的链接。)您会发现 W3C XML Schema 然后引用回 ISO 标准,特别是第 5.5.3.2.1 节,其中指出“由于周没有定义的结转点(52 或 53),周应该不能在这些应用程序中使用”
【解决方案2】:

您一定遗漏了标准中的某些内容。以下:

System.Xml.XmlConvert.ToString(TimeSpan.FromHours(12))

给我字符串PT12H。所以似乎时间部分需要以T 为前缀。以下解析正确:

System.Xml.XmlConvert.ToTimeSpan("PT25H")

(到一个TimeSpan,字符串化为1.01:00:00。)

【讨论】:

    【解决方案3】:

    System.Xml.XmlConvert.ToTimeSpan("PnYnMnDTnHnMnS") 请使用以下格式。

    P - 指示符必须放在日期格式之前。

    nY - 年数,例如:2Y
    nM - 月数 例如:4M
    nD - 天数 例如:6D

    T - 必须放在时间格式之前的指示符

    nH - 小时数 例如:8H
    nM - 分钟数 例如:12M
    nS - 秒数 例如:14S

        System.Xml.XmlConvert.ToTimeSpan("P2Y4M6DT8H12M14S")
    

    这里,与月和分混淆的部分用相同的字母表示,但指示符的用法使它们分开以便于理解。

    【讨论】:

      猜你喜欢
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多