5

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.

Community
  • 1
  • 1
Bjarte
  • 2,167
  • 5
  • 27
  • 37

2 Answers2

4

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • `Yes, .NET doesn't support this as far as I'm aware`. Isn't that specced somewhere? You seem to be the guy who just "knows" these things, right? :) – bas Jan 02 '14 at 09:40
  • @bas If you look at [`Custom Date and Time Format Strings`](http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx), there is no format to support `24` as an hour. – Soner Gönül Jan 02 '14 at 09:43
  • @bas: Well, the "HH" custom format specifier is documented as: "The hour, using a 24-hour clock from 00 to 23." – Jon Skeet Jan 02 '14 at 09:43
  • Thanks Jon, this solves my problem. I was getting errors with my import from SAP XML exports. – Bjarte Jan 02 '14 at 09:52
  • @Jon: I think your marketing is working well. The moment I read this question I was already thinking "I bet Noda Time does this" and then scrolled down to see your answer. ;-) – Chris Jan 02 '14 at 09:53
  • 1
    @Chris: That's good to hear :) Admittedly we're lucky that Noda Time does this - I think I happened to spot it when reading through ISO-8601... – Jon Skeet Jan 02 '14 at 10:03
  • Hey Jon -- any idea how to get `24:00:00` to parse in DateTime? I'm thinking to just nudge it a day up. – theGreenCabbage Mar 25 '14 at 18:54
  • @theGreenCabbage: As per the first line of the answer: ".NET doesn't support this as far as I'm aware" – Jon Skeet Mar 25 '14 at 19:14
  • It looks like newtonsoft json.net can handle this time format natively too. – Andrew Savinykh May 23 '14 at 06:25
0

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.