Hei*_*nzi 10 .net c# validation datetime
标题基本上都说明了一切.我得到三个用户提供的整数(year,month,day)1从旧的数据库(我不能改变).目前,我使用以下代码将这些整数解析为DateTime结构:
try {
return new DateTime(year, month, day);
} catch (ArgumentException ex) {
return DateTime.MinValue;
}
Run Code Online (Sandbox Code Playgroud)
有时,这些值不代表有效日期(是的,用户输入类似1999-06-31的内容,不,遗留应用程序没有验证这一点).由于在数据验证失败时抛出异常被认为是不好的做法,我宁愿用无异常代码替换它.但是,我能找到的唯一解决方案是将整数转换成一个字符串和TryParseExact这个字符串,这对我来说似乎更加丑陋.我错过了一些明显更好的解决方案吗
1实际上,它是YYYYMMDD格式的一个整数,但将其转换为年,月和日是微不足道的......
Adr*_*tti 20
没有静态函数,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);
}
Run Code Online (Sandbox Code Playgroud)
我说这是一个天真的实现,因为(除了参数范围)唯一的检查是否存在日期是闰年.在实践中,如果您正在使用非公历日历(以及在格里高利历中用于将日期与朱利安日历对齐)的日期缺失,则可能因日历问题而失败.
对于非Gregorian日历,这些假设可能会被打破:
DateTime技术限制,但可能有一个日历(或日历中的Era)具有不同的最小(和最大)日期.管理这个的规则非常复杂,很容易忘记一些事情,所以在这种情况下,捕获异常可能不是一个坏主意.以前验证功能的更好版本可能只提供基本验证并依赖于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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,给定这个新函数,您的原始代码应该是:
return TryNew(year, month, day) ?? DateTime.MinValue;
Run Code Online (Sandbox Code Playgroud)