0

@Entity
@Table(name="friend")
public class Friend {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="name")
    private String name;

    @Column(name="birthday")
    private Date birthday;

    public Date getBirthday() {
        System.out.println("getter" + this.birthday);
        return this.birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

I am using java.sql.Date here to insert a birthday into my MySQL db. For the setter, I get the Date as a String in the form yyyy-MM-dd from a jsp page using form tags and model attributes. After setting, I checked my db table and the date is as expected, but when I call the getter, the date is one day earlier (e.g. If i have 2000-06-20 in my db, the getter returns 2000-06-19).

sonique
  • 4,539
  • 2
  • 30
  • 39
  • 3
    There's a reasonable chance that time zones are the issue and that what's logged in the `System.out.println` is different to local date time as rendered in the client. There's 3 possible timezones in play: the MySQL Server. the server running the Java and the client rendering the date. Usually servers (database and application server) are in UTC. You could have a decent read of the Joda Time library. – GregHNZ Jun 15 '20 at 08:36
  • 3
    @GregHNZ is right but you don't have to use JodaTime anymore as since Java 8 there is the Java DateTime API and you can use LocalDate instead of java.sql.Date. But this my not solve your problem. – Simon Martinelli Jun 15 '20 at 08:51
  • This issue is very likely a duplicate of ["date goes back one day"](https://stackoverflow.com/questions/47698294/getting-the-date-goes-back-one-day) – Nowhere Man Jun 15 '20 at 09:14
  • Does this answer your question? [Getting the date goes back one day](https://stackoverflow.com/questions/47698294/getting-the-date-goes-back-one-day) – OrangeDog Jun 15 '20 at 10:05

2 Answers2

3

Wrong data type

Never use java.util.Date nor java.sql.Date classes. These classes were terribly designed, and were supplanted years ago by the modern java.time classes defined in JSR 310.

And by the way, never write code that depends implicitly on some default time zone. That puts control of your results outside your hands as a programmer.

LocalDate

To represent a date only, without a time-of-day, and without the context of a time zone or offset-from-UTC, use LocalDate.

LocalDate localDate = LocalDate.parse( "2000-06-20" ) ;  // Parses standard ISO 8601 format by default.

Exchanging LocalDate objects with your database

Store a date-only value in a database column of a type akin to the SQL standard type DATE. Note that various databases vary widely in their date-time handling and naming, so study your documentation closely. In MySQL 8 specifically, use its DATE type.

Write to database.

myPreparedStatement.setObject( … , localDate );

Retrieve from database.

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

If you following this approach, default time zones will be irrelevant. Your results will be consistent.

Hibernate & JPA support java.time

As for your use of Hibernate, both Hibernate and JPA were both updated years ago to support java.time. Be sure your JDBC driver complies with JDBC 4.2 or later.

Searches: Hibernate & java.time, and JPA & java.time


Table of date-time types in Java (both legacy and modern) and in standard SQL


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

I had serverTimezone=UTC at the end of my jdbc url, and removing it seems to have fixed the problem. My database server and my Tomcat server seem to be using my local timezone.