Openhab overriding Jython's datetime

Seems like there’s an issue with OH3’s Jython (and possibly before) configuration when it comes to Python’s datetime. For example:

Regular Jython 2.7.2:

>>> from datetime import datetime
>>> now = datetime.now()
>>> print(type(now))
<class 'datetime.datetime'>

But in OH3:

from datetime import datetime
now = datetime.now()
log.info(u"datetime type is '{}'".format(type(now)))

Gives this in the log:
datetime type is '<type 'java.sql.Timestamp'>'

But if you instead have:

log.info(u"datetime.now() type is '{}'".format(type(datetime.now())))

then you get:
datetime.now() type is '<class 'datetime.datetime'>'

Somehow, Openhab is converting any datetime value to a java.sql.Timestamp on assignment. Can’t see any justification for it to do that, given that Jython 2.7.2 has a perfectly functional implementation of datetime

This has been there as long as I’ve used Jython. Scott’s initial suggestion was to not use Python’s date time for this and use Java’s ZonedDateTime instead. That’s what all the stuff that interacts with openHAB itself is going to need anyway. The Helper Library also has some robust conversion utilities to move between all the various date time types.

I don’t know if there ever was an explanation for it.

But, if you run up a Jython console outside Openhab, it doesn’t happen, as per the example I showed. This isn’t a Jython limitation, it’s an openhab issue.

Giving up and forcing python developers to use Java classes seems disrespectful to me.

Isn’t the whole point of providing Jython to allow people to code in Python, not to then force them to effectively learn Java?

I never said it was. There is a problem somewhere and a solution for it was never found.

You are welcome to volunteer your time to try and solve the problem. It seems disrespectful to me to demand people to volunteer their time just because you don’t like the answer.

Think about what you just said. We are offering the result of tens of thousands of volunteer hours of development to you for free and we’re the ones who are being disrespectful for not solving a problem in a way you approve? Entitled much?

All your interactions with openHAB itself is going to be done through Java Objects. If you want “pure” Python you should look at HABApp which runs outside of openHAB in pure Python 3 and interacts with it through the REST API. If you want to use Jython rules, events, event, items["MyItemName"] ir, ScriptExeuction.createTimer(), the logger, and all the rest of that are Java Objects. openHAB is written in Java. Jython runs on Java. You can’t not use Java for these unless you move outside of openHAB.

This problem was found and “solved” way way way back when Steve Bateman first made the Helper Libraries.

If you import core.date before doing anything with Python datetimes you won’t have an issue.

That aside, I agree with Rich, this isn’t CPython it’s Jython, everything is Java underneath the paint so why fight it?

3 Likes

I never found out that the root problem was found and solved. Thanks for pointing that out. The last I saw, before Scott and I fell out, was that it was inexplicable. I’m glad they found a solution. I should have looked at the libraries first.

I’m not sure the source on the OH side, I never did look. All I know is that these conversion internals exist and Steve had this workaround to remove them and restore the CPython behaviour.

I am appropriately chastised. My apologies.

I am beggining to understand that. I have up until now mostly been ignoring all that side of things. I fear the OH Jython documentation is to some extent written from a perspective of knowledge that I certainly lacked, and did not lead me to the right information about how to effectively use it.

I’m going to try to submit some proposed doco changes for Jython once I get a good enough understanding.

1 Like

As in, just include

import core.date

at the top of the script? That doesn’t seem to change the behaviour.

I think you need to include it after you include Python datetime to undo whatever is messing the types up and converting it to a java.sql.Date.

1 Like

Still no change putting them that way around

Then despite the change in the Helper Libraries my memory was correct and it’s not actually fixed. @CrazyIvan359, do you have any more details on that fix or a confirmation on how to use it?

Maybe we need to literally put the import the line before the line(s) that work with the Python datetime. I don’t know.

Looking forward to this, so far the docs are almost entirely written by the people that wrote the Helper Libraries and thus are written from a standpoint of understanding the internals.

Also, the stubs (I think) you are using should make using the Java objects much easier!

I do not, I’ve never messed around with it since I’ve always used Joda or Java time objects. I have no interest in digging into it for a long while at least, this is the first time it has come up as an issue and I have a lot of other things to work on. My recommendation will always first be to use ZonedDateTime instead, it’s free (performance wise, afaik) and frankly much more useful that Python’s datetime.

To be fair, there’s probably no point trying to fix it if we’re moving to GraalVM soon, anyway. Might be something to check in GraalVM testing, though, since the issue seems to be in OH’s Jython interfacing? I assume there’s a test suite for the GraalVM work?

Soon might be many years away. Lots of people are working on it but there is no indication when it’ll be working.

And even after we move to GraalVM that isn’t going to change the fact that all the stuff we use to actually interact with openHAB will still be Java. So even then ZonedDateTime will almost always be the better choice since it will be what is supported by the openHAB stuff (creating Timers, updating DateTime Items, etc.).

1 Like

Really? I got the impression it was nearly working from the talk I’d seen.

Sure. It is a very odd bug to have a value change type when it is assigned to a brand new variable. I don’t know that anyone would think to include that in test cases.

Got any links? I haven’t seen mention of anything in a while…

Don’t even try Python timers, seriously, just use openHAB’s createTimer function. We (myself, Rich, and Scott) spent a week trying to untangle what Jython does with timers.

You have to understand that Jython isn’t CPython so things you take for granted in CPython just don’t work in Jython. Python is an interpretted language and different interpreters handle some things differently.

No, I think it may have been as much wishful thinking, hoping I would be able to move to Python 3 scripting. Having seen posts talking about things being nearly ready six months to a year ago, I think I just assumed they’d have been moving on. I forget how long things can take!

Well, the nice thing with a scripting interface is that you can hide away implementation details. It would make scripting a hell lot easier if for the standard cases if I could just use Python types, which I know how to handle and where they are documented. The helper libs already do that to some extent. But you still have Python things, you have Python helper lib things, you have helper lib things, you have OH things, you have Java things, probably some Eclipse things… and you don’t need to do anything funky to come across all those. For something basic as the said DateTime for instance there is some searching and indirections needed before you find some actual API documentation. That may be obvious for people like you, who know OH inside out, but it is a tedious task if you are new or not so familiar. On the other hand many things about Python datetime I know from the top of my head, and if not I know where to find it. So if there was a layer abstracting the native Java stuff and mapping it to Python types for the common cases, while keeping the overall OH API, that would help a lot. And for the remaining few special cases you could still resort to directly accessing the Java objects.
Well, just as an outside perspective… :slight_smile:

My first thought was: What is ZonedDateTime? How does it relate to DateTime? The thing is, if you are used to Python the native datetime comes much more natural. Not sure what ZonedDateTime offers that is not possible with Pythons datetime.

@redm I understand where you’re coming from, but read the above. For the time being we’re stuck with Jython, and it doesn’t handle Python datetimes very well. ZonedDateTime is a Java class, documentation can be found by Googling it, Java classes are very similar to Python classes so it’s not a foreign construct to someone who knows Python.

I don’t disagree with your thoughts on things being confusing for beginners, but I don’t have time to write a novel on how to script in OH using Python. I help out where I can when I have time. If you have questions you can open a thread on here. If you have contributions to the Helper Libraries documentation based on your experience learning to script in OH, they will be welcome. I just don’t have the time to write the book on it.