From df6230fc0132520b481161efd0415d1f082a6ad2 Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Fri, 3 Jun 2022 23:13:40 +0800 Subject: [PATCH] fix(install): date deserialization. Closes #1512. --- .../hmcl/util/gson/DateTypeAdapter.java | 17 +++++++++-- .../hmcl/util/gson/DateTypeAdapterTest.java | 28 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 HMCLCore/src/test/java/org/jackhuang/hmcl/util/gson/DateTypeAdapterTest.java diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/DateTypeAdapter.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/DateTypeAdapter.java index b53ae0e4b..6d1d007b7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/DateTypeAdapter.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/DateTypeAdapter.java @@ -27,10 +27,13 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.util.Date; import java.util.Locale; +import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME; + /** * * @author huangyuhui @@ -65,20 +68,28 @@ public final class DateTypeAdapter implements JsonSerializer, JsonDeserial public static final DateFormat EN_US_FORMAT = DateFormat.getDateTimeInstance(2, 2, Locale.US); public static final DateFormat ISO_8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + public static final DateTimeFormatter ISO_DATE_TIME = new DateTimeFormatterBuilder() + .append(ISO_LOCAL_DATE_TIME) + .optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd() + .optionalStart().appendOffset("+HHMM", "+0000").optionalEnd() + .optionalStart().appendOffset("+HH", "Z").optionalEnd() + .optionalStart().appendOffsetId().optionalEnd() + .toFormatter(); + public static Date deserializeToDate(String string) { synchronized (EN_US_FORMAT) { try { return EN_US_FORMAT.parse(string); } catch (ParseException ex1) { try { - ZonedDateTime zonedDateTime = ZonedDateTime.parse(string, DateTimeFormatter.ISO_DATE_TIME); + ZonedDateTime zonedDateTime = ZonedDateTime.parse(string, ISO_DATE_TIME); return Date.from(zonedDateTime.toInstant()); } catch (DateTimeParseException e) { try { - LocalDateTime localDateTime = LocalDateTime.parse(string, DateTimeFormatter.ISO_LOCAL_DATE_TIME); + LocalDateTime localDateTime = LocalDateTime.parse(string, ISO_LOCAL_DATE_TIME); return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); } catch (DateTimeParseException e2) { - throw new JsonParseException("Invalid date: " + string, e2); + throw new JsonParseException("Invalid date: " + string, e); } } } diff --git a/HMCLCore/src/test/java/org/jackhuang/hmcl/util/gson/DateTypeAdapterTest.java b/HMCLCore/src/test/java/org/jackhuang/hmcl/util/gson/DateTypeAdapterTest.java new file mode 100644 index 000000000..8eff68937 --- /dev/null +++ b/HMCLCore/src/test/java/org/jackhuang/hmcl/util/gson/DateTypeAdapterTest.java @@ -0,0 +1,28 @@ +package org.jackhuang.hmcl.util.gson; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +public class DateTypeAdapterTest { + + @Test + public void parse() { + Assert.assertEquals( + LocalDateTime.of(2017, 6, 8, 4, 26, 33) + .atOffset(ZoneOffset.UTC).toInstant(), + DateTypeAdapter.deserializeToDate("2017-06-08T04:26:33+0000").toInstant()); + + Assert.assertEquals( + LocalDateTime.of(2021, 1, 3, 0, 53, 34) + .atOffset(ZoneOffset.UTC).toInstant(), + DateTypeAdapter.deserializeToDate("2021-01-03T00:53:34+00:00").toInstant()); + + Assert.assertEquals( + LocalDateTime.of(2021, 1, 3, 0, 53, 34) + .atOffset(ZoneOffset.UTC).toInstant(), + DateTypeAdapter.deserializeToDate("2021-01-03T00:53:34").toInstant()); + } +}