Java是否有智能日期API来识别模式本身?

时间:2012-02-17 09:52:29

标签: java jodatime

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

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

我可以保证格式为D.M.Y,但如果长或短或混淆则不能。在Joda中是否已经有一个函数可以帮助选择“基本模式”给出的模式?

谢谢!

4 个答案:

答案 0 :(得分:3)

我使用模式的搜索路径。有些日期不明确,因此您需要知道如何处理它们,例如是ADL / 1903/2003 2月3日的第1次,1月1日,公元3年或公元1年/ 1901年/ 2001年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

答案 1 :(得分:2)

我认为我使用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"));

答案 2 :(得分:1)

如果你不想使用任何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与此用法没有非常紧密的匹配,因为验证输入始终是个好主意。

答案 3 :(得分:1)

恕我直言,你是从错误的角度来解决问题,如果你有一个输入,它包含表示日期的字符串列表,但是格式不同,那么你有文本验证问题,而不是日期格式问题。 / p>

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