diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ee47df3..8f5c9578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## Next Release + +- Fix date format prasing issue, closes Github issue [#333](https://github.com/EasyPost/easypost-java/issues/333) + ## v7.4.2 (2024-08-09) - Fix pagination parameters for `getNextPage` in `User` service diff --git a/src/main/java/com/easypost/model/DateDeserializer.java b/src/main/java/com/easypost/model/DateDeserializer.java index f639f6c1..ea0ff00d 100644 --- a/src/main/java/com/easypost/model/DateDeserializer.java +++ b/src/main/java/com/easypost/model/DateDeserializer.java @@ -13,43 +13,10 @@ public class DateDeserializer implements JsonDeserializer { private static final String[] DATE_FORMATS = new String[]{ - // Basic formats - "yyyy-MM-dd", + // EasyPost API returns below date formats + "yyyy-MM-dd'T'HH:mm:ssX", "yyyy-MM-dd'T'HH:mm:ss", - "yyyy-MM-dd'T'HH:mm:ss'Z'", - - // With milliseconds - "yyyy-MM-dd'T'HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", - - // With time zone offset - "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ssXXX", - - // Alternative time formats - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm:ss.SSS", - - // Month and day only "yyyy-MM-dd", - "MM/dd/yyyy", - "MM-dd-yyyy", - - // Year and week - "yyyy-'W'ww", - "yyyy-'W'ww-u", - - // Full date and time - "EEE, d MMM yyyy HH:mm:ss Z", - "EEE, d MMM yyyy HH:mm:ss z", - "EEEE, MMMM d, yyyy h:mm:ss a", - - // Short formats - "M/d/yy", - "M-d-yy", - "M.d.yy", - "MM/dd/yyyy", - "MM-dd-yyyy" }; /** @@ -70,9 +37,11 @@ public Date deserialize(JsonElement json, Type type, JsonDeserializationContext sdf.setTimeZone(TimeZone.getTimeZone("UTC")); return sdf.parse(json.getAsString()); } catch (ParseException e) { - throw new JsonParseException("Unable to parse this date format"); + // Continue to try the next format } } + + // Throw an exception if no formats matched from the DATE_FORMATS throw new JsonParseException("Unparseable date: \"" + json.getAsString() + "\""); } } diff --git a/src/test/java/com/easypost/DateDeserializerTest.java b/src/test/java/com/easypost/DateDeserializerTest.java new file mode 100644 index 00000000..72843dce --- /dev/null +++ b/src/test/java/com/easypost/DateDeserializerTest.java @@ -0,0 +1,91 @@ +package com.easypost; + +import com.easypost.model.DateDeserializer; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import org.junit.jupiter.api.Test; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DateDeserializerTest { + private final Gson gson = new GsonBuilder() + .registerTypeAdapter(Date.class, new DateDeserializer()) + .create(); + + /** + * Get hour in UTC time zone. + * + * @param date The input date object. + * @return int of hour in UTC time zone. + */ + public static int getUtcHour(Date date) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTime(date); + return calendar.get(Calendar.HOUR_OF_DAY); + } + + /** + * Get date of the month in UTC time zone. + * + * @param date The input date object. + * @return int of date in UTC time zone. + */ + public static int getUtcDate(Date date) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTime(date); + return calendar.get(Calendar.DAY_OF_MONTH); + } + + /** + * Test parsing a date format (yyyy-MM-dd'T'HH:mm:ssX). + * + */ + @Test + public void testDeserializeIso8601WithTimezone() { + String json = "\"2024-09-11T10:15:30Z\""; + Date date = gson.fromJson(json, Date.class); + + assertEquals(8, date.getMonth()); // .getMonth() returns between 0 and 11, with the value 0 representing January + assertEquals(11, date.getDate()); + assertEquals(10, getUtcHour(date)); + assertEquals(15, date.getMinutes()); + assertEquals(30, date.getSeconds()); + } + + /** + * Test parsing a date format (yyyy-MM-dd'T'HH:mm:ss). + * + */ + @Test + public void testDeserializeIso8601WithoutTimezone() { + String json = "\"2024-09-11T10:15:30\""; + Date date = gson.fromJson(json, Date.class); + + assertEquals(8, date.getMonth()); + assertEquals(11, date.getDate()); + assertEquals(10, getUtcHour(date)); + assertEquals(15, date.getMinutes()); + assertEquals(30, date.getSeconds()); + } + + /** + * Test parsing a regular date format (yyyy-MM-dd). + * + */ + @Test + public void testDeserializeRegularDateFormat() { + String json = "\"2024-09-11\""; + Date date = gson.fromJson(json, Date.class); + + assertEquals(8, date.getMonth()); + assertEquals(11, getUtcDate(date)); + assertEquals(0, getUtcHour(date)); + assertEquals(0, date.getMinutes()); + assertEquals(0, date.getSeconds()); + } +}