简体   繁体   中英

Can I make JodaTime DateTimeFormat lenient about the milliseconds of a date?

I have this unit test that is failing and I would like to get it to pass:

@Test
public void testDateFormatsWithNo() throws Exception {
    List<String> dateStrings = Lists.newArrayList("2014-08-02T22:21:32Z", "2014-05-27T17:11:55.597Z");
    try {
        String twoMillis = "yyyy-MM-dd'T'HH:mm:ss'Z'";
        for (String dateString : dateStrings) {
            DateTimeFormat.forPattern(twoMillis).parseDateTime(dateString);
        }
    } catch (Exception e) {
        fail(e.getMessage());
    }
}

@Test
public void testDateFormatsWithThreeMillis() throws Exception {
    List<String> dateStrings = Lists.newArrayList("2014-08-02T22:21:32Z", "2014-05-27T17:11:55.597Z");
    try {
        String threeMillis = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
        for (String dateString : dateStrings) {
            DateTimeFormat.forPattern(threeMillis).parseDateTime(dateString);
        }
    } catch (Exception e) {
        fail(e.getMessage());
    }
}

It fails with these error messages, respectively:

java.lang.AssertionError: Invalid format: "2014-05-27T17:11:55.597Z" is malformed at ".597Z"
java.lang.AssertionError: Invalid format: "2014-08-02T22:21:32Z" is malformed at "Z"

I want to know if there is a single date format pattern I can use to parse both of these date strings. As you can see, some strings have 2 milliseconds and some have 3. Is this possible?

For correct handling of Z symbol in your input your pattern is NOT correct because the letter Z is not a literal but stands for UTC+00:00. Following solution will work for you (and you can adjust the precision as you want):

DateTimeParser[] parsers = { 
  new DateTimeFormatterBuilder()
    .appendLiteral('.')
    .appendFractionOfSecond(2, 3) // or even set min-digits to 1
    .appendTimeZoneOffset("Z", true, 1, 2)
    .toParser(),
  new DateTimeFormatterBuilder()
    .appendTimeZoneOffset("Z", true, 1, 2)
    .toParser()};
DateTimeFormatter dtf =
  new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
    .append(null, parsers)
    .toFormatter();
String input = "2014-08-02T22:21:32.123Z";
System.out.println(dtf.parseDateTime(input));
// in my timezone: 2014-08-03T00:21:32.123+02:00

input = "2014-08-02T22:21:32.12Z";
System.out.println(dtf.parseDateTime(input));
// 2014-08-03T00:21:32.120+02:00

input = "2014-08-02T22:21:32Z";
System.out.println(dtf.parseDateTime(input));
// 2014-08-03T00:21:32.000+02:00

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM