Java 是否有一个可以识别模式本身的智能日期 API?

发布于 2025-01-06 16:59:14 字数 409 浏览 3 评论 0原文

我有以下输入案例,但我不想自己检查格式并每次都更改模式。我目前使用 DateTimeFormat.forPattern("dd.MM.yyyy");,只要 a), c)d)< 就会失败/code> 已应用。

a) 1.1.12      => 01.01.0012 x
b) 01.01.2012  => 01.01.2012 ✓
c) 01.01.12    => 01.01.0012 x
d) 1.1.2012    => 01.00.2012 x

我可以保证格式是 DMY,但如果它是长的、短的或混合的,则不是。 Joda 中是否已经有一个函数可以帮助选择“基本模式”上给出的模式?

谢谢你!

I have the following input cases, but I don't want to examine the format myself and change the pattern everytime. I currently make use of DateTimeFormat.forPattern("dd.MM.yyyy");, this fails as soon as a), c) or d) are applied.

a) 1.1.12      => 01.01.0012 x
b) 01.01.2012  => 01.01.2012 ✓
c) 01.01.12    => 01.01.0012 x
d) 1.1.2012    => 01.00.2012 x

I can assure that the format is D.M.Y, but not if it's long or short or mixed up. Is there already a function in Joda which helps to choose the pattern given on a "base pattern"?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

讽刺将军 2025-01-13 16:59:14

我使用模式搜索路径。有些日期是不明确的,因此您需要知道如何处理它们,例如 1.2.3 是公元 1903 年 2 月 3 日第一天或 1 月 2 日,公元 3 日或公元 1901 年 2 月 3 日。

我使用的一个简单模式(除了我缓存 SimpleDateFormat 对象;)

public static Date parseDate(String dateStr) throws IllegalArgumentException {
    // optionally change the separator
    dateStr = dateStr.replaceAll("\\D+", "/");

    for (String fmt : "dd/MM/yy,yyyy/MM/dd,dd/MM/yyyy".split(",")) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(fmt);
            sdf.setLenient(false);
            return sdf.parse(dateStr);
        } catch (ParseException ignored) {
        }
    }
    throw new IllegalArgumentException("Unable to parse date '" + dateStr + "'");
}

public static void main(String... args) {
    String dates = "1.2.12\n" +
            "01.02.2012\n" +
            "2012.02.01\n" +
            "01-01-12\n" +
            "1.1.2012";
    for (String dateStr : dates.split("\n")) {
        Object result;
        try {
            result = parseDate(dateStr);
        } catch (IllegalArgumentException e) {
            result = e;
        }
        System.out.println(dateStr + " => " + result);
    }
}

打印

1.2.12 => Wed Feb 01 00:00:00 GMT 2012
01.02.2012 => Wed Feb 01 00:00:00 GMT 2012
2012.02.01 => Wed Feb 01 00:00:00 GMT 2012
01-01-12 => Sun Jan 01 00:00:00 GMT 2012
1.1.2012 => Sun Jan 01 00:00:00 GMT 2012

I use a search path of patterns. Some dates are ambiguous, so you need to know how you want to handle them e.g. is 1.2.3 the first of Feb 3 AD/1903/2003 or second of January, 3 AD or 1 AD/1901/2001 Feb the third.

A simple pattern I use (except I cache the SimpleDateFormat objects ;)

public static Date parseDate(String dateStr) throws IllegalArgumentException {
    // optionally change the separator
    dateStr = dateStr.replaceAll("\\D+", "/");

    for (String fmt : "dd/MM/yy,yyyy/MM/dd,dd/MM/yyyy".split(",")) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(fmt);
            sdf.setLenient(false);
            return sdf.parse(dateStr);
        } catch (ParseException ignored) {
        }
    }
    throw new IllegalArgumentException("Unable to parse date '" + dateStr + "'");
}

public static void main(String... args) {
    String dates = "1.2.12\n" +
            "01.02.2012\n" +
            "2012.02.01\n" +
            "01-01-12\n" +
            "1.1.2012";
    for (String dateStr : dates.split("\n")) {
        Object result;
        try {
            result = parseDate(dateStr);
        } catch (IllegalArgumentException e) {
            result = e;
        }
        System.out.println(dateStr + " => " + result);
    }
}

prints

1.2.12 => Wed Feb 01 00:00:00 GMT 2012
01.02.2012 => Wed Feb 01 00:00:00 GMT 2012
2012.02.01 => Wed Feb 01 00:00:00 GMT 2012
01-01-12 => Sun Jan 01 00:00:00 GMT 2012
1.1.2012 => Sun Jan 01 00:00:00 GMT 2012
灼痛 2025-01-13 16:59:14

