DateTime.Parse的FormatException。检查我的日期字符串中哪一部分不正确

时间:2018-09-04 08:11:06

标签: c# datetime parsing

我想验证TextBox中的日期字符串。

如果我的TextBox中有 2018-06-07 字符串,则可以使用DateTime.TryParse或{{1 }}。

但是如果我的DateTime.Parse中有 2018-12-35 ,则TextBox会抛出DateTime.Prase,这是绝对正确的。 如何确定DateTime的哪一部分错误。例如,如何确定“天”或“月”是否错误。

1 个答案:

答案 0 :(得分:1)

DateTime.Parse尝试了多种格式-有些与当前的区域性有关,而另一些则与不变性有关。似乎正在尝试使用ISO-8601格式“ yyyy-MM-dd”进行解析-这对您的第一个示例有效,但对第二个示例无效。 (十二月没有35天。)

在尝试解析多种格式时,区分哪一部分是“错误的”并不一定有意义-不同的部分可能对不同的格式无效。

如何解决此问题取决于数据的来源。如果它是机器可读的数据,则最好强制采用文化固定格式(理想情况下为ISO-8601),而不要使用DateTime.Parse:使用DateTime.ParseExact或{{1}指定所需的格式}。您仍然不会获得有关哪一部分有问题的信息,但至少更容易推理。 (这还将使您更容易知道正在使用哪个日历系统。)

如果数据来自用户,则理想情况下,您将为它们提供某种形式的日历用户界面,这样他们根本不必输入文本。到那时,只有直接输入文本的用户会产生无效的输入,您可能会认为输入为“ okay”,使他们得到“此值无效”的错误消息。

我不相信.NET可以提供任何迹象表明该值最初在哪里无效,即使对于单个值也是如此。 Noda Time在通过异常进行解析时提供了更多信息,但不是以机器可读的方式提供。 (异常消息提供了诊断信息,但这可能无法向用户显示。)

简而言之:您可能无法完全做到此处想要做的事情(没有编写自己的解析器或验证器),因此最好尝试找出其他方法。为此编写通用验证器非常困难。

如果仅 需要处理ISO-8601日期,则相对简单:

  • 用破折号分隔输入。如果没有三个破折号,则无效
  • 将输入的每个部分解析为整数。这可能会失败(分别在每个部分上)
  • 确认这一年是您乐意应对的一年
  • 验证月份在1-12之间
  • 验证日期在该月中是否有效(使用DateTime.TryParseExact进行帮助)

其中的每个部分都相当简单明了,但是您使用该信息所做的 将特定于您的应用程序。在没有做出重大假设的情况下,我们实际上没有足够的上下文来帮助编写代码。