Accept millis larger than 3 characters and truncate to the first three digits. Update deserialisation tests accordingly.
diff --git a/src/main/java/com/fasterxml/jackson/databind/util/StdDateFormat.java b/src/main/java/com/fasterxml/jackson/databind/util/StdDateFormat.java
index b0b2581..139d709 100644
--- a/src/main/java/com/fasterxml/jackson/databind/util/StdDateFormat.java
+++ b/src/main/java/com/fasterxml/jackson/databind/util/StdDateFormat.java
@@ -564,40 +564,30 @@
int minute = _parse2D(dateStr, 14);
// Seconds are actually optional... so
- int seconds;
+ int seconds = 0;
if ((totalLen > 16) && dateStr.charAt(16) == ':') {
seconds = _parse2D(dateStr, 17);
- } else {
- seconds = 0;
}
cal.set(year, month, day, hour, minute, seconds);
// Optional milliseconds
- start = m.start(1) + 1;
- end = m.end(1);
int msecs = 0;
- if (start >= end) { // no fractional
- cal.set(Calendar.MILLISECOND, 0);
- } else {
- // first char is '.', but rest....
- msecs = 0;
- switch (end-start) {
+ if( m.start(1) != -1 ) {
+ start = m.start(1) + 1;
+ end = m.end(1);
+
+ int millisLen = Math.min(3, end-start);
+ switch (millisLen) {
case 3:
msecs += (dateStr.charAt(start+2) - '0');
case 2:
msecs += 10 * (dateStr.charAt(start+1) - '0');
case 1:
msecs += 100 * (dateStr.charAt(start) - '0');
- break;
- default:
- throw new ParseException(String.format(
-"Cannot parse date \"%s\": invalid fractional seconds '%s'; can use at most 3 digits",
- dateStr, m.group(1).substring(1)
- ),
- pos.getErrorIndex());
}
- cal.set(Calendar.MILLISECOND, msecs);
}
+ cal.set(Calendar.MILLISECOND, msecs);
+
return cal.getTime();
}
formatStr = DATE_FORMAT_STR_ISO8601;
diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/DateDeserializationTZTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/DateDeserializationTZTest.java
index 9f05e94..8018a92 100644
--- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/DateDeserializationTZTest.java
+++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/DateDeserializationTZTest.java
@@ -121,36 +121,27 @@
public void testDateUtilISO8601_DateTimeMillis() throws Exception
{
// WITH timezone (from 4 to 0 digits)
- verify( MAPPER, "2000-01-02T03:04:05.678+01:00", judate(2000, 1, 2, 3, 4, 5, 678, "GMT+1"));
- verify( MAPPER, "2000-01-02T03:04:05.67+01:00", judate(2000, 1, 2, 3, 4, 5, 670, "GMT+1"));
- verify( MAPPER, "2000-01-02T03:04:05.6+01:00", judate(2000, 1, 2, 3, 4, 5, 600, "GMT+1"));
- verify( MAPPER, "2000-01-02T03:04:05+01:00", judate(2000, 1, 2, 3, 4, 5, 000, "GMT+1"));
+ verify( MAPPER, "2000-01-02T03:04:05.6789+01:00", judate(2000, 1, 2, 3, 4, 5, 678, "GMT+1"));
+ verify( MAPPER, "2000-01-02T03:04:05.678+01:00", judate(2000, 1, 2, 3, 4, 5, 678, "GMT+1"));
+ verify( MAPPER, "2000-01-02T03:04:05.67+01:00", judate(2000, 1, 2, 3, 4, 5, 670, "GMT+1"));
+ verify( MAPPER, "2000-01-02T03:04:05.6+01:00", judate(2000, 1, 2, 3, 4, 5, 600, "GMT+1"));
+ verify( MAPPER, "2000-01-02T03:04:05+01:00", judate(2000, 1, 2, 3, 4, 5, 000, "GMT+1"));
-// failure(MAPPER, "2000-01-02T03:04:05.6789+01:00");
-// failure( MAPPER, "2000-01-02T03:04:05.6789Z"); // , judate(2000, 1, 2, 3, 4, 11, 789, "UTC"));
-
// WITH timezone Z (from 4 to 0 digits)
- // FIXME the .6789 millis are interpreted as 6789 millisecondes or 6.789 seconds!
- verify( MAPPER, "2000-01-02T03:04:05.678Z", judate(2000, 1, 2, 3, 4, 5, 678, "UTC"));
- verify( MAPPER, "2000-01-02T03:04:05.67Z", judate(2000, 1, 2, 3, 4, 5, 670, "UTC"));
- // FIXME should be 670 millis instead of 67
- verify( MAPPER, "2000-01-02T03:04:05.6Z", judate(2000, 1, 2, 3, 4, 5, 600, "UTC"));
- // FIXME should be 600 millis instead of 6
- verify( MAPPER, "2000-01-02T03:04:05Z", judate(2000, 1, 2, 3, 4, 5, 0, "UTC"));
+ verify( MAPPER, "2000-01-02T03:04:05.6789Z", judate(2000, 1, 2, 3, 4, 5, 678, "UTC"));
+ verify( MAPPER, "2000-01-02T03:04:05.678Z", judate(2000, 1, 2, 3, 4, 5, 678, "UTC"));
+ verify( MAPPER, "2000-01-02T03:04:05.67Z", judate(2000, 1, 2, 3, 4, 5, 670, "UTC"));
+ verify( MAPPER, "2000-01-02T03:04:05.6Z", judate(2000, 1, 2, 3, 4, 5, 600, "UTC"));
+ verify( MAPPER, "2000-01-02T03:04:05Z", judate(2000, 1, 2, 3, 4, 5, 0, "UTC"));
// WITHOUT timezone (from 4 to 0 digits)
- // FIXME: the .6789 millis are interpreted as 6789 millisecondes or 6.789 seconds!
-
- verify( MAPPER, "2000-01-02T03:04:05.678", judate(2000, 1, 2, 3, 4, 5, 678, LOCAL_TZ));
- verify( MAPPER, "2000-01-02T03:04:05.67", judate(2000, 1, 2, 3, 4, 5, 670, LOCAL_TZ));
- // FIXME: the .67 millis are interpreted as 67 seconds.
-
- verify( MAPPER, "2000-01-02T03:04:05.6", judate(2000, 1, 2, 3, 4, 5, 600, LOCAL_TZ));
- verify( MAPPER, "2000-01-02T03:04:05", judate(2000, 1, 2, 3, 4, 5, 000, LOCAL_TZ));
-
-// failure(MAPPER, "2000-01-02T03:04:05.6789"); // judate(2000, 1, 2, 3, 4, 11, 789, LOCAL_TZ));
+ verify( MAPPER, "2000-01-02T03:04:05.6789", judate(2000, 1, 2, 3, 4, 5, 678, LOCAL_TZ));
+ verify( MAPPER, "2000-01-02T03:04:05.678", judate(2000, 1, 2, 3, 4, 5, 678, LOCAL_TZ));
+ verify( MAPPER, "2000-01-02T03:04:05.67", judate(2000, 1, 2, 3, 4, 5, 670, LOCAL_TZ));
+ verify( MAPPER, "2000-01-02T03:04:05.6", judate(2000, 1, 2, 3, 4, 5, 600, LOCAL_TZ));
+ verify( MAPPER, "2000-01-02T03:04:05", judate(2000, 1, 2, 3, 4, 5, 000, LOCAL_TZ));
// ---------------------------------------------------------------------------------------------
@@ -165,17 +156,16 @@
// time-secfrac = "." 1*DIGIT
// partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
//
- // The second fraction (ie the millis) is optional and can be ommitted. However, a fraction
+ // The second fraction (ie the millis) is optional and can be omitted. However, a fraction
// with only a dot (.) and no digit is not allowed.
//
- // The forms below should be refused but some are accepted by the StdDateFormat. They are
- // included in the test to detect any change in behavior in futur releases...
+ // The forms below are therefore ILLEGAL and must be refused.
// ---------------------------------------------------------------------------------------------
// millis part with only a dot (.) and no digits
- failure( MAPPER, "2000-01-02T03:04:05.+01:00"); // judate(2000, 1, 2, 3, 4, 5, 000, "GMT+1"));
- failure( MAPPER, "2000-01-02T03:04:05."); // judate(2000, 1, 2, 3, 4, 5, 000, LOCAL_TZ));
- failure(MAPPER, "2000-01-02T03:04:05.Z"); // FIXME this one fails, but not the others...
+ failure( MAPPER, "2000-01-02T03:04:05.+01:00");
+ failure( MAPPER, "2000-01-02T03:04:05.");
+ failure( MAPPER, "2000-01-02T03:04:05.Z");
}