我想我使用 Joda-Time 得到了更好的解决方案。我把它归结为你必须尝试的两个解析器:

    DateTimeFormatter f = new DateTimeFormatterBuilder()
            .appendDayOfMonth(1)
            .appendLiteral('.')
            .appendMonthOfYear(1)
            .appendLiteral('.')
            .appendTwoDigitYear(1970) // Notice this!!
            .toFormatter();

    System.out.println(f.parseDateTime("01.1.12"));
    System.out.println(f.parseDateTime("01.01.12"));

    f = new DateTimeFormatterBuilder()
            .appendDayOfMonth(1)
            .appendLiteral('.')
            .appendMonthOfYear(1)
            .appendLiteral('.')
            .appendYear(4,4)
            .toFormatter();

    System.out.println(f.parseDateTime("01.01.2012"));
    System.out.println(f.parseDateTime("1.1.2012"));
    System.out.println(f.parseDateTime("01.1.2012"));

I think I got a better solution using Joda-Time. I got it down to two parsers that you have to try:

    DateTimeFormatter f = new DateTimeFormatterBuilder()
            .appendDayOfMonth(1)
            .appendLiteral('.')
            .appendMonthOfYear(1)
            .appendLiteral('.')
            .appendTwoDigitYear(1970) // Notice this!!
            .toFormatter();

    System.out.println(f.parseDateTime("01.1.12"));
    System.out.println(f.parseDateTime("01.01.12"));

    f = new DateTimeFormatterBuilder()
            .appendDayOfMonth(1)
            .appendLiteral('.')
            .appendMonthOfYear(1)
            .appendLiteral('.')
            .appendYear(4,4)
            .toFormatter();

    System.out.println(f.parseDateTime("01.01.2012"));
    System.out.println(f.parseDateTime("1.1.2012"));
    System.out.println(f.parseDateTime("01.1.2012"));
温馨耳语 2025-01-13 16:59:14

恕我直言,您从错误的角度处理问题,如果您的输入由表示日期的字符串列表组成,但格式不同,那么您将遇到文本验证问题,而不是日期格式问题。

再说一次,这只是我的意见,但我认为如果您所做的是创建一个文本解析器,在必要时将所有这些输入的文本更改为更适合您的日期解析器的文本格式,您会发现它更容易,这样您可以使用更强大的实用程序,例如正则表达式...

IMHO you are approaching the problem from the wrong perspective, if you have an input which consist on a list of Strings that represent dates, but in different formats, then you have a text validation problem, not a date formatting problem.

Again, this is only my opinion, but I think you'll find it easier if what you do is create a text parser that changes the text for all this inputs when necessary to a more suitable text format for your date parser, this way you can use more powerful utilities like regex...

清风无影 2025-01-13 16:59:14

如果您不想使用任何对 java.util.Data 的引用,则必须这样做:

public DateTime getDateTime(String text) {
    DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder();
    fb.appendDayOfMonth(2);
    fb.appendLiteral('.');
    fb.appendMonthOfYear(2);
    fb.appendLiteral('.');
    fb.appendYear(2, 4);
    DateTimeFormatter formatter = fb.toFormatter();

    DateTime dt = formatter.parseDateTime(text);
    if (dt.getYear() < 2000) {
        dt = dt.plusYear(2000);
    }
    return dt;
}

但我会推荐这个解决方案:

public DateTime getDateTime(String text) {
    SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
    java.util.Date jud = f.parse(text);
    if (jud != null) {
        return new DateTime(jud);
    } else {
        return null;
    }
}

两者都应该可以解决问题并适用于您的示例。

注意:正如 Alberto 所说,您应该首先使用正则表达式验证您的输入,因为 SimpleDateFormat 与此用法没有非常紧密的匹配,并且验证输入始终是一个好主意。

If you don't want to use any reference to java.util.Data, you'll have to do it like this:

public DateTime getDateTime(String text) {
    DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder();
    fb.appendDayOfMonth(2);
    fb.appendLiteral('.');
    fb.appendMonthOfYear(2);
    fb.appendLiteral('.');
    fb.appendYear(2, 4);
    DateTimeFormatter formatter = fb.toFormatter();

    DateTime dt = formatter.parseDateTime(text);
    if (dt.getYear() < 2000) {
        dt = dt.plusYear(2000);
    }
    return dt;
}

But I would recommend this solution:

public DateTime getDateTime(String text) {
    SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
    java.util.Date jud = f.parse(text);
    if (jud != null) {
        return new DateTime(jud);
    } else {
        return null;
    }
}

Both should do the trick and work for your examples.

Note: As Alberto said, you should validate your input first using regular expressions, because SimpleDateFormat doesn't have a very tight matching with this usage and because it's always a good idea to validate input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文