I have a SpringBoot app. using Spring Initializer, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.
I have a domain object with 2 properties (initDate, endDate). I want to create 2 converters to deal with mySQL DB
@Convert(converter = LocalDateTimeAttributeConverter.class)
private LocalDateTime initDate;
@Convert(converter = ZonedDateTimeAttributeConverter.class)
private ZonedDateTime endDate;
the converter 1 (is OK)
@Converter
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime localDateTime) {
return (localDateTime == null ? null : Timestamp.valueOf(localDateTime));
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
}
}
This is the one that I want to create
@Converter
public class ZonedDateTimeAttributeConverter implements AttributeConverter<ZonedDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(ZonedDateTime zoneDateTime) {
return (zoneDateTime == null ? null : Timestamp.valueOf(zoneDateTime));
}
@Override
public ZonedDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toZonedDateTime());
}
}
But I can't because I have 2 errors:
The method valueOf(String) in the type Timestamp is not applicable for the arguments (ZonedDateTime)
and the TimeStamp does not have the method toZonedDateTime()
and if I don't add any converter for the ZonedDate, JPA creates a table with the type varbinary(255)
Instant – represents a point in time (timestamp) LocalDate – represents a date (year, month, day) LocalDateTime – same as LocalDate, but includes time with nanosecond precision.
A LocalDateTime instance represents a point in the local timeline. It cannot represent an instant on the universal timeline without additional information such as an offset or time zone. A ZonedDateTime instance represents an instant in the universal timeline. It is the combination of date, time and zone information.
now() now() method of a ZonedDateTime class used to obtain the current date-time from the system clock in the default time-zone. This method will return ZonedDateTime based on system clock with default time-zone to obtain the current date-time.
public static ZonedDateTime now() Obtains the current date-time from the system clock in the default time-zone. This will query the system clock in the default time-zone to obtain the current date-time. The zone and offset will be set based on the time-zone in the clock.
Timestamp extends Date
to provide nanosecond accuracy. Neither Date
nor Timestamp
are designed to refer to a specific timezone as ZoneDateTime
.
If you need to convert ZonedDateTime
-> Timestamp
you will have to discard the timezone/offset information. E.g.
LocalDateTime withoutTimezone = zoneDateTime.toLocalDateTime();
Timestamp timestamp = Timestamp.valueOf(withoutTimezone));
and for converting Timestamp
-> ZonedDateTime
you need to specify an offset:
LocalDateTime withoutTimezone = sqlTimestamp.toLocalDateTime();
ZonedDateTime withTimezone = withoutTimezone.atZone(ZoneId.of("+03:00"));
or timezone:
ZonedDateTime withTimezone = withoutTimezone.atZone(ZoneId.of("Europe/Paris"));
If your intention is to save ZonedDateTime
variables in the database and preserve the various timezones specified there, I recommend designing your database accordingly. Suggestions:
DATETIME
to save a LocalDateTime
and a VARCHAR
saving a timezone like "Europe/Paris"
or a SMALLINT
saving an offset in minutes.ZonedDateTime
to a String
and save in a VARCHAR
column like "2017-05-16T14:12:48.983682+01:00[Europe/London]"
. You'll then have to parse it when reading from the database.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With