2

I have a string text that i want to parse/convert to DateTime,
the text can have a different formats (depending on the user who write it),
it can be "dd/MM/yyyy" or it can be "MM/dd/yyyy".

I am using DateTime.TryParseExact(string, formats[], provider, dateTimeStyles, out result)
as descripted here TryParseExact

Now the problem happens in the following cases
if (for example) string text = "06/01/2023"

The text could have two meanings
1st  --> Day: 06, Month: 01, Year: 2023
2nd --> Day: 01, Month: 06, Year: 2023

My Question is when does the Method TryParseExact() return true
does it return true for the first format that matches text ?
or does it evalute all/each format inside the formats[] array ?

i have tried to search for a similar question, but i didn't seem to find one,
i have tried read this reference TryParseExactMultiple
i have tried this question

Thank you for your help in advance.

My code:

string text = "06/01/2023";

string[] formatsArray = new string[]
{
  "yyyyMMdd",
  "dd/MM/yyyy",
  "dd-MMM-yy",
  "MM/dd/yyyy",
  "MM-dd-yyyy"
};

DateTime result;

DateTime.TryParseExact(text, formatsArray, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out result)

Output is:
result = Day: 06, Month: 01, Year: 2023

  • 1
    Looks like it tries them in the order you present them. If you swap the order in formatsArray, what answer does it give? – codeulike Dec 15 '22 at 12:17
  • It doesn't matter how `TryParseExact` works because there's no way for *humans* to say what the correct date is. This is why people should *not* use localized formats. Where does this string come from? A UI element? HTTP request? CSV file? Whatever creates the string should either be modified to use `DateTime` instead, or it should use the ISO8601 format. – Panagiotis Kanavos Dec 15 '22 at 12:24
  • @codeulike if I swap the order then `result = Day: 01, Month: 06, Year: 2023` but still, how do I know which format is used in the parsing? – Bola Adel Nassif Dec 15 '22 at 12:25
  • @BolaAdelNassif it doesn't matter which one is used - even you can't guess what that date is without additional information. If you know what locale was used, instead of `TryParseExact` it's better to use `TryParse` with the correct locale. – Panagiotis Kanavos Dec 15 '22 at 12:26

2 Answers2

2

It seems that source code is pretty clear - TryParseExact calls TryParseExactMultiple which cycles formats in provided order and returns first one that succeeds:

internal static bool TryParseExactMultiple(ReadOnlySpan<char> s, string?[]? formats,
    DateTimeFormatInfo dtfi, DateTimeStyles style, scoped ref DateTimeResult result)
{
    // ...

    // Do a loop through the provided formats and see if we can parse successfully in
    // one of the formats.
    for (int i = 0; i < formats.Length; i++)
    {
        string? format = formats[i];
        // ...
        if (TryParseExact(s, format, dtfi, style, ref innerResult))
        {
            result.parsedDate = innerResult.parsedDate;
            result.timeZoneOffset = innerResult.timeZoneOffset;
            return true;
        }
    }

    result.SetBadDateTimeFailure();
    return false;
}

Since documentation does not specify behaviour for I would not recommend to rely on it, if it is possible, or possibly wrap this into helper method which will be tested for your particular requirements.

In general - when accepting data from somewhere you need to agree on data format, if the source of the data is not under your control - contact the vendor to clarify it otherwise sooner or later the situation like this are bound to happen (in theory not only related to dates).

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

According to the documentation, TryParseExact does not provide an indication for which format was used. My general recommendation is to allow users to send only one date format.

Crispy Holiday
  • 412
  • 1
  • 9
  • 28
  • Thank you for your help, what if I take inputs from two different sources and each source has his own format and I don't know the format of each source? – Bola Adel Nassif Dec 15 '22 at 12:33
  • 1
    @BolaAdelNassif you need to determine format for each of the sources and use different code to parse both. – Guru Stron Dec 15 '22 at 12:39
  • @BolaAdelNassif I don't know your specific use case, but I could suggest either having different endpoints depending on the request source (if this is an API) or writing a function that tries several formats one by one and returns the successful format. Why do you need to know the format? – Crispy Holiday Dec 15 '22 at 13:04