在C#中解析不可能的日期

时间:2009-09-24 15:10:42

标签: c# datetime parsing user-input validation

C#中的日期输入是否有一种优雅的方式可以容纳用户输入,例如'2009-09-31'(例如9月31日,它不存在并导致DateTime.Parse窒息)?理想情况下,我想将其解析为10月1日(例如最新可能的日期加溢出)。

6 个答案:

答案 0 :(得分:11)

我不相信这是直接为您处理的。你可以做的是自己解析日期,作为三个单独的整数:

  • 解析2009年,构建2009年1月1日的日期时间
  • 解析09并减去一,然后致电dt = dt.AddMonths(8)以获得9月1日
  • 解析31并减1,然后调用dt.AddDays(30)

这将处理像2009/13/01这样的事情,意味着2010年1月1日。虽然我怀疑它不会做你想要的2月31日...

答案 1 :(得分:4)

避免用户输入中错误日期的一种方法是不要让它们在第一个实例中发生,即使用日期选择器控件。

如何使用DateTime.TryParse

  

转换指定的字符串   表示日期和时间   它的DateTime等效使用   指定的特定文化格式   信息和格式样式,以及   返回一个指示是否的值   转换成功了。

MSDN page显示了使用示例。

答案 2 :(得分:1)

我认为DateTime.DaysInMonth方法可以帮助很多,在TryParse之后......你可以实现你所谈论的逻辑

答案 3 :(得分:1)

(道德上)不应该尝试处理这样的输入。是1900年2月29日被解释为1900年3月1日(因为1900年2月29日可以被解释为1900年2月28日之后的那天,但因为它不存在于1900年2月28日之后的实际日期)或2月1900年2月28日(因为1900年2月29日可以解释为1900年2月的最后一天)?另一种情况是,如果用户意味着输入“2009-3-3”,但由于手指快速且粘滞,意外地键入“2009-3-33”。然后,自定义解析器将吞下它,而不是捕获它们的错误,比如说,2009年4月2日。由于这种情况,您应该只是DateTime.TryParse输入,并在发生无效输入时通知用户。这就是你应该做的事情。

现在,如果要求您处理此类输入。我会使用以下内容:

static DateTime Parse(int year, int month, int day) {
        DateTime date;
        if (month < 1 || month > 12) {
            int direction = month < 1 ? 1 : -1;
            do {
                month += direction * 12;
                year -= direction;
            } while (month < 1 || month > 12);
        }
        int daysInMonth = DateTime.DaysInMonth(year, month);
        if (day < 1 || day > daysInMonth) {
            date = new DateTime(year, month, daysInMonth);
            int difference = day - daysInMonth;
            date = date.AddDays(difference);
        }
        else {
            date = new DateTime(year, month, day);
        }
        return date;
}

答案 4 :(得分:0)

编译器只会抛出一个无法解析的异常,所以你必须为这类问题编写自己的解析器。

答案 5 :(得分:0)

规则#1:尽可能合理,不要让用户首先输入无效数据。

如果您正在使用Windows窗体,请尽可能使用DateTimePicker(尽管它在语言环境方面有其局限性);或者,如果您的应用程序在ASP.NET中,请使用日历或其中一个AJAX控件工具包控件(我现在忘记确切的名称),但它会弹出一个日历。

如果以后有可能需要本地化这个应用程序,我强烈建议不要将日期组件分成不同的字段(或解析它们)。