# Gateway Message Handler translates a datetime.now() command into a java.sql.Timestamp, how can I change it back?

**URL:** <https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [October 18, 2023, 1:31am UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628 "2023-10-18T01:31:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 1:31am UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/1 "2023-10-18T01:31:59Z")

</div>

I am trying to pass a datetime down from the gateway so that I have a single source of truth for my scripts where timing is important. For this I made a simple Request Handler:

```auto
def handleMessage(payload):
	from datetime import datetime
	return datetime.now()

```

the problem is that the object that is returned is reading as a `java.sql.Timestamp`, which evidently can't be delta'd against a datetime.datetime() object. Is there a way to fix this so that it returns the object I asked for (unlikely, because java), or at least translate it back on the recieving side without getting into stringification -\> destringification?

Also, it drops timezone information in the process, regardless of if I use datetime.now() or datetime.utcnow().

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 2:16am UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/2 "2023-10-18T02:16:45Z")

</div>

return a `system.date.now()`, which is a java.util.Date, (and java.sql.Timestamp is a Date subclass).

edit: I'm not sure why a `datetime.datetime` becomes a `java.sql.Timestamp` after serialization/deserialization. Regardless, don't use janky Python types, just use Java's `Date` in your code instead. All the date/time scripting functions are built to work with it.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 18, 2023, 12:08pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/3 "2023-10-18T12:08:19Z")

</div>

