ISO8601 format in serialized dates might not be ECMAScript-compatible
See original GitHub issueAs of jackson-databind::2.6.3
, a java.util.Calendar
or a java.util.Date
object is serialized in non-timestamp format (i.e. after disabling SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
) in ISO8601 format and normalized to UTC, which is fine. For example:
"2013-01-01T13:30:00.000+0000"
The problem is, I’m not really sure this is compatible with the ECMAScript standard, version 6.0 (and older). If we have a look at section 20.3.1.16: Date Time String Format (see http://ecma-international.org/ecma-262/6.0/#sec-date-time-string-format ), it literally says:
ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
So it doesn’t seem the entire ISO8601 is supported, but only a simplification. Which shows when the Z
in the format above is explained as:
Z is the time zone offset specified as “Z” (for UTC) or either “+” or “-” followed by a time expression HH:mm
In my understanding, that might mean the date above, as serialized by Jackson, would not be ECMAScript-valid due to the lack of a colon symbol (:
), even if it is ISO8601-valid indeed.
For being valid it would have to be expressed as any of the following two possibilities:
"2013-01-01T13:30:00.000Z"
"2013-01-01T13:30:00.000+00:00"
This comes from the use at https://github.com/FasterXML/jackson-databind/blob/20a67f73f362bce0d0d93afacec12d30796affa8/src/main/java/com/fasterxml/jackson/databind/util/StdDateFormat.java#L34 of the following date pattern:
protected final static String DATE_FORMAT_STR_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
But the problem is that, as stated at the javadoc for java.text.SimpleDateFormat
(see http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html ), the Z
format modifier is for RFC822 format, which is why Java 7 introduced the X
modified for ISO8601.
So in Java 7 this should look like:
protected final static String DATE_FORMAT_STR_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
Nevertheless, Jackson 2.6 should still support Java 6, so the transformation (adding the :
) needs to be done manually 😦
As for why bother doing this… the JSON specification itself does obviously not say anything about dates, because they are not one of the possible types of JSON values. But being the JSON specification so profoundly related to that of ECMAScript from which it borrowed a large part of its syntax, it makes sense to me that date literals are specified in JSON serializations in an ECMAScript-compatible way, at least by default.
Finally, issue #919 seems related to this topic, though deserialization-oriented.
Issue Analytics
- State:
- Created 8 years ago
- Comments:13 (8 by maintainers)
Top GitHub Comments
@cowtowncoder actually I have no observed issues to report 😃. As I explained in my message to
jackson-dev
, I noticed this while performing the changes needed for Thymeleaf to adopt Jackson as its default JavaScript serialization strategy for Thymeleaf 3.0.We already had a custom-made JavaScript/JSON serialization mechanism in place in previous versions, which we will keep in 3.0 as a fallback in case users don’t want to add Jackson to their apps for some reason, and our intention is to make both mechanisms produce equivalent output for simple values (text literals, numerals, dates…)
And while doing this, we found that the format in which dates were output using our mechanism didn’t match Jackson’s output, which made some of our existing tests fail. Anyway, we are providing a default
DateFormat
configuration for Jackson in Thymeleaf 3.0 which enables this ECMAScript compatibility, so it’s not really a problem for us right now.Just a discrepancy with the specs, nothing else 😃
Fwtw, I filed this:
https://github.com/FasterXML/jackson3-dev/issues/7
to change Jackson 3.0 default serialization.