4

I have the following (somewhat abbreviated) code to parse String input into a Joda Time DateTime object. I need to properly handle multiple formats, including four & two digit years.

setupValidDateFormats();
DateTime date = convertToDateTime(thisField.getText());
if (date != null) {
    thisField.setText(date.toString("MM/dd/yyyy"));
} else {
    System.out.println("Invalid date");
}

private void setupValidDateFormats() {
    DateTimeParser[] formats = {
            DateTimeFormat.forPattern("MM/dd/yyyy").getParser(),
            DateTimeFormat.forPattern("MM/dd/yy").getParser(),
            DateTimeFormat.forPattern("MM-dd-yyyy").getParser(),
            DateTimeFormat.forPattern("MM-dd-yy").getParser(),
            DateTimeFormat.forPattern("MMddyyyy").getParser(),
            DateTimeFormat.forPattern("MMddyy").getParser()
    };
    formatter = new DateTimeFormatterBuilder().append(null, formats).appendTwoDigitYear(1950, true).toFormatter()
            .withLocale(Locale.US);
}

private DateTime convertToDateTime(String input) {
    if (isNullOrEmpty(input)) {
        return null;
    }

    DateTime date;
    try {
        // When you parse a date, it'll throw an exception for not only invalid formats,
        // but for invalid values such as 09/31/2013 or 02/30/2013. Leap year is included as well.
        date = formatter.parseDateTime(input);
    } catch (Exception e) {
        // User input a date in the incorrect format, or an invalid value.
        // Example: 02/30/2013 is invalid.
        date = null;
    }

    return date;
}

The issue I'm having is that when the user enters 120100, I expect it to be able to parse correctly and ultimately output at 12/01/1900. However, formatter.parseDateTime(input); in convertToDateTime throws an IllegalArgumentException instead, and the method returns null.

Probably worth noting that if I remove the appendTwoDigitYear from the DateTimeFormatterBuilder chain, the input does parse successfully, but 120100 becomes 12/01/0000, but that's not what I need.

Am I misunderstanding the Joda Time API? Shouldn't appendTwoDigitYear with the 1950 pivot handle the 00 two year digit as 1900?

4

1 回答 1

4

当您使用类似的模式时

DateTimeFormat.forPattern("MMddyyyy")

它可以读取类似的日期"120100"。它的作用是读取12for MM01fordd00作为 , 的字面值yyyy0从年开始0,所以0000

因为该模式出现MMddyy在您的parsers数组之前,它将用于解析您的日期字符串。

除了重新排序或删除该格式之外,您想要做的是使用基准年。

public static void main(String[] args) throws Exception {
    String str = "120100";

    DateTimeParser[] formats = {
            DateTimeFormat.forPattern("MM/dd/yyyy").getParser(),
            DateTimeFormat.forPattern("MM/dd/yy").getParser(),
            DateTimeFormat.forPattern("MM-dd-yyyy").getParser(),
            DateTimeFormat.forPattern("MM-dd-yy").getParser(),
            DateTimeFormat.forPattern("MMddyy").getParser()
    };

    DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, formats).toFormatter()
            .withPivotYear(1950).withLocale(Locale.US);

    DateTime dateTime = formatter.parseDateTime(str);
    System.out.println(dateTime);       
}

印刷

1900-12-01T00:00:00.000-05:00

我仍在试图弄清楚它是如何appendTwoDigitYear工作的。

于 2013-10-02T19:04:43.260 回答