> [@Kevin.Herron](#):
>
> don't use janky Python types

This.

Also, see this topic (not just for Perspective):

> [@System.date.now Timezone](https://forum.inductiveautomation.com/t/system-date-now-timezone/72478):
>
> When running the function system.date.now() from a perspective session, what time zone should be returned? The user's computer time? Or the server's time?

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:00pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/4 "2023-10-18T22:00:19Z")

</div>

From my perspective, Java types seem equally janky, and having python types but not truly supporting them (as evidenced by the serialization in gateway comms that is apparently required for a lot of consistent scripting) is the most painful middle ground.

Half of the draw of Ignition is its advertised capability to script in Python (my preferred language, and the language used for almost all of the supporting software we have), and the more I use it the more I am frustrated by it. I don't know how much of it is jython, I don't know how much of it is the implementation in the gateway backend, but also I don't want to have to care.

@pturmel

> Also, see this topic (not just for Perspective):

Thank you, it provides some context. I suppose what I have to do, but was hoping I didn't have to do, is write my own ISO 8601 parser in ignition. Its reinventing the wheel for the upteenth time. I already tried to transit my timestamps in ISO 8601 format, but the system.date.parse method (which I am already using, out of necessity) doesn't seem to happily take the T that goes between the date and time. I do know that this was made optional in ISO 8601-2019, but it should still be handled.

@Kevin.Herron If anything is to be taken from my venting -- please fast-lane basic ISO 8601-1:2019 and extended ISO 8601-2:2019 methods for parsing datetime strings. I see [other requests](https://forum.inductiveautomation.com/t/feature-add-iso-8601-date-format-into-format-transform-list/60327/2) for this in the forums.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:11pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/5 "2023-10-18T22:11:56Z")

</div>

> [@sherman](#):
>
> Half of the draw of Ignition is its advertised capability to script in Python (my preferred language, and the language used for almost all of the supporting software we have), and the more I use it the more I am frustrated by it. I don't know how much of it is jython, I don't know how much of it is the implementation in the gateway backend, but also I don't want to have to care.

Python is the scripting _language_, the runtime, however is Jython, not CPython. For most users this is a meaningless distinction, but unfortunately it trips up people who have some Python or programming experience.

You don't need to transit your timestamps in ISO-8601, Java's Date is already UTC. Just use that. Don't get fooled by the fact that when you display it it gets displayed in the local timezone. If you need to control how it gets displayed, use one of the date format functions _at that point_ to convert it to a String for display.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:19pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/6 "2023-10-18T22:19:18Z")

</div>

> unfortunately it trips up people who have some Python or programming experience.

Somewhat of an understatement, I'd say. Still not sure how my `datetime.datetime` is coming back with `java.sql.Timestamp`.

> You don't need to transit your timestamps in ISO-8601, Java's Date is already UTC. Just use that. Don't get fooled by the fact that when you display it it gets displayed in the local timezone. If you need to control how it gets displayed, use one of the date format functions _at that point_ to convert it to a String for display.

And if the strings coming through are not in UTC? Operating in different timezones with different programmers formatting different awful timestamp strings? ISO 8601 exists for a reason, and it is a good reason: timestamps are amongst the most painful data types to work with, for a multitude of reasons. Allowing or perhaps even encouraging strict ISO 8601 adherence is very valuable.

Also having a builtin method that can be run in client or in gateway that will return the gateway's current time (as UTC milliseconds since the epoch, or something), very valuable.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:19pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/7 "2023-10-18T22:19:52Z")

</div>

> [@sherman](#):
>
> @Kevin.Herron If anything is to be taken from my venting -- please fast-lane basic ISO 8601-1:2019 and extended ISO 8601-2:2019 methods for parsing datetime strings. I see [other requests](https://forum.inductiveautomation.com/t/feature-add-iso-8601-date-format-into-format-transform-list/60327/2) for this in the forums.

I don't know what's meant by this. You can format and parse ISO 8601 right now.

```auto
now = system.date.now()

print now

iso_now = system.date.format(now, "yyyy-MM-dd'T'HH:mm:ss'Z'")

print iso_now

parsed_from_iso = system.date.parse(iso_now, "yyyy-MM-dd'T'HH:mm:ss'Z'")

print parsed_from_iso

```

```auto
Wed Oct 18 15:19:02 PDT 2023
2023-10-18T15:19:02Z
Wed Oct 18 15:19:02 PDT 2023
>>> 

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:20pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/8 "2023-10-18T22:20:49Z")

</div>

> [@sherman](#):
>
> Also having a builtin method that can be run in client or in gateway that will return the gateway's current time (as UTC milliseconds since the epoch, or something), very valuable.

Sure, we've already talked about it. It's `system.date.now()`. It returns the current Date, which is just milliseconds since epoch UTC under the hood.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:21pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/9 "2023-10-18T22:21:29Z")

</div>

> Sure, we've already talked about it. It's `system.date.now()` . It returns the current Date, which is just milliseconds since epoch since UTC under the hoo

How can I know that this is gateway, and not client? Half of the battles I seem to be fighting stem from this question.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:23pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/10 "2023-10-18T22:23:50Z")

</div>

Partly you should just know what scope you are executing your code in... but there's also `system.util.getSystemFlags` if you really need to programmatically figure out where you are.

[https://docs.inductiveautomation.com/display/DOC81/system.util.getSystemFlags](https://docs.inductiveautomation.com/display/DOC81/system.util.getSystemFlags)

Not sure how this relates to the discussion about time though. An instant in time, represented in milliseconds since epoch UTC, is the same instant no matter what scope you are in.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:27pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/11 "2023-10-18T22:27:48Z")

</div>

> Not sure how this relates to the discussion about time though. An instant in time, represented in milliseconds since epoch UTC, is the same instant no matter what scope you are in.

You might want to go take a look at some of the vision client behavior -- I am assuming this is a windows clock problem; I can't force windows to syncronize system clocks well enough to solve this to the second. I see something like a 35 second difference in the results of datetime.now() between my laptop (designer and client) and another laptop with a vision client installed. It was the impetus of this entire exercise.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:31pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/12 "2023-10-18T22:31:33Z")

</div>

> [@Kevin.Herron](#):
>
> Partly you should just know what scope you are executing your code in

As someone who has been using Ignition a fair amount for about a year now, I still have a very hard time "just knowing" which it is. I am getting better and better, but clearly it is not clear and obvious.

"You should just know" is the kind of thing that some of my worst professors would say. The professors that have been so deep for so long in the understanding of a system that they have forgotten what it is like to not "just know" everything.

I need to know _how to know_, otherwise I will be bothering people on the forums for a lot longer than anyone would like 😉

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:32pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/13 "2023-10-18T22:32:44Z")

</div>

I mean, I get what you're saying, but it's not a crazy leap. Did you write your code in a button handler? It's client. Did you write it in a tag change script? It's gateway.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:33pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/14 "2023-10-18T22:33:06Z")

</div>

Perhaps a cheat sheet would be useful.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:33pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/15 "2023-10-18T22:33:52Z")

</div>

Yeah, might be. I'll raise that with the docs team. Might be something for the user manual if it doesn't exist already.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 10:38pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/16 "2023-10-18T22:38:48Z")

</div>

And if it does exist, some kind of hook to have it obviously available and indexed well -- I have not come across one and I have been 10 tabs deep in the docs for a year now.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:48pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/17 "2023-10-18T22:48:23Z")

</div>

> [@Kevin.Herron](#):
>
> ```auto
> iso_now = system.date.format(now, "yyyy-MM-dd'T'HH:mm:ss'Z'")
> 
> print iso_now
> 
> ```

I didn't notice because I was going too fast, but this doesn't actually work. It assumes the timezone is UTC already. The code I wrote to parse an ISO-8601 formatted date afterwards does work, though.

The actual code to format a date into UTC time for display is ugly enough that it probably does warrant a system scripting function.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 18, 2023, 10:55pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/18 "2023-10-18T22:55:53Z")

</div>

That said, I think the date formatting stuff was a distraction.

Your original goal to pass a time reference to clients should be as simple as:

```auto
def handleMessage(payload):
	return system.date.now()

```

The question is: what do you need to do with that reference once you've received it in the client that you weren't able to do?

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [October 18, 2023, 11:42pm UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/19 "2023-10-18T23:42:33Z")

</div>

> [@Kevin.Herron](#):
>
> ```auto
> def handleMessage(payload):
> return system.date.now()
> 
> ```

Yes I will be using this and going from there.

I was trying to build a timer that I could override with a button. It worked (using datetime.now()) on my machine exactly as expected, but does not work on a deployed vision client. I believe this is because my laptop has better time syncronization with our gateway, somehow. I actually don't know for sure.

The implementation of the timer was using an expression tag that takes a delta from a memory tag loaded with a datetime.now() object (which I believe runs on the gateway). I had a second expression tag that was whether or not the timer had hit the threshold, which returned a bool value that was then bound to the enabled field on a button. I believe the problem stemmed from the setting of the timer, which was (in the original implementation) a datetime.now() object from the client. I observed by triggering the system that it was getting an initial time delta of -35 rather than zero.

I actually have not been able to iterate on this today, due to a GUI bug that caused an engineer to delete the contents of an entire tag provider while he was trying to delete SFC objects. Our backups just came online. We are trying to determine the exact repro steps so that we can submit a bug report.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 20, 2023, 6:20am UTC](https://forum.inductiveautomation.com/t/gateway-message-handler-translates-a-datetime-now-command-into-a-java-sql-timestamp-how-can-i-change-it-back/80628/20 "2023-10-20T06:20:07Z")

</div>

> [@sherman](#):
>
> I believe this is because my laptop has better time syncronization with our gateway, somehow. I actually don't know for sure.

You should be using an [NTP server](https://en.wikipedia.org/wiki/Network_Time_Protocol) to keep your clients and gateway synchronized.
