How do I convert an ISO8601 TimeSpan to a C# TimeSpan?
Solution 1
You need to add the Time separator to your string. Try this:
TimeSpan ts = XmlConvert.ToTimeSpan("PT72H");
See the duration specification - http://www.w3.org/TR/xmlschema-2/#duration
3.2.6.1 Lexical representation
The lexical representation for duration is the [ISO 8601] extended format PnYn MnDTnH nMnS, where nY represents the number of years, nM the number of months, nD the number of days, 'T' is the date/time separator, nH the number of hours, nM the number of minutes and nS the number of seconds. The number of seconds can include decimal digits to arbitrary precision.
Edit/Update based on comments
As there was some question as to why the string P2M2W5D
would not be considered a valid TimeSpan
since W
is part of the ISO 8601 standard, I wanted to add this update so that if someone runs across that issue they don't have to read through the comments to get the answer. The issue, both for the original string in question P72H
and P2M2W5D
is that the string must conform to the W3C XML Schema (see the documentation for XmlConvert.ToTimeSpan). When we look at the W3C XML Schema (link above), it references back to the ISO 8601 standard, and in particular to section 5.5.3.2.1 which gives the reason why W
is not a valid character in the XML Schema:
Since weeks have no defined carry-over point (52 or 53), weeks should not be used in these applications
Solution 2
You must have missed something in the standard. The following:
System.Xml.XmlConvert.ToString(TimeSpan.FromHours(12))
gives me the string PT12H
. So it seems like the time portion needs to be prefixed with a T
. And the following parses correctly:
System.Xml.XmlConvert.ToTimeSpan("PT25H")
(To a TimeSpan
that stringifies to 1.01:00:00
.)
Solution 3
Please use the following format for System.Xml.XmlConvert.ToTimeSpan("PnYnMnDTnHnMnS")
.
P - The designator must be placed before date format.
nY - Number of years, ex: 2Y
nM - Number of months ex: 4M
nD - Number of Days ex: 6D
T - The designator that must be placed before the time format
nH - Number of Hours ex: 8H
nM - Number of Minutes ex: 12M
nS - Number of seconds ex: 14S
System.Xml.XmlConvert.ToTimeSpan("P2Y4M6DT8H12M14S")
Here, the confusion part with Month and Minutes have the same letter to denote, but the designator usage makes them separate to understand easily.
Comments
-
Codeman about 3 years
I am getting a
System.FormatException
when I try to do the following (as an example):TimeSpan ts = XmlConvert.ToTimeSpan("P72H");
I've investigated the ISO8601 Standard and it seems to be correct, but I cannot get it to parse hours without throwing an exception, no matter what I do.
Thanks!
EDIT:
Exception detail:
System.FormatException was unhandled by user code HResult=-2146233033 Message=The string 'P72H' is not a valid TimeSpan value. Source=System.Xml
-
Codeman over 11 yearsOdd, I don't have to do this for "P4D", but this works! Thanks!
-
pstrjds over 11 years@Pheonixblade9 - That is because
D
is days, you need to add the time seperatorT
when you are indicating time. -
Ryan over 11 yearsFrom the ISO8601 Wikipedia URL: "To resolve ambiguity, "P1M" is a one-month duration and "PT1M" is a one-minute duration (note the time designator, T, that precedes the time value)." There is no ambiguity with P4D and it doesn't include any time components, but the "T" is necessary for values with time components.
-
Alexandru Marculescu over 8 yearsDoes anyone have any clue as to why would I get a "The string 'P2M2W5D' is not a valid TimeSpan value."? It seems like a valid input, with no ambiguity...
-
pstrjds over 8 yearsBecause 'W' is not part of the ISO8601 schema.
P2M5D
is valid as well asP2M19D
which I am assuming is what you intend with the2W
in your string. -
pstrjds over 8 years@AlexandruMărculescu - Sorry, I was pretty exhausted when I responded to your comment and forgot to tag you. Your issue is that
W
is not part of the ISO8601 schema. If you meant 'Weeks', just convert the2W
to14D
and it should work just fine. -
Cristian Diaconescu almost 7 years@pstrjds Can you share a link for 'W' not being part of the standard? Wikipedia says it is: en.wikipedia.org/wiki/ISO_8601#Time_intervals
-
pstrjds almost 7 years@CristiDiaconescu - Sorry, I was not clear in my comment (note followup comment about sleepiness level)The actual issue is that the string must conform to the W3C XML Schema (see MSDN XmlConvert.ToTimeSpan) and then link in answer.) You will find the W3C XML Schema then references back to the ISO standard, and in particular to section 5.5.3.2.1 which states "Since weeks have no defined carry-over point (52 or 53), weeks should not be used in these applications"
-
Jonathan about 5 yearsSame code in PowerShell:
[System.Xml.XmlConvert]::ToTimeSpan("PT72H") | ft