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

OffsetDateTime & ZonedDateTime: the dateTime field should CONVERT to UTC, and not store LocalDate with a "Z" appended #6

Open
slaout opened this issue Mar 2, 2022 · 0 comments

Comments

@slaout
Copy link

slaout commented Mar 2, 2022

Hello,

First, thanks for this wonderful library!

I'd like to configure its data-representations to be as close as possible as the original processing done by MongoBD, and as compact as possible.

Here is my configuration:

@Singleton
public class Jsr310AdditionalCodecsProvider implements CodecProvider {
    // As date objects to be able to compare them and have an ISO and smaller representation
    private static final LocalDateTimeCodec LOCAL_DATE_TIME_CODEC = new LocalDateTimeCodec();

    // As strings to have an ISO and smaller representation
    private static final ZoneOffsetAsStringCodec ZONE_OFFSET_CODEC = new ZoneOffsetAsStringCodec();

    // As strings to have a smaller representation
    private static final ZoneIdAsStringCodec ZONE_ID_CODEC = new ZoneIdAsStringCodec();

    @Override
    public <T> Codec<T> get(Class<T> clazz, CodecRegistry registry) {
        if (clazz.equals(ZonedDateTime.class)) {
            return (Codec<T>) new ZonedDateTimeAsDocumentCodec(LOCAL_DATE_TIME_CODEC, ZONE_OFFSET_CODEC, ZONE_ID_CODEC);
        } else if (clazz.equals(OffsetDateTime.class)) {
            return (Codec<T>) new OffsetDateTimeAsDocumentCodec(LOCAL_DATE_TIME_CODEC, ZONE_OFFSET_CODEC);
        } else if (clazz.equals(ZoneOffset.class)) {
            return (Codec<T>) ZONE_OFFSET_CODEC;
        } else if (clazz.equals(ZoneId.class)) {
            return (Codec<T>) ZONE_ID_CODEC;
        }
        return null; // Other default codecs are fine to us
    }
}

The goal is to store OffsetDateTime & ZonedDateTime as close as possible as the default MongoDB codecs: as $date fields to be able to compare them, with just one or two additional fields to be able to restore the original offset, lost with the default MongoDB converter, as well as the original zone, non-standard, and thus also lost.

Unfortunately, the dateTime fields are stored as LocalDate with a "Z" appended, making the date objects not comparable.

Example of stored document: the two OffsetDateTimes are at the same moment, created on my machine that is currently GMT+1 (will be GMT+2 in 6 months when DST kicks in):

{
  "offsetDateTime": {
    "dateTime": { "$date": "2022-03-02T15:15:44.555Z" },
    "offset": "+01:00"
  },
  "offsetDateTime2": {
    "dateTime": { "$date": "2022-03-02T16:15:44.555Z" },
    "offset": "+02:00"
  }
}

So, as long as you create documents on the same machine, or on machines with the same offset AND that do not honor Daylight Saving Time, then the created dates are comparable.

That's a lot of ifs :)

And semantically speaking, if we store a "Z"-date in database, we expect it to be UTC, like MongoDB does by default.

We would also expect Instant.parse(offsetDateTime2.dateTime).atOffset(ZoneOffset.of(offsetDateTime2.zone)) to restore the original OffsetDateTime: it currently does not.

I'd like both fields above to have theirs dateTime to "$date": "2022-03-02T14:15:44.555Z".

Did I use the library wrong? Is there a possible way to do this?

If not, is it possible to create alternate ZonedDateTimeAsDocumentCodec & OffsetDateTimeAsDocumentCodec classes that do not use a LocalDateTimeCodec or that convert them to UTC first?

Thanks a lot.

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

1 participant