Home > Blockchain >  Inconsistency when parsing DateTime in the same format
Inconsistency when parsing DateTime in the same format

Time:11-20

I have the following strings: 10/10/2021 00:00:00 and 18/11/2021 23:59:59

I have this code:

    bool first = DateTime.TryParse("10/10/2021 00:00:00", 
        CultureInfo.InvariantCulture, 
        DateTimeStyles.None, 
        out DateTime firstDate);

    bool second = DateTime.TryParse("18/11/2021 23:59:59",
        CultureInfo.InvariantCulture,
        DateTimeStyles.None,
        out DateTime secondDate);

    Console.WriteLine(firstDate   " --- "   secondDate);

The output is: 10/10/2021 12:00:00 AM --- 1/1/0001 12:00:00 AM

As you can see the second date is not properly parsed, even though it's in the same format. What is the reason for that and how can I fix it?

CodePudding user response:

As you can see the second date is not properly parsed, even though it's in the same format.

Here my two cents.

Programming languages and frameworks are not smart enough to know which kind of format data you applied, specially for dates, times, numbers etc.. If you provide these data, you kinda have to provide the proper format as well so they can do their job. You "said" the same format, but you didn't apply any format in your code. So, as we humans, we know (at least you told us) but the computer don't know.

Let's look what TryParse(String, IFormatProvider, DateTimeStyles, DateTime) documentation says;

Converts the specified string representation of a date and time to its DateTime equivalent using the specified culture-specific format information and formatting style, and returns a value that indicates whether the conversion succeeded.

You didn't supply format information you supplied IFormatProvider as InvariantCulture. So, what are these "culture specific formats"?

Well, most of them are returns with GetAllDateTimePatterns method (but not all of them) but be aware because documentation says;

You can use the custom format strings in the array returned by the GetAllDateTimePatterns method in formatting operations. However, if you do, the string representation of a date and time value returned in that formatting operation cannot always be parsed successfully by the Parse and TryParse methods. Therefore, you cannot assume that the custom format strings returned by the GetAllDateTimePatterns method can be used to round-trip date and time values.

So, if you run;

CultureInfo.InvariantCulture.DateTimeFormat.GetAllDateTimePatterns().Dump();

*Dump is just an extension method of LINQPad by the way, it just outputs to the console.

You will get a lot of datetime patterns, but for our case, the important one is we get MM/dd/yyyy HH:mm:ss format for InvariantCulture.

As you can see, your 18/11/2021 23:59:59 data doesn't match with MM/dd/yyyy HH:mm:ss format because there is no 18th month on Gregorian calendar which is a DateTime instance belongs internally.

Your second parsing fails by the way, that's quite different just saying "the second date is not properly parsed" and this is how DateTime.TryParse method works as explained in the documentation;

When this method returns, contains the DateTime value equivalent to the date and time contained in s, if the conversion succeeded, or MinValue (which is 1/1/0001 12:00:00 AM) if the conversion failed. The conversion fails if the s parameter is null, is an empty string (""), or does not contain a valid string representation of a date and time.

So, best way to handle this to supply a "specific" format using with DateTime.TryParseExact method or one of its overloads like;

bool first = DateTime.TryParseExact("10/10/2021 00:00:00",
    "dd/MM/yyyy HH:mm:ss",
    CultureInfo.InvariantCulture, 
    DateTimeStyles.None, 
    out DateTime firstDate);

bool second = DateTime.TryParseExact("18/11/2021 23:59:59",
    "dd/MM/yyyy HH:mm:ss",
    CultureInfo.InvariantCulture,
    DateTimeStyles.None,
    out DateTime secondDate);

CodePudding user response:

The default DateTime format is 'MM/dd/yyyy' and since you have the date in 'dd/MM/yyyy' format it gives you the output. Maybe try changing the date format input as 11/18/2021 23:59:59

  • Related