[
https://issues.apache.org/jira/browse/CALCITE-2989?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17694246#comment-17694246
]
Gregory Hart commented on CALCITE-2989:
---------------------------------------
[~jdw], could you modify your test case with a date after 1582-10-15? That
should avoid the calendar system issue.
The Java standard is to use a java.util.Calendar instance to parse a timestamp
returned from Timestamp.getTime(). You should be able to use Calendar.get() to
retrieve the year, month, day, hour, etc. For the JDBC API, if you do not
provide a Calendar instance then the default one is used which includes the
local timezone (DEFAULT_ZONE in the DateTimeUtils class).
Avatica represents unix timestamps internally as the number of milliseconds
since the unix epoch in UTC. This requires a timezone conversion when
converting from a Long to a Timestamp using the default Calendar.
You should see the same behavior with the major database vendors (such as
Oracle and SQL Server). If you do not specify a Calendar to
ResultSet.getTimestamp(int, Calendar) then the timestamp is converted to the
local timezone. This allows it be parsed correctly when using the
Calendar.get() methods.
Below is the test case from the merge request that verifies that the unix epoch
as a number (0) is the same as 1970-01-01T00:00:00 UTC.
{code:java}
final Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
Locale.ROOT);
utcCal.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
utcCal.set(Calendar.MILLISECOND, 0);
assertThat(unixTimestampToSqlTimestamp(0L, utcCal).getTime(),
is(utcCal.getTimeInMillis()));{code}
> Use ISO-8601 calendar when converting between java.sql types and UNIX
> timestamps
> --------------------------------------------------------------------------------
>
> Key: CALCITE-2989
> URL: https://issues.apache.org/jira/browse/CALCITE-2989
> Project: Calcite
> Issue Type: Bug
> Components: avatica
> Reporter: vinoyang
> Assignee: Gregory Hart
> Priority: Major
> Labels: pull-request-available
> Fix For: avatica-1.23.0
>
> Time Spent: 2h 10m
> Remaining Estimate: 0h
>
> Converting java.sql types to unix timestamps requires extra steps to also
> convert to the correct calendar. Unix timestamps should follow the proleptic
> Gregorian calendar as defined by ISO-8601. Java uses the standard Gregorian
> calendar for java.sql types and switches to the Julian calendar for dates
> before the Gregorian shift.
> If we uses avatica's {{DateTimeUtils}} the dates less than 2299161 will cause
> an error result in Flink table/sql , test code :
> {code:java}
> testAllApis(
> "1500-04-30 12:00:00".cast(Types.SQL_TIMESTAMP),
> "'1500-04-30 12:00:00'.cast(SQL_TIMESTAMP)",
> "CAST('1500-04-30 12:00:00' AS TIMESTAMP)",
> "1500-04-30 12:00:00.0")
> {code}
> result :
> {code:java}
> Expected :1500-04-30 12:00:00.0
> Actual :1500-04-20 12:00:00.0
> {code}
> another case is here :
> https://issues.apache.org/jira/browse/FLINK-11935
> I find a key code snippet has been removed in CALCITE-1884 which caused this
> issue :
> {code:java}
> if (j < 2299161) {
> j = day + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
> }
> {code}
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)