The title basically says it all. I’m getting three user-supplied integers (year, month, day)1 from a legacy database (which I cannot change). Currently, I use the following code to parse those integers into a DateTime structure:
try {
return new DateTime(year, month, day);
} catch (ArgumentException ex) {
return DateTime.MinValue;
}
Sometimes, the values don’t represent a valid date (yes, users enter stuff like 1999-06-31, and no, the legacy app did not verify this). Since throwing an exception when data validation fails is considered bad practice, I’d prefer to replace this with exception-less code. However, the only solution I could find was to convert the integers into one string and TryParseExact this string, which seems even uglier to me. Did I miss some obvious better solution?
1 Actually, it’s one integer in the format YYYYMMDD, but converting that to year, month and day is trivial…
There is not a static function
IsValidDate()so you have to write it by yourself, first naive implementation may be:I said this is a naive implementation because (besides arguments range) the only check to see if a date exists is for leap year. In practice this may fail because of calendar issues if you’re working with non Gregorian calendars (and missing days even in Gregorian calendar that has been used to align date from Julian calendar).
Working With Calendars
These assumptions may be broken for non Gregorian calendars:
DateTimetechnical limit but there may be a calendar (or an Era within a calendar) with a different minimum (and maximum) date.Rules to manage this are pretty complex and it’s too easy to forget something so, in this case, catching an exception may not be such bad idea. A better version of previous validation function may just provide basic validation and relying on
DateTimeto check other rules:Then, given this new function, your original code should be: