Reputation: 151
I had a class in Java (Spring) and one of the variables was type Date (called fnac, which stores a birthdate, so I don't need hours!)
These were their set and get methods:
public String getFnac() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
format.setTimeZone(TimeZone.getTimeZone("UTC+2"));
return format.format(this.fnac);
}
public void setFnac(String fnac) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
format.setTimeZone(TimeZone.getTimeZone("UTC+2"));
this.fnac = format.parse(fnac);
}
I've decided to use LocalDate, as everyone seems to say that it's newer and better, and... I would like to addapt the setter and getter to LocalDate
@Column(name = "FNAC")
private LocalDate fnac;
I've been trying and searching for hours but I couldn't addapt it to LocalDate yet.. Here are my last try:
public void setFnac(String fnac) throws ParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
ZonedDateTime zdt = ZonedDateTime.parse(fnac, formatter.withZone(ZoneId.systemDefault()));
this.fnac = zdt.toLocalDate();
}
public String getFnac() {
Instant now = Instant.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
ZonedDateTime zdt = now.atZone(ZoneId.systemDefault());
return zdt.format(formatter).toString();
}
(I may have anything right in the setter, but... I'm sorry you have to read such a disaster getter...)
PD: Yes, I have LocalDate persisted with this: https://thoughts-on-java.org/persist-localdate-localdatetime-jpa/
With only this code it will store dates "sucessfully":
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
But seems that I need to work with time-zones because... when I save a date in the database, it will save the previous day (because it seems to save with dd/mm/yyyy at 00:00 UTC+0), so if I set a birthdate as 07/10/2015 it will save 06/10/2015. I don't even understand why LocalDate is even saving an hour. I'm using LocalDate for a reason, not LocalDateTime. I only want Dates, but the times keep pursuiting me!
I'm UTC+2 (but I think it doesn't makes sense to store UTC+2 because the next week we will be UTC+1), so I think it would be ZoneId.of("Europe/Madrid") (I suposse then that it will change the hour automatically when the time zones changes).
I hope you can help me! (I'm sorry for my english, it's not perfect). Thank you!
Upvotes: 1
Views: 5439
Reputation: 183
As you don't require time then you need to use the only LocalDate.
public void setFnac(String fnac) {
this.fnac = LocalDate.parse(fnac, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
No need to use ZonedDateTime for this. Hope this wil help.
Upvotes: 0
Reputation: 151
I had to change this line in application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/...........&serverTimezone=UTC
to this line:
spring.datasource.url=jdbc:mysql://localhost:3306/...........&serverTimezone=Europe/Madrid
I tried before with UTC+2, but it didn't exist
Changing that config and the answer of Ole V.V. worked for me
Thank you!
Upvotes: 1
Reputation: 86276
LocalDate.parse
This is a lot easier than you seem to think.
public void setFnac(String fnac) {
this.fnac = LocalDate.parse(fnac);
}
public String getFnac() {
return fnac.toString();
}
I am exploiting the fact that your strings are in ISO 8601 format, the default format for the classes of java.time, the modern Java date and time API. So LocalDate
parses this format without any explicit formatter, and also returns it from its toString
method.
Just forget everything about the old Date
and SimpleDateFormat
classes. java.time can do it all for you. And also don’t worry about time zone because a LocalDate
hasn’t got any. If the date is saved incorrectly to the database, there’s a bug somewhere in the software doing that or its configuration/setup that you need to pursue.
Link: Wikipedia article: ISO 8601
Upvotes: 3
Reputation: 2935
The database you are currently using doesn't have the concept of LocalDate
and when you convert the LocalDate
to the normal Date
class, it carries along the hours an minutes set to midnight 00:00
Then when the database stores the object in the database it will save the date and add the servers timezone offset to it.
Here is an example of converting a LocalDate
to Date
LocalDate date = LocalDate.now();
System.out.println("From LocalDate: " + date);
Date d = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("From Date" + d);
Output:
From LocalDate: 2019-10-23
Form Date: Wed Oct 23 00:00:00 UTC 2019
As you can see the timezone is still stored in the date even though there was no time stored in your LocalDate. This is essentially what your conversion is doing.
The easiest way to remediate the timezone problem would be to store the date as a string in your desired format then convert as needed. This will be consistent regardless of what timezone your server is on and where you are located.
Upvotes: 2