Jython date/time comparison?

is there an easy way (or really ANY way) to do this? i’m not having any luck whatsoever doing time comparisons, specifically from the astro binding. i have a cron rule that runs every 10 minutes after 4pm, but doesn’t do anything until after sunset…but in trying to convert that to jython i’m having zero luck in getting this to work. i’ve been trying to use strptime, but all i ever end up with is exceptions.

Here an example:

#import needed
from datetime import datetime
from datetime import timedelta

#If you want to compare two events time

#Store first event datetime string
dateTime_1 = datetime.now().strftime('%d/%m/%Y %H:%M:%S')

#Store second event datetime string
dateTime_2 = datetime.now().strftime('%d/%m/%Y %H:%M:%S')

#elaborate
dtEvent1 = datetime.strptime(dateTime_1, '%d/%m/%Y %H:%M:%S')
dtEvent2 = datetime.strptime(dateTime_2, '%d/%m/%Y %H:%M:%S')

delta = dtEvent1 - dtEvent2
if delta.seconds < 600:
    #do something

    
    
#If you want to compare your hour and minutes set point with actual values
nowHH = int(datetime.now().strftime('%H'))
nowMM = int(datetime.now().strftime('%M'))

if nowHH == myHOUR and nowMM == myMINUTE:
    #do something

I’ve created some utility functions to convert between the different time types in openHAB (Java Calendar and Date, Joda DateTime and Python datetime). For example, you could use this to convert the dates to Python datetimes for comparison.

Hi Everyone,

I don’t know how and why, but this issue now occures with a recent Jython / OH version to me. The awkward thing is that it just started yesterday and I have no clue, what triggered it. I have the issue in a larger project where I use datetime comparisons quite often (… well they worked…).

I created a snippet which in my case shows the problem… including above fix from @steve1 (thanks!), which sadly did not work for me.

from datetime import datetime, timedelta, date, time
import sys

from core.log import logging

def logOut(text):
    logging.getLogger("S2E.TestDateTime").info(text)


strPath = ";".join(sys.path)
logOut("System path: " + strPath )
logOut("Python version: " + sys.version )


# If you do not see the check for the fix below, check, which modules are available..
# logOut(str(sys.modules))



# Fix as of https://community.openhab.org/t/jython-date-time-comparison/12806
# NOT WORKING :(
if 'core.jsr223' in sys.modules:
    # Workaround for Jython JSR223 bug where
    # dates and datetimes are converted to java.sql.Date
    # and java.sql.Timestamp
    def remove_java_converter(clazz):
        logOut("  - checking class: %s" % (  clazz.__name__  )   )
        if hasattr(clazz, '__java__'):
            del clazz.__java__
            logOut("    ... removed.")
        else:
            logOut("    ... not found.")
    logOut("core.jsr found, removing java converters...")
    remove_java_converter(date)
    remove_java_converter(time)
    remove_java_converter(datetime)
    remove_java_converter(timedelta)




logOut("**** Test 0")
dtStart = datetime.now()
dtEnd = time( 6, 0)
logOut("  Input for calc... start '%s' of type %s AND end '%s' of type %s" % (  str(dtStart), str(type(dtStart)), str(dtEnd), str(type(dtEnd))  )   )


logOut("**** Test 1")
dtStart = datetime.now()
dtEnd = datetime.now() + timedelta(minutes=45)
logOut("  Input for calc... start '%s' of type %s AND end '%s' of type %s" % (  str(dtStart), str(type(dtStart)), str(dtEnd), str(type(dtEnd))  )   )
dtDelta = None
try:
    dtDelta = dtEnd - dtStart
    logOut("  DT-Calc succesful: " + dtDelta.strftime("%d.%m.%Y %H:%M"))
except Exception as inst:
    logOut("  DT-Calc errored: '%s' and Details: %s" % (  str(sys.exc_info()[0]), str(inst)  )   )

logOut("**** Test 2")
dtStart = datetime.combine( datetime.today(), time( 6, 0) ) + timedelta(minutes=-30)
dtEnd = datetime.combine( datetime.today(), time( 6, 0) ) + timedelta(minutes=45)
logOut("  Input for calc... start '%s' of type %s AND end '%s' of type %s" % (  str(dtStart), str(type(dtStart)), str(dtEnd), str(type(dtEnd))  )   )
dtDelta = None
try:
    dtDelta = dtEnd - dtStart
    logOut("  DT-Calc succesful: " + dtDelta.strftime("%d.%m.%Y %H:%M"))
except Exception as inst:
    logOut("  DT-Calc errored: '%s' and Details: %s" % (  str(sys.exc_info()[0]), str(inst)  )   )

