Serializing DATETIME and INTERVAL values in standard formats

Use the datetimeSerializationMode and intervalSerializationMode options to output DATETIME values in RFC 3339 format and INTERVAL values in ISO 8601 duration format.

By default, the JSON serializer writes DATETIME and INTERVAL values in the Genero string representation. You can change this behavior using the datetimeSerializationMode and intervalSerializationMode options.

The following example sets both options and serializes a DATETIME YEAR TO SECOND and an INTERVAL DAY TO SECOND value to JSON. The options are reset to their defaults at the end of the program.

IMPORT json

MAIN
  DEFINE d  DATETIME YEAR TO SECOND
  DEFINE iv INTERVAL DAY TO SECOND

  LET d  = DATETIME(2024-11-05 09:15:58) YEAR TO SECOND
  LET iv = INTERVAL(2 10:30:00) DAY TO SECOND

  -- DATETIME serialization modes
  CALL json.Serializer.setOption("datetimeSerializationMode", 0)
  DISPLAY "datetime mode 0 (FGL legacy)    : ", serializeDatetime(d)
  CALL json.Serializer.setOption("datetimeSerializationMode", 1)
  DISPLAY "datetime mode 1 (RFC 3339 UTC)  : ", serializeDatetime(d)
  CALL json.Serializer.setOption("datetimeSerializationMode", 2)
  DISPLAY "datetime mode 2 (RFC 3339 offset): ", serializeDatetime(d)

  -- INTERVAL serialization modes
  CALL json.Serializer.setOption("intervalSerializationMode", 0)
  DISPLAY "interval mode 0 (FGL legacy)    : ", serializeInterval(iv)
  CALL json.Serializer.setOption("intervalSerializationMode", 1)
  DISPLAY "interval mode 1 (ISO 8601)      : ", serializeInterval(iv)

  -- Restore defaults
  CALL json.Serializer.setOption("datetimeSerializationMode", 0)
  CALL json.Serializer.setOption("intervalSerializationMode", 0)
END MAIN

FUNCTION serializeDatetime(value)
  DEFINE value  DATETIME YEAR TO SECOND
  DEFINE writer json.JSONWriter
  DEFINE t      TEXT
  LOCATE t IN MEMORY
  LET writer = json.JSONWriter.Create()
  CALL writer.setOutputCharset("UTF-8")
  CALL writer.writeToText(t)
  CALL writer.startJSON()
  CALL json.Serializer.VariableToJSON(value, writer)
  CALL writer.endJSON()
  CALL writer.close()
  RETURN t
END FUNCTION

FUNCTION serializeInterval(value)
  DEFINE value  INTERVAL DAY TO SECOND
  DEFINE writer json.JSONWriter
  DEFINE t      TEXT
  LOCATE t IN MEMORY
  LET writer = json.JSONWriter.Create()
  CALL writer.setOutputCharset("UTF-8")
  CALL writer.writeToText(t)
  CALL writer.startJSON()
  CALL json.Serializer.VariableToJSON(value, writer)
  CALL writer.endJSON()
  CALL writer.close()
  RETURN t
END FUNCTION

The code above would generate the following output with TZ=UTC (GMT):

datetime mode 0 (FGL legacy)    : "2024-11-05 09:15:58"
datetime mode 1 (RFC 3339 UTC)  : "2024-11-05T09:15:58Z"
datetime mode 2 (RFC 3339 offset): "2024-11-05T09:15:58+00:00"
interval mode 0 (FGL legacy)    : "  2 10:30:00"
interval mode 1 (ISO 8601)      : "P2DT10H30M00S"