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.
You need to register a type adapter when you build your GSON instance that has serialization logic for a Date.
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());
}
}
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:
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
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.
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.
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.