如何从 GUI 获取有效日期作为输入

How to get a valid Date as input from GUI

我有一个学校实习,用户在 TForm 上的 TEdit 中输入他们的出生日期。用户很可能会根据他们的自定义日期设置输入日期,但我希望能够将任何或至少大多数日期格式转换为我存储在 .mdb Access 数据库中的格式。 如何从用户输入的 GUI 中获取准确有效的日期?

我知道 decodedate(Date, year, month, day) 过程,但是如果用户输入的日期与系统设置不同或者显示在 TDBGrid 通过 [=14 连接到 .mdb 数据库=] 和 ADOTable?然后程序会崩溃。

成为用户的帮助而不是痛苦:

  • “包含”是字面意思,所以用户实际上也可以输入带有前导 and/or 尾随空格的日期?这样的事情会发生,尤其是从别处复制文本时。 修剪 这样的空白很容易,所以允许这样做。参见 trim()

  • 避免一般性错误消息,而是尽可能精确

    • 长度错误?说出你的期望和得到的结果,即:“预期长度:10,但得到的是 8。”
    • 预期位置没有分隔符?这么说,即:“预期的分隔符“/”作为第 5 个字母,但得到的是“3”。
    • 非法月份?这么说,即:“预计月份为“1”或“01”到“12”,但得到的却是“23”。
  • 尝试一次收集多个错误消息,这样用户就可以看到他所有的错误并一次性修复它们,而不是再次受到惩罚每次拍摄仅发送一条消息。

  • 检测 模式 并使其具有限制性:

    • 位置 #1 是 in ['0'.. '2'],位置 #2 到 #4 是 in ['0'.. '9']?看起来像 year 我们可以继续:
      • 位置 #5 是 in ['/', '-', '.']
        • 位置 #6 是 '0',位置 #7 是 in ['1'.. '9']?或者 pos #6 是 '1' 而 pos #7 是 in ['0'.. '2']?

    ...等等。这样您就可以更好地识别选择了哪种格式,并且可以给出更准确的错误消息。它还会导致输入不明确,例如 4/10/2016 从中您不知道 4 是一天还是一个月。

  • 检查非法日期:哪些月份不能有第 31 天? 2 月 29 日见 IsLeapYear()

  • 根据您识别的内容显示日期 - 这有助于您和您的用户确保识别正确。理想情况下,您拥有年、月和日三个整数,然后将它们连同定界符再次转换为文本——结果通常应该是您必须处理的输入。

  • Regular expressions 非常擅长识别模式,然后访问找到的部分。但是,它本身就是一个主题,只有当它自己知道时才应该使用它。我在此示例中使用的格式的正则表达式是 /([0-2][0-9]{3})[/.-](0?[1-9]|1[0-2])[/.-](0?[1-9]|[12][0-9]|3[01])/,您可以在其中轻松访问 </code> 作为年份,<code> 作为一位或两位数字的月份,以及 作为一个或两位数的一天。您“只”需要检查非法日期。

正如@AndreasReijbrand 指出的那样,TDateTimePicker 是在 GUI 上接收用户输入日期的正确方法。 TDateTimePicker 为您完成所有验证工作。经过多次辩论,我们最终被允许使用它。我 post 这个新答案对 TDateTimePicker 组件有一些重要的见解:

  1. TDateTimePicker自动更改为pc本地设置的日期格式。所以不需要验证。
  2. 不需要将日期显示格式(yyyy/mm/ddyyyy-mm-dd)从 .mdb Access 数据库转换为 TDateTimePicker,反之亦然。这也是自动完成的。 (开始明白为什么当初没有使用这个组件会受到那么多的非议了。)
  3. DateTimePicker 不允许负值或无意义的值,例如 (0030/09/082003/89/89).