From d1a40b4739dc2c2408b1936b4afedaed12ca0ac5 Mon Sep 17 00:00:00 2001 From: Noemi Praml Date: Tue, 31 May 2022 10:47:08 +0200 Subject: [PATCH 1/3] failing test --- .../org/tests/timezone/LocalTimeTest.java | 69 +++++++++++++++++++ .../java/org/tests/timezone/MLocalTime.java | 28 ++++++++ 2 files changed, 97 insertions(+) create mode 100644 ebean-test/src/test/java/org/tests/timezone/LocalTimeTest.java create mode 100644 ebean-test/src/test/java/org/tests/timezone/MLocalTime.java diff --git a/ebean-test/src/test/java/org/tests/timezone/LocalTimeTest.java b/ebean-test/src/test/java/org/tests/timezone/LocalTimeTest.java new file mode 100644 index 000000000..6f5b7e0f9 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/timezone/LocalTimeTest.java @@ -0,0 +1,69 @@ +package org.tests.timezone; + +import io.ebean.Database; +import io.ebean.DatabaseFactory; +import io.ebean.config.DatabaseConfig; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.time.LocalTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class LocalTimeTest { + + protected String platform="h2"; + protected Database db; + + @BeforeAll + public void startTest() { + db = createServer("GMT"); // test uses GMT database + } + + @AfterAll + public void shutdown() { + if (db != null) { + db.find(MLocalTime.class).delete(); + db.shutdown(); + } + } + + /** + * The test checks the write and read of LocalTime values. The database is in GMT time zone. + * In order to verify the test in different java time zones (where the application runs), + * use the -Duser.timezone as JVM argument, + * e.g. -Duser.timezone="America/New_York" or -Duser.timezone="PST"> + * or any other timezone: https://garygregory.wordpress.com/2013/06/18/what-are-the-java-timezone-ids/. + */ + @Test + public void testLocalTime() { + LocalTime lt = LocalTime.of(5, 15, 15); + assertThat(db.find(MLocalTime.class).findCount()).isEqualTo(0); + db.sqlUpdate("insert into mlocal_time (id, local_time) values (1, '05:15:15')").execute(); + + int count = db.find(MLocalTime.class).where().eq("local_time", lt).findCount(); + assertThat(count).isEqualTo(1); + + MLocalTime dbModel = db.find(MLocalTime.class).where().eq("local_time", lt).findOne(); + assertThat(dbModel.getLocalTime().toString()).isEqualTo(lt.toString()); + } + + private Database createServer(String dbTimeZone) { + DatabaseConfig config = new DatabaseConfig(); + config.setName(platform); + config.loadFromProperties(); + config.setDdlExtra(false); + config.setDefaultServer(false); + config.setRegister(false); + config.setChangeLogAsync(false); + config.addClass(MLocalTime.class); + + config.setDumpMetricsOnShutdown(false); + config.setDataTimeZone(dbTimeZone); + + return DatabaseFactory.create(config); + } +} diff --git a/ebean-test/src/test/java/org/tests/timezone/MLocalTime.java b/ebean-test/src/test/java/org/tests/timezone/MLocalTime.java new file mode 100644 index 000000000..4a2d30313 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/timezone/MLocalTime.java @@ -0,0 +1,28 @@ +package org.tests.timezone; + +import javax.annotation.Nullable; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.time.LocalTime; + +@Entity +public class MLocalTime { + + @Id + private Integer id; + + @Nullable + private LocalTime localTime; + + @Nullable + public LocalTime getLocalTime() { + return localTime; + } + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + +} From c8be59fd9553bd1ae14a9eb27357261ae8b0de45 Mon Sep 17 00:00:00 2001 From: Noemi Praml Date: Wed, 25 May 2022 10:20:46 +0200 Subject: [PATCH 2/3] it fixes the test (cherry picked from commit d2e21aa3dcbd4ae59dd8d1ff5404d94c298f087b) --- .../src/main/java/io/ebeaninternal/server/type/DataBind.java | 2 +- .../main/java/io/ebeaninternal/server/type/RsetDataReader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java index 04492de5c..2ef0c6db3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java @@ -178,7 +178,7 @@ public class DataBind implements DataBinder { @Override public final void setTime(Time v) throws SQLException { - Calendar timeZone = dataTimeZone.getTimeZone(); + Calendar timeZone = dataTimeZone.getDateTimeZone(); if (timeZone != null) { pstmt.setTime(++pos, v, timeZone); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java index 6469f8346..4bb1be3ae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java @@ -156,7 +156,7 @@ public class RsetDataReader implements DataReader { @Override public final Time getTime() throws SQLException { - Calendar cal = dataTimeZone.getTimeZone(); + Calendar cal = dataTimeZone.getDateTimeZone(); if (cal != null) { return rset.getTime(pos(), cal); } else { From 9c354919e5c64e1787b6f335601aafcde059570f Mon Sep 17 00:00:00 2001 From: Noemi Praml Date: Wed, 25 May 2022 10:36:52 +0200 Subject: [PATCH 3/3] refactoring (cherry picked from commit 43e28c4f5c747cdda2e3547a8db593eab490ceec) --- .../ebeaninternal/server/core/timezone/DataTimeZone.java | 7 +++---- .../server/core/timezone/MySqlDataTimeZone.java | 2 +- .../main/java/io/ebeaninternal/server/type/DataBind.java | 4 ++-- .../java/io/ebeaninternal/server/type/RsetDataReader.java | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/DataTimeZone.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/DataTimeZone.java index 775e826d1..ff9366802 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/DataTimeZone.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/DataTimeZone.java @@ -13,11 +13,10 @@ public interface DataTimeZone { Calendar getTimeZone(); /** - * Return the Calendar to use for Timezone information when reading/writing date. - * A 'date' only value has normally no timezone information, but some platforms (like MySQL) - * reqire this. + * Return the Calendar to use for Timezone information when reading/writing a time component (date only/time only). + * A time component has normally no timezone information, but some platforms (like MySQL) reqire this. */ - default Calendar getDateTimeZone() { + default Calendar getTimeComponentTimeZone() { return null; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/MySqlDataTimeZone.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/MySqlDataTimeZone.java index 85ceab500..102fcd88f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/MySqlDataTimeZone.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/timezone/MySqlDataTimeZone.java @@ -19,7 +19,7 @@ public class MySqlDataTimeZone implements DataTimeZone { } @Override - public Calendar getDateTimeZone() { + public Calendar getTimeComponentTimeZone() { return zone; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java index 2ef0c6db3..ab17244e4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java @@ -158,7 +158,7 @@ public class DataBind implements DataBinder { @Override public final void setDate(java.sql.Date v) throws SQLException { - Calendar timeZone = dataTimeZone.getDateTimeZone(); + Calendar timeZone = dataTimeZone.getTimeComponentTimeZone(); if (timeZone != null) { pstmt.setDate(++pos, v, timeZone); } else { @@ -178,7 +178,7 @@ public class DataBind implements DataBinder { @Override public final void setTime(Time v) throws SQLException { - Calendar timeZone = dataTimeZone.getDateTimeZone(); + Calendar timeZone = dataTimeZone.getTimeComponentTimeZone(); if (timeZone != null) { pstmt.setTime(++pos, v, timeZone); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java index 4bb1be3ae..5bf529d77 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java @@ -107,7 +107,7 @@ public class RsetDataReader implements DataReader { @Override public final Date getDate() throws SQLException { - Calendar cal = dataTimeZone.getDateTimeZone(); + Calendar cal = dataTimeZone.getTimeComponentTimeZone(); if (cal != null) { return rset.getDate(pos(), cal); } else { @@ -156,7 +156,7 @@ public class RsetDataReader implements DataReader { @Override public final Time getTime() throws SQLException { - Calendar cal = dataTimeZone.getDateTimeZone(); + Calendar cal = dataTimeZone.getTimeComponentTimeZone(); if (cal != null) { return rset.getTime(pos(), cal); } else {