Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate a string is in YYYY-MM-DD form (C#)

Most of the ways I have seen on SO have involved validating a C# date object which is not what I want to do. For what I'm working on, the user will enter a string in a format for example, 1999-02-23. I would like to validate that the string they enter follows the format of YYYY-MM-DD. The solutions I have come up with seem overly complex.

like image 738
tonyleMill Avatar asked Feb 07 '16 23:02

tonyleMill


2 Answers

Try

var stringToValidate = "1999-02-23";
DateTime dt;
bool ok = DateTime.TryParseExact(
   stringToValidate,
   "yyyy-MM-dd",
   CultureInfo.InvariantCulture,
   DateTimeStyles.None,
   out dt
);
like image 113
AlexD Avatar answered Nov 09 '22 06:11

AlexD


DISCLAIMER: @AlexD - has the correct way to validate a date. You cannot do the same with a Regex because calculations are required for leap years.

However, quoted from the original question:

Most of the ways I have seen on SO have involved validating a C# date object which is not what I want to do.

Since the question is also tagged regex, here are a couple of ways to get varying degrees of partial success with a Regex:

FEB / APR / JUN / SEP / NOV fail to produce a valid DateTime when compared to DateTime.TryParseExact():

// single line Regex, formatted below for readability:
// "\d{3}[1-9]-(0[1-9]|1[012])-(0[1-9]|1\d|2\d|3[01])"
var regexSimple = new Regex(
    @"
        # DateTime.MinValue => '0001-01-01'
        \d{3}[1-9]
        - 
        (0[1-9] | 1[012])
        -
        (0[1-9] | 1\d | 2\d | 3[01])
    ",
    RegexOptions.Compiled
    | RegexOptions.IgnorePatternWhitespace
);

FEB fails to produce a valid DateTime when compared to DateTime.TryParseExact() on leap years:

// single line Regex, formatted below for readability:
// "\d{3}[1-9]-(([0][13578]-(0[1-9]|1[012]|2\d|3[01]))|([0][469]-(0[1-9]|1[012]|2\d|30))|(02-(0[1-9]|1[012]|2[0-8]))|(11-(0[1-9]|1[012]|2\d|30))|(12-(0[1-9]|1[012]|2\d|3[01])))"
var regexAllButFeb = new Regex(
    @"
        # DateTime.MinValue => '0001-01-01'
        \d{3}[1-9]
        - 
        (
            # JAN / MAR / MAY / JUL/ AUG
            ([0][13578]-(0[1-9] | 1[012] | 2\d | 3[01]))
            | 
            # APR / JUN / SEP / NOV
            ([0][469]-(0[1-9] | 1[012] | 2\d | 30))
            |
            # FEB
            (02-(0[1-9] | 1[012] | 2[0-8]))
        #   or replace with [0-9] - ^^^^^
            |
            # NOV
            (11-(0[1-9] | 1[012] | 2\d | 30))
            |
            # DEC
            (12-(0[1-9] | 1[012] | 2\d | 3[01]))
        )
    ",
    RegexOptions.Compiled
    | RegexOptions.IgnorePatternWhitespace
);

Hopefully above isn't among the same thing(s) you've tried. ;)

like image 42
kuujinbo Avatar answered Nov 09 '22 04:11

kuujinbo