public static class DatePattern
    {
        private class RegexFunc
        {
            public Regex Pattern;
            public Func<string, DateTime> Converter;
        }
      
        private static class RegexFuncParsers
        {
            private static CultureInfo enCulture = new CultureInfo("en-US");
            private static DateTime nowTime { get { return DateTime.Now; } }
            public static RegexFunc[] DateParsers =
            {
                new RegexFunc //now
                    {
                        Pattern = new Regex("(?i)(now)"),
                        Converter = (string match) => nowTime
                    },
                new RegexFunc // (?i)\d+ min ago [5 mins]
                    {
                        Pattern = new Regex(@"(?i)^\d+.*?(?=min)"),
                        Converter = (string match) =>
                        {
                            string minutes = Regex.Match(match, @"(?i)^\d+.*?(?=min)").Value.Trim();
                            return nowTime.AddMinutes(0-int.Parse(minutes));
                        }
                    },
                new RegexFunc //(?i)\d+ hours ago [1 hour, 2hours, 1 hr, 2hrs]
                    {
                        Pattern = new Regex(@"(?i)^(\d+).*?(?=h(?:ou)?r)"),
                        Converter = (string match) =>
                        {
                            string hours = Regex.Match(match, @"(?i)^(\d+).*?(?=h(?:ou)?r)").Value.Trim();
                            return nowTime.AddHours(0-int.Parse(hours));
                        }
                    },
                new RegexFunc //(?i)today H/h:mm(?:\s?tt) [Today at 8:20 AM, Today at 8:20am, Today at 8:20]
                    {
                        Pattern = new Regex(@"(?i)^today.*?(\d+:\d+(?:\s?[apm]{2})?)$"),
                        Converter = (string match) =>
                        {
                            string tt = Regex.IsMatch(match, @"(?i)\d+:\d+(?:\s?[apm]{2})") ? "tt" : "";
                            string h = tt.Any<char>() ? "h" : "H";
                            match = Regex.Replace(match, @"(?i)^today.+?(?=\d+:)", "");
                            match = Regex.Replace(match, @"(?i)(?<=:\d.+)\s(?=[apm]{2})", ""); //delete space
                            match = DateTime.Today.ToString("yyyy MM dd ") + match;
                            string format = "yyyy MM dd " + h + ":mm" + tt;
                            return DateTime.ParseExact(match, format,  enCulture);
                        }
                    },
                new RegexFunc //(?i)yesterday H/h:mm(?:\s?tt) [Yesterday at 8:20 AM, Yesterday at 8:20am, Yesterday at 8:20]
                    {
                        Pattern = new Regex(@"(?i)^yesterday.*?(\d+:\d+(?:\s?[apm]{2})?)$"),
                        Converter = (string match) =>
                        {
                            string tt = Regex.IsMatch(match, @"(?i)\d+:\d+(?:\s?[apm]{2})") ? "tt" : "";
                            string h = tt.Any<char>() ? "h" : "H";
                            match = Regex.Replace(match, @"(?i)^yesterday.+?(?=\d+:)", "");
                            match = Regex.Replace(match, @"(?i)(?<=:\d.+)\s(?=[apm]{2})", ""); //delete space
                            match = DateTime.Today.AddDays(-1.0).ToString("yyyy MM dd ") + match;
                            string format = "yyyy MM dd " + h + ":mm" + tt;
                            return DateTime.ParseExact(match, format,  enCulture);
                        }
                    }
            };
        }
      
        public static DateTime Convert(string date_pattern)
        {
            date_pattern = date_pattern.Trim();
            var dateParsers = RegexFuncParsers.DateParsers;
            for (int i = 0; i < dateParsers.Length; i++)
            {
                var match = dateParsers[i].Pattern.Match(date_pattern);
                if (!match.Success)
                    continue;
                return dateParsers[i].Converter(date_pattern);
            }
            throw new Exception("no pattern in dateParsers for " + date_pattern);
        }
    }