Home > Software engineering >  How can I parse a datetime with a nonstandard format (yyyyMMdd:Hmm)?
How can I parse a datetime with a nonstandard format (yyyyMMdd:Hmm)?

Time:10-06

We have an integration partner who insists on sending us datetimes as strings in the format yyyyMMdd:Hmm, e.g., "20211029:102". Note that the hour does not have a leading zero.

I tried to parse it like this:

Datetime datetime = DateTime.ParseExact(
   "20211029:102", 
   "yyyyMMdd:hmm", 
   CultureInfo.InvariantCulture, 
   DateTimeStyles.None
);

But this results in

FormatException••• String '20211029:102' was not recognized as a valid DateTime.

I can make it work by re-adding the missing zero, something like:

string datetimeParts = "20211029:102".Split(":");
string value = datetimeParts[0]   datetimeParts[1].PadLeft(4, '0');
Datetime dt = DateTime.ParseExact(
    value, 
    "yyyyMMddHHmm", 
    CultureInfo.InvariantCulture, 
    DateTimeStyles.None
);

But I feel I shouldn't need to "preparse" the value. Is it possible to parse this format without pre-processing?

CodePudding user response:

The problem lies in the time part of your format string, so my answer will explain why you cannot parse 102 with the format string Hmm. (I know you wrote hmm, but since you don't have an AM/PM designator, I'll assume that you meant to write Hmm instead. The same reasoning applies to hmm.)

If we look at the the reference source, we can see that the DateTime parser is "greedy": If the parser encounters a single-letter format specifier (such as H), it will still try to consume 2 digits, if two digits are available.

In your case, two digits are available, so H will consume 10 of 102. This only leaves 2 for the minute, which won't match mm (since it only has one digit).

Given this limitation, it's not possible to parse a DateTime value formatted as Hmm with DateTime.ParseExact. The documentation notes the following:

Note

If format is a custom format pattern that does not include date or time separators (such as "yyyyMMddHHmm"), use the invariant culture for the provider parameter and the widest form of each custom format specifier. For example, if you want to specify hours in the format pattern, specify the wider form, "HH", instead of the narrower form, "H".

  • Related