Even after restarting openhab and the whole machine, I get this same issue. In the logs, it looks like this - showing that java.sql.Timestamp is returned all over the place.

2019-12-03 11:37:01.973 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'python/personal/test_dt.py'
2019-12-03 11:37:06.151 [INFO ] [S2E.TestDateTime                    ] - System path: /etc/openhab2/automation/lib/python;/etc/openhab2/automation/jython/Lib;/etc/openhab2/automation/jython/jython-standalone-2.7.0.jar/Lib;__classpath__;__pyclasspath__/
2019-12-03 11:37:06.174 [INFO ] [S2E.TestDateTime                    ] - Python version: 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) 
[OpenJDK Server VM (Azul Systems, Inc.)]
2019-12-03 11:37:06.183 [INFO ] [S2E.TestDateTime                    ] - core.jsr found, removing java converters...
2019-12-03 11:37:06.223 [INFO ] [S2E.TestDateTime                    ] -   - checking class: date
2019-12-03 11:37:06.239 [INFO ] [S2E.TestDateTime                    ] -     ... not found.
2019-12-03 11:37:06.249 [INFO ] [S2E.TestDateTime                    ] -   - checking class: time
2019-12-03 11:37:06.260 [INFO ] [S2E.TestDateTime                    ] -     ... not found.
2019-12-03 11:37:06.270 [INFO ] [S2E.TestDateTime                    ] -   - checking class: datetime
2019-12-03 11:37:06.276 [INFO ] [S2E.TestDateTime                    ] -     ... not found.
2019-12-03 11:37:06.289 [INFO ] [S2E.TestDateTime                    ] -   - checking class: timedelta
2019-12-03 11:37:06.293 [INFO ] [S2E.TestDateTime                    ] -     ... not found.
2019-12-03 11:37:06.296 [INFO ] [S2E.TestDateTime                    ] - **** Test 0
2019-12-03 11:37:06.312 [INFO ] [S2E.TestDateTime                    ] -   Input for calc... start '2019-12-03 12:37:06.297' of type <type 'java.sql.Timestamp'> AND end '07:00:00' of type <type 'java.sql.Time'>
2019-12-03 11:37:06.319 [INFO ] [S2E.TestDateTime                    ] - **** Test 1
2019-12-03 11:37:06.331 [INFO ] [S2E.TestDateTime                    ] -   Input for calc... start '2019-12-03 12:37:06.322' of type <type 'java.sql.Timestamp'> AND end '2019-12-03 13:22:06.323' of type <type 'java.sql.Timestamp'>
2019-12-03 11:37:06.344 [INFO ] [S2E.TestDateTime                    ] -   DT-Calc errored: '<type 'exceptions.TypeError'>' and Details: unsupported operand type(s) for -: 'java.sql.Timestamp' and 'java.sql.Timestamp'
2019-12-03 11:37:06.353 [INFO ] [S2E.TestDateTime                    ] - **** Test 2
2019-12-03 11:37:06.375 [INFO ] [S2E.TestDateTime                    ] -   Input for calc... start '2019-12-03 06:30:00.0' of type <type 'java.sql.Timestamp'> AND end '2019-12-03 07:45:00.0' of type <type 'java.sql.Timestamp'>
2019-12-03 11:37:06.380 [INFO ] [S2E.TestDateTime                    ] -   DT-Calc errored: '<type 'exceptions.TypeError'>' and Details: unsupported operand type(s) for -: 'java.sql.Timestamp' and 'java.sql.Timestamp'

I have found out that there was(?) an issue with jython regarding this, but there are few hits when googleing for the topic:

But esp the later hints you to avoid setting a variable to a python datetime value (which I would not see as an option for me).
This thread actually was returned quite often (that’s why I thought it might be a good idea to reopen it).

Thanks for any hints you have.

If you use the Helper Libraries there are datetime convenience functions available, including ones to get different unit’s deltas between two datetime objects of any type. These functions are in core.date and they are documented in the code and also here.

Just looking at your code above, your issue there may be that you need to remove the Java packages before importing the Python ones.

Replace __java__ with __tojava__! This was a fix I made (actually, IIRC I had Michael make it) in the core.date library…

1 Like

@CrazyIvan359, @5iver thanks for the super quick reply and the helpful advice!!

I also added some more tests in my script:

  • variables in module scope are affected
  • variables in methods (w/o class) are NOT affected
  • variables in class methods are NOT affected

I imported core.date and this fixes the issue also for module scope. So I will go ahead and just import the helper lib’s date module into my project (I’m already using some of the other modules, but until now had no reason to use date).

Thanks!! :grinning: :+1: