You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by Daniel John Debrunner <dj...@apache.org> on 2007/05/11 02:22:07 UTC
Conversion of SQL datetime values to JDBC objects using Calendar
- any JDBC spec lead guidance?
[Derived & expanded from the discussion in DERBY-1816]
Derby has SQL datetime types DATE/TIME/TIMESTAMP. The SQL standard
(section 4.6.2) says the fields (year, month day etc.) are "constrained
by the natural rules for dates using the Gregorian calendar"
The JDBC datetime objects store a milli-second value relative to the
epoch of 1970-01-01 and thus are not tied to the Gregorian calendar with
the possible exception of the conversion to/from String.
JDBC ResultSet has getDate/getTime/getTimestamp methods that convert SQL
date-time values to java.sql.{Date,Time,Timestamp} objects. These
methods have two variants, ones that take a java.util.Calendar object
and those that don't.
For the methods that take a Calendar the behaviour is somewhat
undefined, and thinking about it leads to several questions:
1) The Javadoc has comments like:
"This method uses the given calendar to construct an appropriate
millisecond value for the timestamp if the underlying database does not
store timezone information."
"cal - the java.util.Calendar object to use in constructing the date"
To me this implies the actual Calendar object passed in is used and
modified by the JDBC driver to calculate the milli-second value to
construct the Time/Date/Timestamp object. Thus after one of these calls
the SQL column's value is "returned" twice, once as an JDBC object
(Time/Date/Timestamp) and once as the current contents of the passed-in
Calendar. Is this correct or is the Calendar object expected to be
unchanged by the getXXX() call?
[embedded uses the passed-in Calendar - (with minor bugs) ]
[client uses different Calendar objects just fetching the timezone from
passed-in Calendar]
2) If the answer to 1) is that the actual Calendar is used, then should
the Calendar object have clear() called before setting any of the
fields, or should just the valid fields defined by SQL be set?
This makes a difference if the caller has set for a GregorianCalendar
the ERA field to GregorianCalendar.BC. Clearing the fields will ignore
the BC setting, setting only the fields defined by the datetime value
will cause honour the BC request.
[embedded & client cal clear()]
3) What happens if the passed-in Calendar is not a GregorianCalendar?
Should the Calendar just have its fields set that correspond to the SQL
fields set (YEAR,MONTH,DAY), so that 2007-05-10 would be the year 2007
in the non-Gregorian calendar? Note that for some calendars the ERA is
key, meaning the answer for 2) would have to be: do not call clear().
Or should the SQL datetime always be treated as a normalized Gregorian
value and instead converted to milli-second value using a
GregorianCalendar and then set the passed-in calendar to that
milli-second value?
E.g. with a SQL value of 2007-05-10 and passing in a Jewish calendar is
the absolute value of the date returned today (22 Iyyar 5767,
2007-05-10AD) or sometime in the past (year 2007 in the Jewish calendar,
somewhere ~1754BC Gregorian).
[embedded/client just uses the SQL fields to set the Calendar fields]
4) For a java.sql.Time object the 'date components must be set to the
"zero epoch" value of January 1, 1970'. That's clear that the date
components are based upon the Gregorian calendar. Then the issue is the
passed-in calendar cannot be used to generate the mill-second value to
create the java.sql.Time object because it cannot be guaranteed that
setting the YEAR field to 1970 will correspond to the epoch. So the
passed in Calendar object would be used for the timezone but not used to
calculate the milli-second value. And then would the passed in Calendar
object needs to be set to the millisecond value corresponding to the
return java.sql.Time object?
Getting more confused the more I look at this ...
Dan.