有没有更快的方法来检查这是否是一个有效的日期?

时间:2010-05-17 13:06:09

标签: c# performance datetime

有没有更快的方法来简单地捕获如下的异常?

try
{
    date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
    // This is an invalid date
}

9 个答案:

答案 0 :(得分:15)

String DateString = String.Format("{0}/{1}/{2}", model_.Date.Month, (7 * multiplier) + (7 - dow) + 2),model_.Date.Year);

DateTime dateTime;
if(DateTime.TryParse(DateString, out dateTime))
{
    // valid
}

正如GenericTypeTea指出的评论一样,这段代码的运行速度不会超过你现在的速度。但是,我相信你获得了可读性。

答案 1 :(得分:9)

如果您的目标是避免使用异常,则可以编写自定义验证方法:

public bool IsValidDate(int year, int month, int multiplier, int dow)
{
    if (year < 1 | year > 9999) { return false; }

    if (month < 1 | month > 12) { return false; }

    int day = 7 * multiplier + 7 - dow;
    if (day < 1 | day > DateTime.DaysInMonth(year, month)) { return false; }

    return true;
}

这与您正在使用的DateTime构造函数执行大多数相同的验证 - 它只会省略检查以查看结果DateTime是否小于DateTime.MinValue或大于DateTime.MaxValue。

如果你大多数都得到了好的值,那么整体上可能会更慢:DateTime.DaysInMonth必须做很多与DateTime构造函数相同的事情,所以它会增加所有好日期的开销。

答案 2 :(得分:5)

嗯......按照这种方式思考:model_类有一个DateTime属性

model_.Date

,所以无需验证年份和年份。月。唯一棘手的部分是这个月的日子:

(7 * multiplier) + (7 - dow) + 2

这样一种非常快速有效的方法来验证它(比抛出和捕获更好)就是使用DateTime.DaysInMonth方法:

if ((multiplier <= 4) && 
    (DateTime.DaysInMonth(model_.Date.Year, model_.Date.Month) < 
        (7 * multiplier) + (7 - dow) + 2))
{
    // error: invalid days for the month/year combo...
}

另一个好处是您不需要实例化新的DateTime来验证此信息。

PS 更新了代码以确保乘数 <&lt; = 4.这只是有意义的,因为任何值&gt; = 5都会使DaysInMonth测试失败。

答案 3 :(得分:2)

查看DateTime.TryParse方法

答案 4 :(得分:2)

编辑:Woops! DateTime.TryParse不会在内部引发异常。我在说我的臀部!总之...

DateTime.TryParse()将在内部抛出异常,并且会导致与您的问题中的代码相同的结果。如果速度很重要,则必须编写自己的方法。

这可能看起来更像代码,但我认为如果您预计会出现大量错误,它会更快:

public bool GetDate(int year, int month, int day, out DateTime dateTime)
{
    if (month > 0 && month <= 12)
    {
        int daysInMonth = DateTime.DaysInMonth(year, month);
        if (day <= daysInMonth)
        {
            dateTime = new DateTime(year, month, day);
            return true;
        }
    }
    dateTime = new DateTime();
    return false;
}

我上面的例子不会处理所有情况(即我不处理年数),但它会指出你正确的方向。

答案 5 :(得分:2)

最快的日期验证方法是单行代码:

static bool IsValidDate(int year, int month, int day) =>
             !(year < 1 || year > 9999 ||
            month < 1 || month > 12 ||
            day < 1 || day > DateTime.DaysInMonth(year, month));

使用DateTime构造函数或任何解析函数或任何异常处理程序将减慢验证速度。仅当您要验证字符串时,才首选TryParse。

答案 6 :(得分:1)

我不知道更快,但

DateTime.TryParse()

应该做同样的事情。

如果有人能告诉我这是否比问题中描述的方式更快(就处理器时间而言),我会感兴趣。

答案 7 :(得分:0)

但有一件事:例外是针对例外情况。 Bogoformatted字符串不是例外但是预期,因此TryParse更合适。

使用try / catch来检查有效性是滥用和误解异常,特别是对于一个包罗万象的捕获(后者已经导致我搜索了为什么某些东西不起作用的原因,并且很多次)。

答案 8 :(得分:-1)

如果解析机制不是更快,那么您可以使用稍微更详细的方法直接检查模型对象的属性以获取有效值。