Question

I'm trying to parse incoming date from data source (which cannot be changed). It gives me time in ISO 8601 format example: 2007-04-05T24:00.

How ever in .Net it fails to parse this as valid time.

The wikipedia states that it should be valid format. Wikipedia ISO 8601

Example from https://stackoverflow.com/a/3556188/645410

How can I do this without a nasty string check hack?

Example (fiddle: http://dotnetfiddle.net/oB7EZx):

var strDate = "2007-04-05T24:00";       
Console.WriteLine(DateTime.Parse(strDate, null, DateTimeStyles.RoundtripKind));

Throws:

The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.

Was it helpful?

Solution

Yes, .NET doesn't support this as far as I'm aware.

My Noda Time project does, but only partially: it can parse the value, but the value is just parsed to midnight at the start of the next day, and is never formatted as 24:00. There's nothing in the Noda Time conceptual model to represent "the end of the day".

Sample code to show what's possible:

using System;
using NodaTime;
using NodaTime.Text;

class Test
{
    static void Main()
    {
        string text = "2007-04-05T24:00";
        var pattern = LocalDateTimePattern.CreateWithInvariantCulture
             ("yyyy-MM-dd'T'HH:mm");
        var dateTime = pattern.Parse(text).Value;
        Console.WriteLine(pattern.Format(dateTime)); // 2007-04-06T00:00
    }
}

If you don't mind losing the difference between inputs of "2007-04-05T24:00" and "2007-04-05T00:00" then you're probably okay.

OTHER TIPS

Here is one simple solution — it updates this kind of end-of-the-day values to the start-of-the-next-day:

using System;
using System.Text.RegularExpressions;
    
namespace Iso8601ToDateTime
{
  class Program
  {
    string text = "2021-12-31T24:00:00+01:00";
    var pattern = @"^([-\d]+)(T24)";
    var replaced = Regex.Replace(text, pattern,
            m => DateTime.Parse(m.Groups[1].Value)
                    .AddDays(1).ToString("yyyy-MM-dd") + "T00");

    Console.WriteLine(replaced);  // 2022-01-01T00:00:00+01:00
  }
}

UPDATED: Fixed bug based on raznagul's comment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top