SafeCalendarJsonAdapter extends JsonAdapter<T> { @Override public T fromJson(JsonReader reader) throws IOException { String dateStr = reader.nextString(); if (dateStr.isEmpty()) return null; DateFormat format = null; for (Map.Entry<Pattern, ThreadLocal<SimpleDateFormat>> entry : DATE_FORMAT_MAP.entrySet()) { Matcher matcher = entry.getKey().matcher(dateStr); if (matcher.matches()) { format = entry.getValue().get(); break; } } if (format == null) { throw new AssertionError("Unsupported date format! Expecting ISO 8601, but found: " + dateStr); } try { Date date = format.parse(dateStr); String chosenPattern = ((SimpleDateFormat) format).toPattern(); Calendar calendar = new SafeCalendar(); resolveTimeZone(calendar, chosenPattern); calendar.clear(); calendar.setTime(date); clearCalendarByRegEx(calendar, chosenPattern); return (T) calendar; } catch (ParseException ex) { return null; } } SafeCalendarJsonAdapter(); static void resolveTimeZone(Calendar calendar, String chosenPattern); @Override T fromJson(JsonReader reader); @Override void toJson(JsonWriter writer, T calendar); @Override String toString(); static final Factory FACTORY; }
@Test public void nullIfEmpty() throws Exception { assertThat(calendarAdapter().fromJson("\"\"")).isNull(); }
@Test public void throwsUnknown() throws Exception { try { calendarAdapter().fromJson("\"2010-MAY-13\""); fail(); } catch (Throwable e) { assertThat(e).isInstanceOf(AssertionError.class) .hasMessage("Unsupported date format! Expecting ISO 8601, but found: 2010-MAY-13"); } }
@Test public void iso8601withTimeZone() throws Exception { Calendar fromJson = calendarAdapter().fromJson("\"2000-02-27T23:00:23+0200\""); assertThat(fromJson).isNotNull(); assertThat(fromJson.isSet(Calendar.SECOND)).isTrue(); assertThat(fromJson.isSet(Calendar.MINUTE)).isTrue(); assertThat(fromJson.isSet(Calendar.HOUR)).isTrue(); assertThat(fromJson.isSet(Calendar.DAY_OF_MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.YEAR)).isTrue(); assertThat(fromJson.get(Calendar.YEAR)).isEqualTo(2000); assertThat(fromJson.get(Calendar.MONTH)).isEqualTo(Calendar.FEBRUARY); assertThat(fromJson.get(Calendar.DAY_OF_MONTH)).isEqualTo(27); assertThat(fromJson.get(Calendar.HOUR_OF_DAY)).isEqualTo(22); assertThat(fromJson.get(Calendar.MINUTE)).isEqualTo(0); assertThat(fromJson.get(Calendar.SECOND)).isEqualTo(23); assertThat(fromJson.getTimeZone()).isEqualTo(TimeZone.getTimeZone("CET")); }
@Test public void threeLetterIso8601withTimeZone() throws Exception { Calendar fromJson1 = calendarAdapter().fromJson("\"2003-04-21T16:42:11+02:00\""); Calendar fromJson2 = calendarAdapter().fromJson("\"2016-07-21T17:59:59-04:00\""); assertThat(fromJson1).isNotNull(); assertThat(fromJson2).isNotNull(); assertThat(fromJson1.isSet(Calendar.SECOND)).isTrue(); assertThat(fromJson1.isSet(Calendar.MINUTE)).isTrue(); assertThat(fromJson1.isSet(Calendar.HOUR)).isTrue(); assertThat(fromJson1.isSet(Calendar.DAY_OF_MONTH)).isTrue(); assertThat(fromJson1.isSet(Calendar.MONTH)).isTrue(); assertThat(fromJson1.isSet(Calendar.YEAR)).isTrue(); assertThat(fromJson2.isSet(Calendar.SECOND)).isTrue(); assertThat(fromJson2.isSet(Calendar.MINUTE)).isTrue(); assertThat(fromJson2.isSet(Calendar.HOUR)).isTrue(); assertThat(fromJson2.isSet(Calendar.DAY_OF_MONTH)).isTrue(); assertThat(fromJson2.isSet(Calendar.MONTH)).isTrue(); assertThat(fromJson2.isSet(Calendar.YEAR)).isTrue(); assertThat(fromJson1.get(Calendar.YEAR)).isEqualTo(2003); assertThat(fromJson1.get(Calendar.MONTH)).isEqualTo(Calendar.APRIL); assertThat(fromJson1.get(Calendar.DAY_OF_MONTH)).isEqualTo(21); assertThat(fromJson1.get(Calendar.HOUR_OF_DAY)).isEqualTo(16); assertThat(fromJson1.get(Calendar.MINUTE)).isEqualTo(42); assertThat(fromJson1.get(Calendar.SECOND)).isEqualTo(11); assertThat(fromJson1.getTimeZone()).isEqualTo(TimeZone.getTimeZone("CET")); assertThat(fromJson2.get(Calendar.YEAR)).isEqualTo(2016); assertThat(fromJson2.get(Calendar.MONTH)).isEqualTo(Calendar.JULY); assertThat(fromJson2.get(Calendar.DAY_OF_MONTH)).isEqualTo(21); assertThat(fromJson2.get(Calendar.HOUR_OF_DAY)).isEqualTo(23); assertThat(fromJson2.get(Calendar.MINUTE)).isEqualTo(59); assertThat(fromJson2.get(Calendar.SECOND)).isEqualTo(59); assertThat(fromJson1.getTimeZone()).isEqualTo(TimeZone.getTimeZone("CET")); }
@Test public void iso8601withMilliseconds() throws Exception { Calendar fromJson = calendarAdapter().fromJson("\"2016-01-15T07:42:01.000Z\""); assertThat(fromJson).isNotNull(); assertThat(fromJson.isSet(Calendar.SECOND)).isTrue(); assertThat(fromJson.isSet(Calendar.MINUTE)).isTrue(); assertThat(fromJson.isSet(Calendar.HOUR)).isTrue(); assertThat(fromJson.isSet(Calendar.DAY_OF_MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.YEAR)).isTrue(); assertThat(fromJson.get(Calendar.YEAR)).isEqualTo(2016); assertThat(fromJson.get(Calendar.MONTH)).isEqualTo(Calendar.JANUARY); assertThat(fromJson.get(Calendar.DAY_OF_MONTH)).isEqualTo(15); assertThat(fromJson.get(Calendar.HOUR_OF_DAY)).isEqualTo(7); assertThat(fromJson.get(Calendar.MINUTE)).isEqualTo(42); assertThat(fromJson.get(Calendar.SECOND)).isEqualTo(1); }
@Test public void iso8601withMillisecondsAndOffset() throws Exception { Calendar fromJson = calendarAdapter().fromJson("\"2014-04-30T10:53:48.000+02:00\""); assertThat(fromJson).isNotNull(); assertThat(fromJson.isSet(Calendar.MILLISECOND)).isTrue(); assertThat(fromJson.isSet(Calendar.SECOND)).isTrue(); assertThat(fromJson.isSet(Calendar.MINUTE)).isTrue(); assertThat(fromJson.isSet(Calendar.HOUR)).isTrue(); assertThat(fromJson.isSet(Calendar.DAY_OF_MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.MONTH)).isTrue(); assertThat(fromJson.isSet(Calendar.YEAR)).isTrue(); assertThat(fromJson.get(Calendar.YEAR)).isEqualTo(2014); assertThat(fromJson.get(Calendar.MONTH)).isEqualTo(Calendar.APRIL); assertThat(fromJson.get(Calendar.DAY_OF_MONTH)).isEqualTo(30); assertThat(fromJson.get(Calendar.MINUTE)).isEqualTo(53); assertThat(fromJson.get(Calendar.SECOND)).isEqualTo(48); assertThat(fromJson.getTimeZone()).isEqualTo(TimeZone.getTimeZone("CET")); }