Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISO8601DateFormat is deprecated but replacement is unclear. #1786

Closed
huxi opened this issue Oct 5, 2017 · 11 comments
Closed

ISO8601DateFormat is deprecated but replacement is unclear. #1786

huxi opened this issue Oct 5, 2017 · 11 comments

Comments

@huxi
Copy link

huxi commented Oct 5, 2017

com.fasterxml.jackson.databind.util.ISO8601DateFormat is deprecated since 2.9 but I couldn't find any information about how to replace its current usage while upgrading.

So far, I checked the following locations:

But no luck...

I suspect that I could probably just delete objectMapper.setDateFormat(new ISO8601DateFormat()); and be fine but I wanted to double-check.

So this is a bug report against the documentation, not the code. If it can be safely removed and dates are still serialized as ISO-8601 strings then this should be mentioned somewhere.

@cowtowncoder
Copy link
Member

Correct: StdDateFormat has been used everywhere at least with 2.8 (I did not see where it would have been used originally), and it is the default formatter/parser.
And it supports (one of many) ISO-8601 format, one that JDK date/time types have supported.

You are correct in that you should just remove that setDateFormat() call: StdDateFormat is used by default.

I'll see if I can find more information on last Jackson version that actually used ISO8601DateFormat.
If I had realized its lack of use earlier, I'd have first deprecated it in 2.8; but due to big rewrite of ISO-8601 handling, lack of direct use, I assumed (... incorrectly it seems) that no one was using it.

@cowtowncoder
Copy link
Member

Ok. So, the class has been include since 2.0 at least (Jackson moved to github at that version), but was never actually used by rest of databind code. I do not recall its history: I do not usually include utility classes that are not bound or accessed by API. It is possible this might have been due to refactoring since 1.9.

If there is any documentation that suggest use of this class I would want to update it.

@huxi
Copy link
Author

huxi commented Oct 5, 2017

I can't tell you where I originally found a reference to that class but I'm 100% sure it dates back to 2010 or 2011. From there it was copy-pasted to every new ObjectMapper configuration because "Of course we want ISO-8601". ¯\(ツ)

No problem at all, I just wanted to check back before removing it all over the code base.

Thanks for the fast reply!

@cowtowncoder
Copy link
Member

@huxi lol. Yes, apologies for breaking change here -- I can totally see why it would make sense from user perspective, esp. considering that documentation has always been bit sparse.

So: yes, this mysterious class is gone and should not be needed.

@rferreira
Copy link

For posterity, here's an example of serializing to iso8601 without the ISO8601DateFormat class from the jackson tests themselves:

mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

@dmitrygusev
Copy link

dmitrygusev commented Oct 30, 2018

Looks like default StdDateFormat doesn't format date-time the same as ISO8601DateFormat.

I found this while integrating with a 3rd party API which uses Swagger spec.
In Swagger they have a date-time data type:

date-time – the date-time notation as defined by RFC 3339, section 5.6, for example, 2017-07-21T17:32:28Z

According to the RFC the timezone information must follow this BNF:

   time-numoffset  = ("+" / "-") time-hour ":" time-minute
   time-offset     = "Z" / time-numoffset
...
   full-time       = partial-time time-offset

Notice the ":" in time-numoffset is not optional, but default StdDateFormat is omitting it, so Swagger implementations will refuse such dates.

Not sure if that's an issue in RFC or Swagger, but I cannot really use the default StdDateFormat. With ISO8601DateFormat everything works as expected, but as I understand the class is deprecated for removal.

@rhwood
Copy link

rhwood commented Mar 20, 2019

Migrating from Jackson 2.8.11 to 2.9.8, and am finding that for a given date, StdDateFormat.format(date) returns 2019-03-20T21:56:29.533+0000 while ISO8601DateFormat(date) returns 2019-03-20T21:56:29Z. How do I force the ISO8601DateFormat behavior when using StdDateFormat?

Note that the format returned by ISO8601DateFormat is listed as the default in the JavaDocs.

@cowtowncoder
Copy link
Member

@rhwood
So, the way to customize formatting of output is either by overriding DateFormat used:

ObjectMapper.setDateFormat()

and defining (for example) properly configured SimpleDateFormat of your choice, or by specifying format String for type(s) you want it to apply:

    mapper.configOverride(Date.class)
            .setFormat(JsonFormat.Value.forPattern("yyyy.dd.MM"));

in which case a SimpleDateFormat is constructed with the format String (in case of "old" JDK types), or, with Joda and Java 8 date/time, using their formatter equivalents.

StdDateFormat has limited configurability itself, and is not meant to be directly configured; for output it supports specific format indicated (javadoc should of course include correct information, I'll update that for 2.10 javadocs).

@cowtowncoder
Copy link
Member

@dmitrygusev There is addition of StdDateFormat.withColonInTimeZone(boolean) (see #1744) that will be in 2.10 (and was actually included in 2.9.1, which is against typical versioning constraints -- added since it was deemed critical problem for some users).
So it is possible to force inclusion of colon in timezone, to work with systems that mandate it. Note that JDK itself has had different versions in this regard so discrepancies have backwards compatibility root.

@cowtowncoder
Copy link
Member

Ok, so Javadoc might be correct I think, although it may be misleading: it states that "Format String" looks like yyyy-MM-dd'T'HH:mm:ss.SSSZ, where Z refers to offset without colons, as per:

https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html

@slonopotamus
Copy link

slonopotamus commented May 21, 2019

I also found that StdDateFormat cannot be used as is in place of ISO8601DateFormat because Go cannot parse StdDateFormat output. To be exact, Go doesn't support parsing timezone offset without colon. Using withColonInTimeZone(true) fixes the issue.

It is because in section 5.6. Internet Date/Time Format of RFC 3339 colon is not optional:

time-numoffset = ("+" / "-") time-hour ":" time-minute

So, while both variants (with and without colon) are valid ISO-8601, using colon improves interoperability with other software that doesn't implement full ISO-8601 spec but only a subset recommended by RFC 3339 for internet communication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants