没有静态函数IsValidDate()所以你必须自己写,第一个幼稚的实现可能是:
public static bool IsValidDate(int year, int month, int day)
{
if (year < DateTime.MinValue.Year || year > DateTime.MaxValue.Year)
return false;
if (month < 1 || month > 12)
return false;
return day > 0 && day <= DateTime.DaysInMonth(year, month);
}
我说这是一个幼稚的实现,因为(除了参数范围)唯一检查日期是否存在是闰年。在实践中,如果您使用的是非公历(甚至在用于与儒略历对齐日期的公历中缺少天数),这可能会因为日历问题而失败。
使用日历
对于非公历,这些假设可能会被打破:
- 1 月 1 日是最小的有效日期。这不是真的。不同的日历有不同的最小日期。此限制只是
DateTime 技术限制,但可能有一个日历(或日历中的一个时代)具有不同的最小(和最大)日期。
- 一年中的月数小于或等于 12。这是不正确的,在某些日历中上限为 13,而且每年并不总是相同。
- 如果日期有效(根据所有其他规则),那么它就是有效日期。这不是真的,一个日历可能有多个纪元,而且并非所有日期都有效(甚至可能在纪元日期范围内)。
管理这种情况的规则非常复杂,而且很容易忘记一些事情,所以在这种情况下,捕捉异常可能不是一个坏主意。之前验证功能的更好版本可能只提供基本验证并依赖DateTime 来检查其他规则:
public static DateTime? TryNew(int year,
int month,
int day,
Calendar calendar)
{
if (calendar == null)
calendar = new GregorianCalendar();
if (year < calendar.MinSupportedDateTime.Year)
return null;
if (year > calendar.MaxSupportedDateTime.Year)
return null;
// Note that even with this check we can't assert this is a valid
// month because one year may be "shared" for two eras moreover here
// we're assuming current era.
if (month < 1 || month > calendar.GetMonthsInYear(year))
return null;
if (day <= 0 || day > DateTime.DaysInMonth(year, month))
return null;
// Now, probably, date is valid but there may still be issues
// about era and missing days because of calendar changes.
// For all this checks we rely on DateTime implementation.
try
{
return new DateTime(year, month, day, calendar);
}
catch (ArgumentOutOfRangeException)
{
return null;
}
}
那么,给定这个新函数,你的原始代码应该是:
return TryNew(year, month, day) ?? DateTime.MinValue;