The attached test passes fails on Linux (ubuntu) and passes on Windows. We use python 2.6 and Jpype 0.5.4.
We calculate a large integer value in python, then pass this into the java.util.Date(long millis) constructor. On Windows, the correct date is constructed, on Linux the long value overflows to a negative value, constructing the wrong date.
We have a work around: formatting the date in Python then parsing the String in Java, with the implied overhead.
import unittest
import datetime
import jpype
class JpypeKdbTests(unittest.TestCase):
def test_javadate(self):
jpype.startJVM(jpype.getDefaultJVMPath())
param = datetime.date(2007,1,1)
## note millis needs to be passed in as a java 'long'
daysSince1970 = param.toordinal() - 719163
millis = daysSince1970 * 1000*60*60*24
print '\n'
print millis
## should print 'Mon Jan 01 00:00:00 GMT 2007'
jdate = jpype.java.util.Date(millis)
print jdate.getTime()
print jdate
## try formatting in Java
df = jpype.java.text.SimpleDateFormat('yyyy-MM-dd')
df.setTimeZone(jpype.java.util.TimeZone.getTimeZone('Europe/London'))
datestr = df.format(jpype.JObject(jdate, 'java.util.Date'))
print datestr
self.assertEqual('2007-01-01', datestr)
if __name__ == '__main__':
unittest.main()
Test results (Linux)
test_javadate (test_timeslinuxbug.JpypeKdbTests) ...
1167609600000
-621504512
Wed Dec 24 20:21:35 GMT 1969
1969-12-24
FAIL
Test results (Windows)
test_javadate (gsa.test_timeslinuxbug.JpypeKdbTests) ...
1167609600000
1167609600000
Mon Jan 01 00:00:00 GMT 2007
2007-01-01
ok
----------------------------------------------------------------------
Ran 1 test in 0.078s
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
test case
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Last edit: Anonymous 2013-05-05
I guess a simpler workaround would be:
jdate = jpype.java.util.Date(long(millis))
By the way, is your Linux 64 bit? I noticed that on all Unix 64 bit platforms (while Win 64 is fine).
Here:
bash-3.00$ python
Python 2.5.1 (r251:54863, Oct 4 2007, 10:50:52) [C] on aix5
Type "help", "copyright", "credits" or "license" for more information.
>>> type(1167609600000)
<type 'long'>
>>>
bash-3.00$ python64
Python 2.5.1 (r251:54863, Oct 2 2007, 12:02:12) [C] on aix5
Type "help", "copyright", "credits" or "license" for more information.
>>> type(1167609600000)
<type 'int'>
>>>
It looks to be a Python's problem, though JPype should handle this, too.
The following patch sort of makes it work:
--- XEngine/src/java/JPype-0.5.2.1/src/native/common/jp_primitivetypes.cpp (revision 7205)
+++ XEngine/src/java/JPype-0.5.2.1/src/native/common/jp_primitivetypes.cpp (working copy)
@@ -464,7 +464,7 @@
jvalue res;
if (JPEnv::getHost()->isInt(obj))
{
- res.j = (jlong)JPEnv::getHost()->intAsInt(obj);
+ res.j = (jlong)JPEnv::getHost()->longAsLong(obj);
}
else if (JPEnv::getHost()->isLong(obj))
{
The following fix might be better instead of the previous, since JPyInt::asLong() returns long rather than int.
Index: src/native/python/py_hostenv.cpp
--- src/native/python/py_hostenv.cpp (revision 7205)
+++ src/native/python/py_hostenv.cpp (working copy)
@@ -253,7 +253,7 @@
return new HostRef(JPyInt::fromLong(v), false);
}
-jint PythonHostEnvironment::intAsInt(HostRef* res)
+jlong PythonHostEnvironment::intAsInt(HostRef* res)
{
return JPyInt::asLong(UNWRAP(res));
}
Index: src/native/python/include/py_hostenv.h
===================================================================
--- src/native/python/include/py_hostenv.h (revision 7205)
+++ src/native/python/include/py_hostenv.h (working copy)
@@ -105,7 +105,7 @@
virtual bool isInt(HostRef*);
virtual HostRef* newInt(jint);
- virtual jint intAsInt(HostRef*);
+ virtual jlong intAsInt(HostRef*);
virtual bool isLong(HostRef*);
virtual HostRef* newLong(jlong);
Index: src/native/common/include/jp_hostenv.h
===================================================================
--- src/native/common/include/jp_hostenv.h (revision 7205)
+++ src/native/common/include/jp_hostenv.h (working copy)
@@ -85,7 +85,7 @@
virtual bool isInt(HostRef*) = 0;
virtual HostRef* newInt(jint) = 0;
- virtual jint intAsInt(HostRef*) = 0;
+ virtual jlong intAsInt(HostRef*) = 0;
virtual bool isLong(HostRef*) = 0;
virtual HostRef* newLong(jlong) = 0;