diff --git a/analytics-core/src/main/java/com/segment/analytics/gson/ISO8601InstantAdapter.java b/analytics-core/src/main/java/com/segment/analytics/gson/ISO8601InstantAdapter.java new file mode 100644 index 00000000..c21638ad --- /dev/null +++ b/analytics-core/src/main/java/com/segment/analytics/gson/ISO8601InstantAdapter.java @@ -0,0 +1,37 @@ +package com.segment.analytics.gson; + +import com.google.gson.*; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.lang.reflect.Type; +import java.time.Instant; + +/** + * A {@link JsonSerializer} that formats {@link Instant} objects into iso8601 formatted strings, and + * {@link JsonDeserializer} that parses iso8601 formatted strings into {@link Instant} objects. + */ +public class ISO8601InstantAdapter extends TypeAdapter + implements JsonSerializer, JsonDeserializer { + @Override + public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(Iso8601Utils.format(src)); // ISO 8601 format + } + + @Override + public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + return Instant.parse(json.getAsString()); + } + + @Override + public void write(JsonWriter out, Instant value) throws IOException { + out.value(value == null ? null : value.toString()); + } + + @Override + public Instant read(JsonReader in) throws IOException { + String str = in.nextString(); + return str == null ? null : Instant.parse(str); + } +} diff --git a/analytics-core/src/main/java/com/segment/analytics/gson/Iso8601Utils.java b/analytics-core/src/main/java/com/segment/analytics/gson/Iso8601Utils.java index 9504a641..95ca5286 100644 --- a/analytics-core/src/main/java/com/segment/analytics/gson/Iso8601Utils.java +++ b/analytics-core/src/main/java/com/segment/analytics/gson/Iso8601Utils.java @@ -16,6 +16,7 @@ package com.segment.analytics.gson; import com.google.gson.JsonParseException; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -277,4 +278,10 @@ private static int indexOfNonDigit(String string, int offset) { } return string.length(); } + + /** Returns {@code date} formatted as yyyy-MM-ddThh:mm:ss.sssZ */ + static String format(Instant instant) { + // Format the instant + return String.valueOf(instant.getEpochSecond()); + } } diff --git a/analytics/src/main/java/com/segment/analytics/Analytics.java b/analytics/src/main/java/com/segment/analytics/Analytics.java index 81af36c7..9b88de8c 100644 --- a/analytics/src/main/java/com/segment/analytics/Analytics.java +++ b/analytics/src/main/java/com/segment/analytics/Analytics.java @@ -4,11 +4,13 @@ import com.google.gson.GsonBuilder; import com.segment.analytics.gson.AutoValueAdapterFactory; import com.segment.analytics.gson.ISO8601DateAdapter; +import com.segment.analytics.gson.ISO8601InstantAdapter; import com.segment.analytics.http.SegmentService; import com.segment.analytics.internal.AnalyticsClient; import com.segment.analytics.internal.AnalyticsVersion; import com.segment.analytics.messages.Message; import com.segment.analytics.messages.MessageBuilder; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -362,6 +364,7 @@ public Analytics build() { gsonBuilder .registerTypeAdapterFactory(new AutoValueAdapterFactory()) + .registerTypeAdapter(Instant.class, new ISO8601InstantAdapter()) .registerTypeAdapter(Date.class, new ISO8601DateAdapter()); Gson gson = gsonBuilder.create();