-2

The known formats are listed below

dd/mm/yyyy (01/01/2015)
d/m/yyyy (1/1/2015)
dd/mm/yy (01/01/15)
d/m/yy (1/1/15)

Other variations will have dash(-), dot(.) or whitespace as field separator.

I am thinking of creating one regex per pattern to keep it maintainable but not sure if there is any better solution. Please share if there any better solution.

Update: The date is part of a large text and I cannot use DateTime.TryParseExact before extracting potential list of dates from the text.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
kodebot
  • 1,718
  • 1
  • 22
  • 29

3 Answers3

6

I have no knowledge about regex but, DateTime.TryParseExact has an overload which takes formats as a string array.

You can easily supply all formats that you have and try your string is matched one of them or not.

By the way, mm specifier is for minutes, MM specifier is for months if you try to mentioned about months.

string s = "";
var formats = new string[]
{
             "dd/MM/yyyy",
             "d/M/yyyy",
             "dd/mm/yy",
             "d/m/yy",

             "dd-MM-yyyy",
             "d-M-yyyy",
             "dd-MM-yy",
             "d-M-yy",

             "dd.MM.yyyy",
             "d.M.yyyy",
             "dd.MM.yy",
             "d.M.yy",

             "dd MM yyyy",
             "d M yyyy",
             "dd MM yy",
             "d M yy",
};
DateTime dt;
if (DateTime.TryParseExact(s, formats, CultureInfo.InvariantCulture,
                              DateTimeStyles.None, out dt))
{
    // Your string is matched one of first successfull match
}
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • Thanks Soner. But that will not meet my requirement because the date will be part of a large text and I need to identify potential list of dates first before using the TryParseExact method. – kodebot Jan 22 '15 at 12:10
  • @Mani Don't you have a chance to split this large string to get these values? – Soner Gönül Jan 22 '15 at 12:20
  • No, because the date can appear in any place in the string that I am parsing. This is why I am thinking of Regex to match various date patterns. – kodebot Jan 22 '15 at 12:24
2

OK. I have split the problem into two

  • Identify Date Pattern in the string and extract the matched string
  • Validate the identified date pattern and then extract day, month and year.

I am using regex to identify the pattern as follows and then using DateTime.TryParseExact to validate and extract day, month and year as suggested by Soner.

var datePatternRegex = new Regex(@"\b\d{1,2}(/|-|.|\s)\d{1,2}(/|-|.|\s)(\d{4}|\d{2})");
var testData = new []{
"This is test1 10/10/1012 data",
"This is test2 1/1/1012 data",
"This is test3 10-10-1012 data",
"This is test4 1-1-1012 data",
"This is test5 10.10.1012 data",
"This is test6 1.1.1012 data",
"This is test7 10 10 1012 data",
"This is test8 1 1 1012 data",
};

foreach(var data in testData)
{
    Console.WriteLine("Parsing {0}", data);

    var match = datePatternRegex.Match(data);
    if(match.Success)
    {
        var result = match.Groups[0];
        Console.WriteLine(result.Value);
    }
    else
    {
        Console.WriteLine("No Match");
    }
}
kodebot
  • 1,718
  • 1
  • 22
  • 29
0

This is working :

        string input = "01/01/2015";
        Regex regex = new Regex(@"(?<day>(3[0-1]|[0-2]\d|\d))/(?<month>(1[0-2]|0\d|\d))/(?<year>([1-2]\d{3}|\d{2}))");
        Match match = regex.Match(input);

        string year = match.Groups["year"].Value;
        string month = match.Groups["month"].Value;
        string day = match.Groups["day"].Value;

        Trace.WriteLine(match.Groups["year"].Value);
        Trace.WriteLine(match.Groups["month"].Value);
        Trace.WriteLine(match.Groups["day"].Value);