Search code examples
c#datetimeiso

Getting C# to correctly set the Kind property for a parsed ISO 8601 string


I'm struggling to understand why parsing a ISO 8601 formatted string that is parsed by DateTime's Parse method doesn't set the Kind property of the new DateTime object correctly. I've reviewed the post How to create a .NET DateTime from ISO 8601 format and in combination with the ISO documentation it appears that the Parse method should be able to set the Kind value however it's not.

Example:

Console.Write(System.DateTime.Parse("2018-11-17T01:00:00").Kind);

Returns: Unspecified

However according to the ISO standard that is a valid format that indicates the value is a local time.

Time Zone Section

Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC. If no UTC relation information is given with a time representation, the time is assumed to be in local time.

Coordinated Universal Time (UTC)

If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset

Even stranger is that adding a Z to the string sets the Kind property to Local.

In order to get the Kind value set correctly for a UTC string a DateTimeStyle of RoundtripKind is required in the Parse method. However if the Z is removed from the string Kind is set to Unspecified again.

Is this a problem with the DateTime class?

Did Microsoft not follow the ISO standard?

Or am I not understanding the ISO standard?


Solution

  • Don't use DateTime to parse the string, but use DateTimeOffset. You can then use the LocalDateTime or UtcDateTime property of the generated DateTimeOffset to explicitly get the time represented by the string in local time or UTC time. Or you can use the Offset property to check whether the string did originally contain a timezone offset or not.