Joda Time & parsing two digit year correctly based on pivot

↘锁芯ラ 提交于 2020-01-24 05:48:04

问题


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?


回答1:


When you use a pattern like

DateTimeFormat.forPattern("MMddyyyy")

it can read a date like "120100". What it does is read the 12 for MM, the 01 for dd, and 00 as a literal value for yyyy, ie. 0 starting at year 0, so 0000.

Because that pattern appears before the MMddyy in your parsers array, it will be used to parse your date string.

What you'll want to do, along with reordering or removing that format, is use a pivot year.

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);       
}

prints

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

I'm still trying to figure out how appendTwoDigitYear works.



来源:https://stackoverflow.com/questions/19143817/joda-time-parsing-two-digit-year-correctly-based-on-pivot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!