1

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?

Axajkamkat
  • 149
  • 1
  • 6
  • 2
    The first date isn't parsed the way you think it is either. Try parsing `01/07/2021`. If you have a specific format to parse (in this case `dd/MM/yyyy`), use `TryParseExact`. – Jeroen Mostert Nov 18 '21 at 13:33
  • Does this answer your question? [What does CultureInfo.InvariantCulture mean?](https://stackoverflow.com/questions/9760237/what-does-cultureinfo-invariantculture-mean) – gunr2171 Nov 18 '21 at 13:35
  • 2
    The second date isn't parsed incorrectly. It just has not been parsed. The value you see is just the default value. When you use a method starting with Try you should check the return boolean if the returned out parameter contains something useful. – Ralf Nov 18 '21 at 13:39

2 Answers2

3

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);
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
1

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

AJ31
  • 210
  • 2
  • 13