Nostromo
Nostromo

Reputation: 1264

Parse string to date with specific culture only

My question is kind of tricky, I hope you can understand what I'm trying to ask.

All my examples use the date 27th of february 2018.

In germany they write this date as 27.02.2018 or as 27.2.2018.

In the UK they write this date as 27/02/2018 or as 27/2/2018.

In the USA they write this date as 2/27/2018 or as 02/27/2018.

The ISO standard for this date is 2018-02-27.

In our software the user can enter a date in a string field and I like to check if the string the user entered is a valid date, but only in the local culture. So in germany only 27.02.2018 or 27.2.2018 are valid entries, in the USA only 2/27/2018 or 02/27/2018 are valid entries.

To accomplish this I tried several methods (CurrentCulture is german)

  1. isValid = Date.TryParse("27.02.2018", New Date)
  2. isValid = Date.TryParse("27.02.2018", CultureInfo.CurrentCulture, DateTimeStyles.None, New Date)
  3. isValid = Date.TryParseExact("27.02.2018", "d.M.yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None, New Date)

The first and the second way work, but they also recognize a date, when the user enters 2018-02-27. The third way works the way I want it, but only when the user enters a german formatted date. If the user works on an american client and enters an USA formatted date, the third way would fail, since the second parameter is culture specific.

So, how can one parse a string to a date for the local culture and for the local culture only? Is there a built-in .NET way or do I have to write a parser myself, picking all the necessary information from the CultureInfo?

Upvotes: 0

Views: 117

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460158

I think "d/M/yyyy" is what you want, because / is replaced with the current culture's date separator. Read: Custom date and time format strings: the "/" custom format specifier

public static DateTime? TryParseLocalShortDate(string dtString)
{
    if (string.IsNullOrWhiteSpace(dtString))
        return null;
    bool isValid = DateTime.TryParseExact(dtString, "d/M/yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt);
    return isValid ? dt : new DateTime?();
}

Your sample:

DateTime? dt1 = TryParseLocalShortDate("27.02.2018"); // 27.02.2018
DateTime? dt2 = TryParseLocalShortDate("2018-02-27"); // null

Unfortunately d/M/yyyy is recognizing "27.02.2018" and "27/02/2018" as valid dates in german culture

Then you could use this approach using DateTimeFormat.ShortDatePattern which is stricter:

public static DateTime? TryParseLocalShortDate(string dtString)
{
    if (string.IsNullOrWhiteSpace(dtString))
        return null;
    string format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
    bool isValid = DateTime.TryParseExact(dtString, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt);
    return isValid ? dt : new DateTime?();
}

Upvotes: 1

Related Questions