Issue2387

classification
Title: Jtable displaying dates
Type: behaviour Severity: major
Components: Core Versions: Jython 2.7
Milestone:
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: Nosy List: darjus, kensingtoncat, zyasoft
Priority: Keywords:

Created on 2015-09-01.15:11:30 by kensingtoncat, last changed 2015-10-07.10:32:50 by darjus.

Messages
msg10191 (view) Author: alan ross (kensingtoncat) Date: 2015-09-01.15:11:30
In 2.5x could have  jtablemodel contain datetime.date data and maintained column renderer for those datetime.date columns.
In 2.5x Table display would "auto-magically" convert the datetime.date to a corresponding java.sql.Date.
However in 2.7, the java.sql.Date value is one day less than the original datetime.date. 
I can rework the software to resolve this, but is this a bug in the new release for JTables?
msg10192 (view) Author: Jim Baker (zyasoft) Date: 2015-09-01.16:48:41
Let's try this out:

>>> import datetime, java
>>> datetime.date.today()
datetime.date(2015, 9, 1)
>>> datetime.date.today().__tojava__(java.sql.Date)
2015-08-31

So there's the reported problem. Let's dig in further. Per above, Jython does this automatic conversion via __tojava__ methods on datetime.{date, datetime, time} Python classes. Here's the relevant conversion for datetime.date:

https://github.com/jythontools/jython/blob/master/Lib/datetime.py#L1073

    if _is_jython:
        def __tojava__(self, java_class):
            if java_class not in (Calendar, Date, Object):
                return Py.NoConversion
            calendar = _make_java_utc_calendar()
            calendar.set(self.year, self.month - 1, self.day)
            if java_class == Calendar:
                return calendar
            else:
                return Date(calendar.getTimeInMillis())

This code is problematic: java.sql.Date is in UTC; but datetime.date is naive.

>>> cal = datetime._make_java_utc_calendar()
>>> cal.clear()
>>> cal.set(2015, 8, 1)
>>> cal.getTimeInMillis()/1000.
1441065600.0
>>> time.time()
1441125551.691
>>> cal.getTimeInMillis()/1000. - time.time()
-59969.53800010681

Or a delta about 16.7 hours. More than enough to cause this issue.

I'm not certain what to do here. java.sql.Date models time differently than datetime.date. Providing this conversion might be worse than useless, but it's also something we have historically done so we cannot just remove.

Interestingly, datetime.datetime does not support conversion to java.sql.Date, which can be done correctly:

>>> datetime.datetime.now().__tojava__(java.sql.Date)
Error

So this specific conversion should be supported.
msg10205 (view) Author: alan ross (kensingtoncat) Date: 2015-09-02.22:33:14
work around --
   if you use a python TableModel class holds datetime.date elements
   you need to create a python JTable class that is derived from a 
   java JTable class in which can override getValueAt and setValueAt.
   for each method you need to do the necessary "coversion":
      METHOD                    FROM                        TO
     getValueAt      datetime.date/java.util.Date       java.sql.Date
     setValueAt      java.sql.Date/java.util.Date       datetime.date
msg10206 (view) Author: alan ross (kensingtoncat) Date: 2015-09-02.22:42:49
Thanks for addressing issue.

I have been careful about "casting" in general.
Unfortunately the implicit casting in JTable caught me off-guard.
msg10315 (view) Author: Darjus Loktevic (darjus) Date: 2015-10-07.10:32:50
Closing, unless there's something else we can do?
History
Date User Action Args
2015-10-07 10:32:50darjussetstatus: open -> closed
nosy: + darjus
messages: + msg10315
2015-09-02 22:42:50kensingtoncatsetmessages: + msg10206
2015-09-02 22:33:14kensingtoncatsetmessages: + msg10205
2015-09-01 16:48:41zyasoftsetresolution: accepted
messages: + msg10192
nosy: + zyasoft
2015-09-01 15:11:30kensingtoncatcreate