Sandrituky
Sandrituky

Reputation: 151

Parsing LocalDate to String in getter and setter methods

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

Answers (4)

viren shah
viren shah

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

Sandrituky
Sandrituky

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

Anonymous
Anonymous

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

locus2k
locus2k

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

Related Questions