Skip to content

Commit 14f82b0

Browse files
committed
Make TimeZoneComparison class
1 parent 6ba1f85 commit 14f82b0

File tree

3 files changed

+100
-82
lines changed

3 files changed

+100
-82
lines changed

embulk-input-mysql/src/main/java/org/embulk/input/MySQLTimeZoneBuilder.java

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package org.embulk.input;
2+
3+
import org.embulk.spi.Exec;
4+
import org.slf4j.Logger;
5+
6+
import java.sql.Connection;
7+
import java.sql.ResultSet;
8+
import java.sql.SQLException;
9+
import java.sql.Statement;
10+
import java.util.Date;
11+
import java.util.Locale;
12+
import java.util.TimeZone;
13+
14+
public class MySQLTimeZoneComparison
15+
{
16+
private static final int ONE_HOUR_SEC = 3600;
17+
private static final int ONE_MIN_SEC = 60;
18+
19+
private Connection connection;
20+
21+
private final Logger logger = Exec.getLogger(getClass());
22+
23+
public MySQLTimeZoneComparison(Connection connection)
24+
{
25+
this.connection = connection;
26+
}
27+
28+
public void compareTimeZone() throws SQLException
29+
{
30+
// TODO error check.
31+
TimeZone serverTimeZone = getServerTimeZone();
32+
TimeZone clientTimeZone = TimeZone.getDefault();
33+
Date today = new Date();
34+
int clientOffset = clientTimeZone.getRawOffset();
35+
36+
if( clientTimeZone.inDaylightTime(today) ){
37+
clientOffset += clientTimeZone.getDSTSavings();
38+
}
39+
40+
//
41+
// Compare offset only. Although I expect to return true, the following code return false,
42+
//
43+
// TimeZone tz_jst = TimeZone.getTimeZone("JST");
44+
// TimeZone tz_gmt9 = TimeZone.getTimeZone("GMT+9");
45+
// tz_jst.hasSameRules(tz_gmt9) // return false.
46+
//
47+
if( clientOffset != serverTimeZone.getRawOffset() ) {
48+
logger.warn(String.format(Locale.ENGLISH,
49+
"The client timezone(%s) is different from the server timezone(%s). The plugin will fetch wrong datetime values.",
50+
clientTimeZone.getID(),serverTimeZone.getID()));
51+
logger.warn(String.format(Locale.ENGLISH,
52+
"Use `options: { useLegacyDatetimeCode: false }`"));
53+
}
54+
logger.warn(String.format(Locale.ENGLISH,"The plugin will set `useLegacyDatetimeCode=false` by default in future."));
55+
56+
57+
}
58+
59+
private TimeZone getServerTimeZone() throws SQLException
60+
{
61+
//
62+
// First, I used `@@system_time_zone`. but It return non Time Zone Abbreviations name on a specific platform.
63+
// So, This method calculate GMT offset with query.
64+
//
65+
String query = "select TIME_TO_SEC(timediff(now(),utc_timestamp()));";
66+
Statement stmt = connection.createStatement();
67+
68+
try {
69+
ResultSet rs = stmt.executeQuery(query);
70+
if (rs.next()) {
71+
int offsetSeconds = rs.getInt(1);
72+
return fromGMTOffsetSeconds(offsetSeconds);
73+
}
74+
else {
75+
// TODO Error check.
76+
return null;
77+
}
78+
79+
} finally {
80+
stmt.close();
81+
}
82+
}
83+
84+
private TimeZone fromGMTOffsetSeconds(int offsetSeconds)
85+
{
86+
if( offsetSeconds == 0 ) {
87+
return TimeZone.getTimeZone("UTC");
88+
}
89+
90+
String sign = offsetSeconds > 0 ? "+" : "-";
91+
int absOffsetSec = Math.abs(offsetSeconds);
92+
int tzHour = absOffsetSec / ONE_HOUR_SEC;
93+
int tzMin = absOffsetSec % ONE_HOUR_SEC / ONE_MIN_SEC;
94+
String tzName = String.format(Locale.ENGLISH, "GMT%s%02d:%02d", sign, tzHour, tzMin);
95+
return TimeZone.getTimeZone(tzName);
96+
}
97+
}

embulk-input-mysql/src/main/java/org/embulk/input/mysql/MySQLInputConnection.java

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package org.embulk.input.mysql;
22

3-
import java.sql.Statement;
4-
import java.util.Date;
53
import java.util.List;
64
import java.sql.Connection;
75
import java.sql.PreparedStatement;
86
import java.sql.SQLException;
97
import java.sql.ResultSet;
10-
import java.util.Locale;
118
import java.util.TimeZone;
129

1310
import com.mysql.jdbc.ConnectionImpl;
1411
import com.mysql.jdbc.ConnectionProperties;
15-
import org.embulk.input.MySQLTimeZoneBuilder;
12+
import org.embulk.input.MySQLTimeZoneComparison;
1613
import org.embulk.input.jdbc.JdbcInputConnection;
1714
import org.embulk.input.jdbc.JdbcLiteral;
1815
import org.embulk.input.jdbc.getter.ColumnGetter;
@@ -66,31 +63,8 @@ public TimeZone getServerTimezoneTZ()
6663

6764
public void compareTimeZone() throws SQLException
6865
{
69-
// TODO error check.
70-
TimeZone serverTimeZone = MySQLTimeZoneBuilder.fromSystemTimeZone(connection);
71-
TimeZone clientTimeZone = TimeZone.getDefault();
72-
Date today = new Date();
73-
int clientOffset = clientTimeZone.getRawOffset();
74-
75-
if( clientTimeZone.inDaylightTime(today) ){
76-
clientOffset += clientTimeZone.getDSTSavings();
77-
}
78-
79-
//
80-
// Compare offset only. Although I expect to return true, the following code return false,
81-
//
82-
// TimeZone tz_jst = TimeZone.getTimeZone("JST");
83-
// TimeZone tz_gmt9 = TimeZone.getTimeZone("GMT+9");
84-
// tz_jst.hasSameRules(tz_gmt9) // return false.
85-
//
86-
if( clientOffset != serverTimeZone.getRawOffset() ) {
87-
logger.warn(String.format(Locale.ENGLISH,
88-
"The client timezone(%s) is different from the server timezone(%s). The plugin will fetch wrong datetime values.",
89-
clientTimeZone.getID(),serverTimeZone.getID()));
90-
logger.warn(String.format(Locale.ENGLISH,
91-
"Use `options: { useLegacyDatetimeCode: false }`"));
92-
}
93-
logger.warn(String.format(Locale.ENGLISH,"The plugin will set `useLegacyDatetimeCode=false` by default in future."));
66+
MySQLTimeZoneComparison timeZoneComparison = new MySQLTimeZoneComparison(connection);
67+
timeZoneComparison.compareTimeZone();
9468
}
9569

9670
}

0 commit comments

Comments
 (0)