sudhakar
sudhakar

Reputation: 1

C# regular expression to match the string "dd/mm/yyyy or mm/dd/yyyy or yyyy/mm/dd"

I'm writing c# custom sonarqube rules. I'm trying to match a string literal in the code which is exactly like "dd/mm/yyyy". I mean whenever developer used dd/mm/yyyy or mm/dd/yyyy or yyyy/mm/dd it should catch.. I need regular expression for this in c# to match the "dd/mm/yyyy or mm/dd/yyyy or yyyy/mm/dd"

Upvotes: 0

Views: 820

Answers (2)

Zohar Peled
Zohar Peled

Reputation: 82474

As I wrote in the comments, you have a much bigger problem - your allowed formats are colliding - There is no way to distinguish between dd/mm/yyyy and mm/dd/yyyy if the day is lower than 13.

Also, validating date formats can easily be achieved using DateTime.TryParseExact so there really is no need to write a big, hard to read, hard to maintain regular expression for that.

Check out this demo program (click to run) I've written to illustrate what I mean:

public class Program
{
    public static void Main(string[] args)
    {
        string[] dates = {
            // Valid dates
            "01/02/2018", // January 2nd (mm/dd/yyyy)
            "04/01/2018", // January 4th (dd/mm/yyyy)
            "20/01/2018", // January 20th (dd/mm/yyyy)
            "01/21/2018", // January 21st (mm/dd/yyyy)
            "2018/01/14", // January 14th (yyyy/mm/dd)

            // Invalid dates
            "23/13/2018", 
            "not a date", 
            "2018/22/01",
            "1/1/18"
        };

        string[] formats = {"dd/MM/yyyy", "MM/dd/yyyy", "yyyy/MM/dd"};

        for(var i = 0; i < dates.Length; i++)
        {
            DateTime dateTime;

            if(DateTime.TryParseExact(dates[i], formats, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out dateTime))
            {
                Console.WriteLine(dates[i] + " is a valid date: "+ dateTime.ToString("yyyy-MM-dd") );
            }
            else
            {
                Console.WriteLine(dates[i] + " is invalid.");
            }
        }
    }
}

And the results:

01/02/2018 is a valid date: 2018-02-01
04/01/2018 is a valid date: 2018-01-04 // Note: Wrong date! should be January 4th!
20/01/2018 is a valid date: 2018-01-20
01/21/2018 is a valid date: 2018-01-21
2018/01/14 is a valid date: 2018-01-14
23/13/2018 is invalid.
not a date is invalid.
2018/22/01 is invalid.
1/1/18 is invalid.

So, having written all that - the correct solution is to avoid string representation of datetime whenever possible, and if you really must allow that, you need to make sure you only allow a well defined set of formats that are not colliding each other - dd/mm/yyyy and yyyy/mm/dd are fine, if you want to add another option you can choose a different delimiter to help you correctly distinguish the values - dd/mm/yyyy and mm-dd-yyyy can live together quite happily, for instance.

Upvotes: 1

Barr J
Barr J

Reputation: 10929

Tihs regex will work for YYYY/MM/DD and DD/MM/YYYY:

((?=\d{4})\d{4}|(?=[a-zA-Z]{3})[a-zA-Z]{3}|\d{2})((?=\/)\/|\-)((?=[0-9]{2})[0-9]{2}|(?=[0-9]{1,2})[0-9]{1,2}|[a-zA-Z]{3})((?=\/)\/|\-)((?=[0-9]{4})[0-9]{4}|(?=[0-9]{2})[0-9]{2}|[a-zA-Z]{3})

example check:

Upvotes: 0

Related Questions