# Returning JSON With Date

**URL:** <https://forum.inductiveautomation.com/t/returning-json-with-date/106486>\
**Category:** Module Development\
**Tags:** perspective, scripting\
**Created:** [May 21, 2025, 3:49am UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486 "2025-05-21T03:49:55Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [May 21, 2025, 3:49am UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/1 "2025-05-21T03:49:55Z")

</div>

I've been scripting a few RPC calls in a module of ours, and I would ultimately like to return a Document/JSON object that will contain a few dates inside of it. I thought using java.util.Date would be best to work with the rest of Ignition, but when I return my data it's treated as a PyUnicode object in designer instead of a native date. What's the right way to return a date?

For the most part, I've been using Gson to return a JsonTree whenever I'm returning a dictionary to Perspective and it seems to natively work except for dates.

```python
return gson.toJsonTree(...myReturnPOJOHere);

```

---

<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:** [May 21, 2025, 12:21pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/2 "2025-05-21T12:21:08Z")

</div>

You need to register a type adapter when you build your GSON instance that has serialization logic for a Date.

```java
    public static class DateAdapter implements JsonDeserializer<Date>, JsonSerializer<Date> {

        @Override
        public Date deserialize(JsonElement jsonElement, Type type,
                                JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            if (jsonElement.isJsonPrimitive()) {
                if (jsonElement.getAsJsonPrimitive().isNumber()) {
                    return new Date(jsonElement.getAsJsonPrimitive().getAsLong());
                } else {
                    return TypeUtilities.toDate(jsonElement.getAsString());
                }
            }
            throw new JsonParseException("Unable to parse as date.");
        }

        @Override
        public JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
            return new JsonPrimitive(date.getTime());
        }
    }

```

---

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [May 21, 2025, 1:54pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/3 "2025-05-21T13:54:08Z")

</div>

Ok so we did that with Instants before but I was thinking it'd be nice to return it as a native date. I can see in a view json that you have something like:

```python
    "startDate": {
      "$": [
        "ts",
        201,
        1747668532860
      ],
      "$ts": 1747075096000
    }

```

If I were to return a structure like that would it work as a native date?

What does the 201 mean? 😅

---

<div class="post-metadata">

**Author:** ![Cody\_Morgan](https://avatars.discourse-cdn.com/v4/letter/c/db5fbb/32.png) [@Cody\_Morgan](https://forum.inductiveautomation.com/u/Cody_Morgan)\
**Post date:** [May 21, 2025, 2:02pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/4 "2025-05-21T14:02:24Z")

</div>

Where do you get this JSON? This is not a standard format to represent a timestamp or date.

I don't think the JSON standard specifies how dates should be represented. There are conventions that people have somewhat standardized on, but you'll still need to define a TypeAdapter like Kevin suggested.

Another option for representation (instead of long) is a string that represents your date format (i.e. "MM/DD/YYYY"), but that leaves a bit more room for error (but is much easier to read).

EDIT: The format in this Stack Overflow answer is what we used at my last job-- it's fairly standard and easy to read. [https://stackoverflow.com/a/15952652](https://stackoverflow.com/a/15952652)

---

<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:** [May 21, 2025, 2:40pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/5 "2025-05-21T14:40:39Z")

</div>

> [@cody.tamaki](#):
>
> native date

There is no such thing as a "native date" in JSON. You have to invent a representation.

In this context you're talking about JSON as a serialization format, so the representation can be anything as long as both sides agree on it.

---

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [May 21, 2025, 2:47pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/6 "2025-05-21T14:47:50Z")

</div>

Ah sorry - I was meaning a java.util.Date. Basically so I can take a date out of the json object I pass and pass it right back into a different script endpoint on another screen.

---

<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:** [May 21, 2025, 2:48pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/7 "2025-05-21T14:48:04Z")

</div>

That's the type adapter solution I gave you.

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [May 21, 2025, 2:50pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/8 "2025-05-21T14:50:53Z")

</div>

For Perspective components, I’ve been using `toJsonDeep` with the `DollarQualified` format.

> **[BindingUtils](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.33/com/inductiveautomation/perspective/gateway/binding/BindingUtils.html#toJsonDeep(java.lang.Object))**
>
> declaration: package: com.inductiveautomation.perspective.gateway.binding, class: BindingUtils

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 21, 2025, 3:30pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/9 "2025-05-21T15:30:11Z")

</div>

If the desired end result is the format you posted above, `BindingUtils` is the way to go; what you have above is the 'dollar qualified' format Carl invented that attaches qualified values (quality code + timestamp) and some type metadata to objects.

---

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [May 21, 2025, 3:54pm UTC](https://forum.inductiveautomation.com/t/returning-json-with-date/106486/10 "2025-05-21T15:54:18Z")

</div>

Ok, I explored a few different options and in the end I'm just going to return the instant long. The "dollar qualified" format returned it how I wanted in perspective, but the same script wouldn't work in a normal gateway/designer python script, so determined it would be better for interoperability to return a long directly and have the user convert to java.util.Date in python if needed.
