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

Support for java.time.Instant #163

Closed
lukasj opened this issue Oct 18, 2017 · 8 comments · Fixed by #434
Closed

Support for java.time.Instant #163

lukasj opened this issue Oct 18, 2017 · 8 comments · Fixed by #434
Projects

Comments

@lukasj
Copy link
Contributor

lukasj commented Oct 18, 2017

Original issue #63 mentioned support for java.time.Instant but it's missing in the final 2.2 spec. I haven't found any reason for omitting it.

I feel it's important for supporting pure UTC data flow as described in the #156. Instant already stores epoch internally so it cleanly maps to a UTC timestamp and it would simplify such use case rather than converting back and forth between different (application, database, user) time zones.

I believe that Instant as a machine-timeline view should be the recommended approach for persisting time data over LocalDateTime, OffsetDateTime, ZonedDateTime which are human-timeline views.

Hibernate supports Instant just fine already and allows changing the database timezone via hibernate.jdbc.time_zone.

@lukasj
Copy link
Contributor Author

lukasj commented Jan 24, 2018

@ghost Commented
Of all the java.time types, it is Instant that is designed exactly to represent a point in time, so it should be supported. It is also the only type that is suitable for conversion from and to java.sql.Timestamp. Of the newly supported types LocalDate, LocalTime, LocalDateTime, OffsetTime and OffsetDateTime, only the latter actually represents a point in time, but cannot be created from a Timestamp alone (the offset is missing).

So if you want to persist a point of time with JPA 2.2, the following options appear to me:

  • Use java.util.Date
  • Use OffsetDateTime, but this forces you to choose an offset for all your values. You can use ZoneOffset.UTC for all, basically reducing OffsetDateTime to an Instant. Also, not all popular database systems support persisting an offset along the timestamp value, so you might need to use @javax.persistence.TemporalTimeZoneColumn, scattering the value among two columns.
  • Use Instant and an AttributeConverter, as you already could do before JPA 2.2

Supporting Instant sounds preferable to each of these.

@lukasj
Copy link
Contributor Author

lukasj commented Aug 31, 2018

@psyklopz
Copy link

psyklopz commented Dec 6, 2018

For others wishing Instants were supported directly, here is my code to support it using an AttributeConverter, as recommended as a stopgap by @lukasj above.
`package Repository;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Timestamp;
import java.time.Instant;

@converter(autoApply = true)
public class InstantAttributeConverter implements AttributeConverter<Instant, Timestamp> {

@Override
public Timestamp convertToDatabaseColumn(Instant instant) {
    if (instant == null)
        return null;
    else
    {
        Timestamp t = Timestamp.from(instant);
        return t;
    }
}

@Override
public Instant convertToEntityAttribute(Timestamp timestamp) {
    //System.out.println(timestamp + " " + timestamp.toInstant() + " " + timestamp.getTimezoneOffset());
    return (timestamp == null ? null : timestamp.toInstant());
}

}`

@sergeykad
Copy link

@psyklopz Unfortunately this approach does not work correctly with all databases. On Microsoft SQL Server for example you will get local time instead of UTC.

@psyklopz
Copy link

psyklopz commented Dec 8, 2018

@sergeykad Great point. By convention all our servers are set to UTC. When running on a local dev machine, we pass the time zone (UTC) as part of our connection string to the MySQL JDBC driver.

Maybe I worry more than I should, but I don't trust that time zone conversions done in Java are always consistent with those done in the database.

I also get uncomfortable that converting from UTC to local and back to UTC is not foolproof. In the hour before (or after) daylight savings we have a wrinkle in time.

I wish databases had no concept of time zones. That belongs in the presentation layer and not in the business layers. But I digress...

Use my sample code if and only if your database and your Java code are both running in UTC.

@sharmasourabh
Copy link

I am in favor of adding support for Instant to JPA specs.

@gavinking
Copy link
Contributor

@lukasj I agree that we should totally do this.

@gavinking
Copy link
Contributor

I've proposed support for Instant and Year in #434.

Note that it's clear why Instant was left out of previous revisions of JPA: the JDBC spec does not mention it in Appendix B. But in fact there are other missing type mappings in the JDBC spec, so what I've done is also nailed down the missing type mappings.

gavinking added a commit to gavinking/jpa-api that referenced this issue Aug 10, 2023
@lukasj lukasj added this to To do in 3.2.0 via automation Aug 10, 2023
3.2.0 automation moved this from To do to Done Aug 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
3.2.0
Done
Development

Successfully merging a pull request may close this issue.

5 participants