0

Today an API changed and broke this legacy code with the following error:

[System.FormatException: String was not recognized as a valid DateTime.]

The new date take this form: 2020-01-16T14:29:17.9743131Z0.

public static void Main()
{
    var result = "2020-01-16T14:29:17.9743131Z0";
    Console.WriteLine("dateTime : {0}", result);
    Console.WriteLine("result : {0}", Convert.ToDateTime(result));
}

Try it Online

Neither DateTime.Parse's official documentation nor DateTime.ParseExact's official documentation help me as far as I tried at that point. Lets ask internet.

I searched online and found How to create a .NET DateTime from ISO 8601 format. The first solution with DateTime.Parse and DateTimeStyles.RoundtripKind but it failed with the same error. The second solution use DateTime.ParseExact, custom formats, and DateTimeStyles.None. 18 formats. None works. The third one rely on the flag DateTimeStyles.AssumeUniversal. It didnt work all the same.

I also check another link (Given a DateTime object, how do I get an ISO 8601 date in string format?) without success.

How can I handle this format?

aloisdg
  • 22,270
  • 6
  • 85
  • 105
  • What does the trailing 0 (`Z0`) mean? – Salman A Jan 22 '20 at 11:39
  • *Neither `DateTime.Parse` nor `DateTime.ParseExact` help me as far as I tried.* ... and solution posted by you is ... `DateTime.ParseExact` – Selvin Jan 22 '20 at 12:20
  • @Selvin I updated the question to reflect the problem. I post this as Q&A because I found the solution while searching and I am looking to help others. – aloisdg Jan 22 '20 at 12:44
  • @SalmanA The 'Z' is a delimiter of the UTC spec. I dont know about the '0'. – aloisdg Jan 22 '20 at 13:26

2 Answers2

2

You were close. Searching a bit more would have yield this two links c# convert datetime object to iso 8601 string and How to parse and generate DateTime objects in ISO 8601 format. They dont fix your problem per se, but they give you more information about those pesky decimal in your format: "fff". You can find it under Custom date and time format strings. We want "FFFFFFF" especially to match your input.

screenshot of the doc

Our format could look like this "yyyy-MM-dd'T'HH:mm:ss.fffffff" We can try it online, but *spoiler* it wont work. We are missing "Z0" at the end. Good news, we can ignore them.

enter image description here

Final code:

public static void Main()
{
    var result = "2020-01-16T14:29:17.9743131Z0";
    Console.WriteLine(result);          

    var format = "yyyy-MM-dd'T'HH:mm:ss.fffffffZ0";
    Console.WriteLine(DateTime.ParseExact(result, format, CultureInfo.InvariantCulture).ToString());
}

Try it online

Note that this code will not work if you have less than 7 decimal in your string. At then end, maybe you should rely on @jgauffin solution.

aloisdg
  • 22,270
  • 6
  • 85
  • 105
1

That string follows the standard with the exception of the last 0.

The "Z" stands for Coordinated Universal Time (UTC). There should be no number after it, so you can safely ignore that extra 0.

var dateStr = "2020-01-16T14:29:17.9743131Z0";

var pos = dateStr.IndexOf('Z');
if (pos != -1 && pos < dateStr.Length - 1)
    dateStr = dateStr.Remove(pos + 1);

var date = DateTime.Parse(dateStr);
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • Agreed, the 0 should not be here. I open an issue to remove it. Meanwhile, I use this solution as a fix. Thank you. – aloisdg Jan 22 '20 at 13:35