【问题标题】:date validation failing in javajava中的日期验证失败
【发布时间】:2013-06-03 01:06:22
【问题描述】:

我有如下的日期验证代码,它不会为 01/01/19211 抛出 parseException。

有什么问题。有没有人有替代解决方案?我不能使用任何第三方库。

SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
        dateFormat.setLenient(false);
        try {
            resetPasswordUIBean.setDateOfBirth(dateFormat.parse(resetPasswordUIBean.getDateInput()));       
        } catch (ParseException e) {
            //handleException 
        }

非常感谢

【问题讨论】:

  • 未来读者请注意:您不应使用SimpleDateFormatDate。使用 java.time 包中提供的现代日期和时间 API。 See Arvind's answer.
  • 请注意,输入字符串 01/01/1921blah does not causeParseException 都会被抛出,尽管子字符串 "blah" 无效。那是因为无论是否解析了整个文本,当所有模式字母都被消耗完时,解析就完成了。

标签: java validation date


【解决方案1】:

没有问题。它接受 19211 年 1 月 1 日的有效日期。我知道文档中并不清楚,但“yyyy”接受超过 4 位数字,超过 9999 年。

如果您想将日期限制在某个最大年份(例如,不是在未来,如果这是一个出生日期),那么您可以通过从 Date 中找出年份来轻松做到这一点(通过Calendar,当然)。您可能还需要最低年份。这些是与解析分开有意义的验证步骤 - 基本上有很多日期是有效的日期,但在您的上下文中无效。

【讨论】:

  • 日期格式是 yyyy,所以从技术上讲它不应该接受 19211(yyyyy),对吗?
  • @RegisteredUser:说实话,从文档中并不清楚 - 但我认为 通常 解析器处理的 yyyy 超过四位数,这似乎是案例在这里。我认为这是合理的,以便处理最多 9999 年的“正常”情况,但 处理以后的日期。阅读我编辑的答案 - 你想添加更多验证无论如何
  • 我希望他们没有设计它认为他们的代码将在 > 10000 年使用:)
【解决方案2】:

单个y可以解析一个+位数的年份

警告:两位数的年份将被解析为没有世纪的年份,例如19 将被解析为 0019。如果您希望它是2019,请使用yy

演示:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/y", Locale.ENGLISH);
        Stream.of(
                    "01/01/1",
                    "01/01/19",
                    "01/01/192",
                    "01/01/1921",
                    "01/01/19211"
        ).forEach( s -> System.out.println(LocalDate.parse(s, dtf)));
    }
}

输出:

0001-01-01
0019-01-01
0192-01-01
1921-01-01
+19211-01-01

ONLINE DEMO

因此,您需要从结果日期获取年份的值并验证年份,例如

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/y", Locale.ENGLISH);
        int year = LocalDate.parse("01/01/19211", dtf).getYear();
        if (year < 1900 || year > 9999) {
            // Do this
        } else {
            // Do that
        }
    }
}

您可能还想查看prefer u to y

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

注意:java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    相关资源
    最近更新 更多