gpt4 book ai didi

c# - 通缉 : DateTime. TryNew(year, month, day) or DateTime.IsValidDate(year, month, day)

转载 作者:可可西里 更新时间:2023-11-01 08:53:25 24 4
gpt4 key购买 nike

标题基本上说明了一切。我从旧数据库 (我无法更改)。目前,我使用以下代码将这些整数解析为 DateTime 结构:

try {
return new DateTime(year, month, day);
} catch (ArgumentException ex) {
return DateTime.MinValue;
}

有时,这些值并不代表有效日期(是的,用户输入了诸如 1999-06-31 之类的内容,但不,旧版应用程序并未对此进行验证)。自 throwing an exception when data validation fails is considered bad practice ,我更愿意用无异常代码替换它。然而,我能找到的唯一解决方案是将整数转换为一个字符串,然后 TryParseExact 这个字符串,这对我来说似乎更难看。我是否遗漏了一些明显更好的解决方案?


1 实际上,它是 YYYYMMDD 格式的一个整数,但将其转换为年月日很简单...

最佳答案

没有静态函数 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);
}

我说这是一个幼稚的实现,因为(除了参数范围之外)唯一检查日期是否存在的是闰年。在实践中,如果您使用的是非公历(并且即使在公历中也缺少日期,用于将日期与儒略历对齐),这可能会因为日历问题而失败。

使用日历

对于非公历,这些假设可能会被打破:

  • 01 年 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;

关于c# - 通缉 : DateTime. TryNew(year, month, day) or DateTime.IsValidDate(year, month, day),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9467967/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com