From 78e74570dc6a78ac802fe37a3aa07ef8a5be2d01 Mon Sep 17 00:00:00 2001 From: Mark Rotteveel Date: Sat, 9 Mar 2024 14:28:12 +0100 Subject: [PATCH] #786 Convert Java offset names to Firebird offset names --- src/docs/asciidoc/release_notes.adoc | 1 + .../gds/ng/FbConnectionProperties.java | 13 +-------- .../props/DatabaseConnectionProperties.java | 27 +++++++++++++++++-- .../gds/ng/FbConnectionPropertiesTest.java | 9 ++++++- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/docs/asciidoc/release_notes.adoc b/src/docs/asciidoc/release_notes.adoc index ecebcc30d..65e3c3440 100644 --- a/src/docs/asciidoc/release_notes.adoc +++ b/src/docs/asciidoc/release_notes.adoc @@ -927,6 +927,7 @@ We do not plan to remove this API at this time, but we recommend that you switch * Fixed: Use of offset timezone names (e.g. `+05:00`) for `sessionTimeZone` would result in a warning being logged, and an incorrect conversion applied (in UTC instead of the offset) when using the legacy time types (https://github.com/FirebirdSQL/jaybird/issues/786[#786]) + This change was also backported to Jaybird 5.0.4. +* Improvement: `sessionTimeZone` now also accepts the Java offset names (`GMT[{plus}-]HH:MM`), which will be automatically converted to the Firebird compatible name (`[{plus}-]HH:MM`). [#potentially-breaking-changes] === Potentially breaking changes diff --git a/src/main/org/firebirdsql/gds/ng/FbConnectionProperties.java b/src/main/org/firebirdsql/gds/ng/FbConnectionProperties.java index 0834f7de0..e9b85933b 100644 --- a/src/main/org/firebirdsql/gds/ng/FbConnectionProperties.java +++ b/src/main/org/firebirdsql/gds/ng/FbConnectionProperties.java @@ -30,8 +30,6 @@ import java.util.HashMap; import java.util.Map; import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Mutable implementation of {@link IConnectionProperties} @@ -43,8 +41,6 @@ public final class FbConnectionProperties extends AbstractAttachProperties implements IConnectionProperties, Serializable { - private static final Pattern GMT_WITH_OFFSET = Pattern.compile("^GMT([+-]\\d{2}:\\d{2})$"); - @SuppressWarnings("java:S1948") private FbImmutableConnectionProperties immutableConnectionPropertiesCache; @@ -98,14 +94,7 @@ protected Object resolveStoredDefaultValue(ConnectionProperty property) { } private static String defaultTimeZone() { - String timeZone = TimeZone.getDefault().getID(); - if (timeZone.startsWith("GMT") && timeZone.length() > 3) { - Matcher matcher = GMT_WITH_OFFSET.matcher(timeZone); - if (matcher.matches()) { - return matcher.group(1); - } - } - return timeZone; + return TimeZone.getDefault().getID(); } @Override diff --git a/src/main/org/firebirdsql/jaybird/props/DatabaseConnectionProperties.java b/src/main/org/firebirdsql/jaybird/props/DatabaseConnectionProperties.java index 2928a318a..15d48e7a1 100644 --- a/src/main/org/firebirdsql/jaybird/props/DatabaseConnectionProperties.java +++ b/src/main/org/firebirdsql/jaybird/props/DatabaseConnectionProperties.java @@ -27,6 +27,8 @@ import org.firebirdsql.jdbc.FirebirdCallableStatement; import java.sql.DatabaseMetaData; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Properties for database connections. @@ -190,11 +192,32 @@ default String getSessionTimeZone() { * * @param sessionTimeZone * Firebird 4+ session time zone name (we strongly suggest to use Java compatible names only), - * use {@code "server"} to use server default time zone (note: conversion will use JVM default time zone) + * use {@code "server"} to use server default time zone (note: conversion will use JVM default time zone). + * For offset-based names, the value will be normalized to the Firebird name (e.g. GMT+05:00 is stored as + * +05:00). * @since 4.0 */ default void setSessionTimeZone(String sessionTimeZone) { - setProperty(PropertyNames.sessionTimeZone, sessionTimeZone); + setProperty(PropertyNames.sessionTimeZone, normalizeTimeZone(sessionTimeZone)); + } + + /** + * Normalizes timezone name, specifically converts Java's {@code GMT[+-]HH:MM} to Firebird's {@code [+-]HH:MM}. + * + * @param timeZone timezone name + * @return original or modified timezone name + */ + private static String normalizeTimeZone(String timeZone) { + @SuppressWarnings("java:S1118") + final class Holder { + static final Pattern GMT_WITH_OFFSET = Pattern.compile("^GMT([+-]\\d{2}:\\d{2})$"); + } + if (timeZone == null) return null; + Matcher matcher = Holder.GMT_WITH_OFFSET.matcher(timeZone); + if (matcher.matches()) { + return matcher.group(1); + } + return timeZone; } /** diff --git a/src/test/org/firebirdsql/gds/ng/FbConnectionPropertiesTest.java b/src/test/org/firebirdsql/gds/ng/FbConnectionPropertiesTest.java index 2080022cb..43affc750 100644 --- a/src/test/org/firebirdsql/gds/ng/FbConnectionPropertiesTest.java +++ b/src/test/org/firebirdsql/gds/ng/FbConnectionPropertiesTest.java @@ -243,7 +243,7 @@ void testAsImmutable() { } @Test - void testSessionTimeZoneSpecialGmtOffsetHandling() { + void testSessionTimeZoneDefaultSpecialGmtOffsetHandling() { final TimeZone before = TimeZone.getDefault(); try { TimeZone.setDefault(TimeZone.getTimeZone("GMT-08:00")); @@ -254,4 +254,11 @@ void testSessionTimeZoneSpecialGmtOffsetHandling() { TimeZone.setDefault(before); } } + + @Test + void testSessionTimeZoneNormalizationOfOffsets() { + info.setSessionTimeZone("GMT+05:00"); + assertEquals("+05:00", info.getSessionTimeZone()); + } + }