/// <summary> /// Validates a date string (using Gregorian calendar) /// </summary> public static bool IsValidDate(string dateString, DatePartsOrder datePartsOrder = DatePartsOrder.MDY) { if (string.IsNullOrWhiteSpace(dateString)) { return(false); } if (dateString.Length < 5) { return(false); } var parts = dateString.Split(new char[] { '.', '/' }); if (parts.Length != 3) { return(false); } Func <string, int> parsePart = s => { s = s.Trim(); if (s.Length == 0) { return(-1); } int ret = 0; if (!int.TryParse(s, out ret)) { return(-1); } return(ret); }; int part1 = parsePart(parts[0]); if (part1 == -1) { return(false); } int part2 = parsePart(parts[1]); if (part2 == -1) { return(false); } int part3 = parsePart(parts[2]); if (part3 == -1) { return(false); } int m, d, y; switch (datePartsOrder) { case DatePartsOrder.MDY: m = part1; d = part2; y = part3; break; case DatePartsOrder.YMD: y = part1; m = part2; d = part3; break; case DatePartsOrder.DMY: d = part1; m = part2; y = part3; break; default: throw new NotImplementedException("Unsupported DatePartsOrder."); } // Up for debate, but in practical terms, a year so much in the future is probably not // the intent of validating a date in a typical user input scenario. if (y < 1 || y > 2200 || m < 1 || m > 12 || d < 1) { return(false); } if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) { if (d > 31) { return(false); } } else if (m == 2) { if (DateTime.IsLeapYear(y)) { if (d > 29) { return(false); } } else if (d > 28) { return(false); } } else if (d > 30) { return(false); } return(true); }
/// <summary> /// Validates a date string (using Gregorian calendar) /// </summary> static public bool IsValidDate(string dateString, DatePartsOrder datePartsOrder = DatePartsOrder.MDY) { if (string.IsNullOrWhiteSpace(dateString)) return false; if (dateString.Length < 5) return false; var parts = dateString.Split(new char[] {'.', '/'}); if (parts.Length != 3) return false; Func<string, int> parsePart = s => { s = s.Trim(); if (s.Length == 0) return -1; int ret = 0; if (!int.TryParse(s, out ret)) return -1; return ret; }; int part1 = parsePart(parts[0]); if (part1 == -1) return false; int part2 = parsePart(parts[1]); if (part2 == -1) return false; int part3 = parsePart(parts[2]); if (part3 == -1) return false; int m, d, y; switch (datePartsOrder) { case DatePartsOrder.MDY: m = part1; d = part2; y = part3; break; case DatePartsOrder.YMD: y = part1; m = part2; d = part3; break; case DatePartsOrder.DMY: d = part1; m = part2; y = part3; break; default: throw new NotImplementedException("Unsupported DatePartsOrder."); } // Up for debate, but in practical terms, a year so much in the future is probably not // the intent of validating a date in a typical user input scenario. if (y < 1 || y > 2200 || m < 1 || m > 12 || d < 1) return false; if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) { if (d > 31) return false; } else if (m == 2) { if (DateTime.IsLeapYear(y)) { if (d > 29) return false; } else if (d > 28) return false; } else if (d > 30) { return false; } return true; }