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

Change default Date serialization to ISO 8601 format #2472

Open
Marcono1234 opened this issue Aug 17, 2023 · 1 comment
Open

Change default Date serialization to ISO 8601 format #2472

Marcono1234 opened this issue Aug 17, 2023 · 1 comment

Comments

@Marcono1234
Copy link
Collaborator

Problem solved by the feature

The current default java.util.Date serialization uses DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US) (source line), which produces output like the following:

"Jan 1, 1970, 1:00:00 AM"

The problem is that this is a locale dependent format intended to be human-readable, and not necessarily to be parsed by computers. The formatting is also dependent on the CLDR data, which changes between Java versions. This has happened for Java 9 already (#1210), and possibly again for Java 20 respectively also older versions using updated CLDR data (#2450 (comment), and JDK-8304925).

This leads to backward compatibility issues (#1682), and makes this format unsuitable for transferring data to other applications or services. However, users might not even be aware of these pitfalls until they encounter the issues when switching Java versions.

Related issues:

Feature description

  • Change the default serialization format for java.util.Date, java.sql.Date, java.sql.Timestamp and java.sql.Time to use ISO 8601 format
    For this can probably either construct a SimpleDateFormat with Locale.ROOT which matches the ISO 8601 format (in case that is possible), or use the existing internal Gson class ISO8601Utils.
  • Deprecate GsonBuilder methods setDateFormat(int) and setDateFormat(int, int)
    Because they encourage serializing using a non-stable format. The deprecation message for setDateFormat(int, int) could show how a user can write their own TypeAdapter if they really need this date formatting. setDateFormat(String) would not have to be marked as deprecated because the provided format might be stable and independent of locale settings and CLDR data (I hope).

The existing Date deserialization logic already has multiple fallbacks in case parsing fails, including ISO8601Utils, so that might work without issues.

Optional changes:

  • Change the deserialization logic to try ISO 8601 deserialization first, and only if that fails fall back to the other SimpleDateFormat patterns. That might yield better performance.

Risks:

  • In some cases applications might be directly displaying the date value to the user, and therefore a human readable format is appreciated
    However, serialization always use the US locale, and especially on Android that might not be desired since you want to match the device locale; so it is questionable how many applications actually rely on this.
  • The ISO 8601 code (either existing one in Gson, or new one we write) could be faulty; this can cause interoperability issues with other libraries and if we need to fix it in future Gson version, that could be a backward incompatible change
  • If a SimpleDateFormat is used for ISO 8601 serialization (instead of ISO8601Utils), care must be taken that it is not accidentally still dependent on any system settings (locale, timezone, ...) or on the CLDR data

(Note that this is really only a feature request for now; this is not something which has been agreed upon as future Gson change.)

Alternatives

  • Change the Date adapter to mimic (or rather duplicate) the US locale default formatting of a certain Java version, without relying (implicitly) on CLDR data, so the pattern remains stable.
    The main problem is that this is probably not feasible, or worth the effort.

Workarounds

Users can either specify a custom date format using GsonBuilder.setDateFormat(String), or register a custom type adapter for Date to work around these issues.

@ckadigkos
Copy link

Hello, Is there any plan someone to work on this ticket anytime soon?

We encountered an issue with the date serialization/deserialization when we mix systems that run on java-8 and java-11 because we rely on the default date format and this is different between version 8 and 9+ of java.
Of course we have consider using a custom date formatter but this is a very big change in our system since it's used in almost all of our codebase.

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

No branches or pull requests

2 participants