使用 Instant 替代 Date (#2713)

* update

* update

* update

* update

* update

* Update

* update

* update

* Add more tests

* fix checkstyle
This commit is contained in:
Glavo
2024-02-13 15:29:54 +08:00
committed by GitHub
parent 95707560ef
commit 5d26a106e9
25 changed files with 177 additions and 231 deletions

View File

@@ -20,10 +20,9 @@ package org.jackhuang.hmcl.countly;
import org.jackhuang.hmcl.util.io.HttpRequest; import org.jackhuang.hmcl.util.io.HttpRequest;
import java.io.IOException; import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone;
import static org.jackhuang.hmcl.util.Pair.pair; import static org.jackhuang.hmcl.util.Pair.pair;
@@ -40,7 +39,7 @@ public class Countly {
pair("metrics", metrics), pair("metrics", metrics),
pair("device_id", deviceId), pair("device_id", deviceId),
pair("timestamp", Long.toString(System.currentTimeMillis())), pair("timestamp", Long.toString(System.currentTimeMillis())),
pair("tz", Integer.toString(TimeZone.getDefault().getOffset(new Date().getTime()) / 60000)), pair("tz", Integer.toString(getTimezoneOffset())),
pair("hour", Integer.toString(currentHour())), pair("hour", Integer.toString(currentHour())),
pair("dow", Integer.toString(currentDayOfWeek())), pair("dow", Integer.toString(currentDayOfWeek())),
pair("app_key", APP_KEY), pair("app_key", APP_KEY),
@@ -50,7 +49,7 @@ public class Countly {
} }
private static int getTimezoneOffset() { private static int getTimezoneOffset() {
return TimeZone.getDefault().getOffset(new Date().getTime()) / 60000; return ZonedDateTime.now().getOffset().getTotalSeconds() / 60;
} }
private static String getLocale() { private static String getLocale() {

View File

@@ -7,8 +7,8 @@ import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.io.File; import java.io.File;
import java.text.SimpleDateFormat; import java.time.LocalDateTime;
import java.util.Date; import java.time.format.DateTimeFormatter;
import java.util.Map; import java.util.Map;
import static org.jackhuang.hmcl.util.Lang.mapOf; import static org.jackhuang.hmcl.util.Lang.mapOf;
@@ -68,7 +68,7 @@ public class CrashReport {
public String getDisplayText() { public String getDisplayText() {
return "---- Hello Minecraft! Crash Report ----\n" + return "---- Hello Minecraft! Crash Report ----\n" +
" Version: " + Metadata.VERSION + "\n" + " Version: " + Metadata.VERSION + "\n" +
" Time: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n" + " Time: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + "\n" +
" Thread: " + thread + "\n" + " Thread: " + thread + "\n" +
"\n Content: \n " + "\n Content: \n " +
stackTrace + "\n\n" + stackTrace + "\n\n" +

View File

@@ -48,6 +48,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -103,7 +104,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
public Stream<Version> getDisplayVersions() { public Stream<Version> getDisplayVersions() {
return getVersions().stream() return getVersions().stream()
.filter(v -> !v.isHidden()) .filter(v -> !v.isHidden())
.sorted(Comparator.comparing((Version v) -> v.getReleaseTime() == null ? new Date(0L) : v.getReleaseTime()) .sorted(Comparator.comparing((Version v) -> Lang.requireNonNullElse(v.getReleaseTime(), Instant.EPOCH))
.thenComparing(v -> VersionNumber.asVersion(v.getId()))); .thenComparing(v -> VersionNumber.asVersion(v.getId())));
} }

View File

@@ -298,7 +298,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
content.setTitle(remoteVersion.getSelfVersion()); content.setTitle(remoteVersion.getSelfVersion());
if (remoteVersion.getReleaseDate() != null) { if (remoteVersion.getReleaseDate() != null) {
content.setSubtitle(formatDateTime(remoteVersion.getReleaseDate().toInstant())); content.setSubtitle(formatDateTime(remoteVersion.getReleaseDate()));
} else { } else {
content.setSubtitle(null); content.setSubtitle(null);
} }

View File

@@ -44,14 +44,15 @@ import org.jackhuang.hmcl.ui.nbt.NBTHelper;
import org.jackhuang.hmcl.ui.versions.GameAdvancedListItem; import org.jackhuang.hmcl.ui.versions.GameAdvancedListItem;
import org.jackhuang.hmcl.ui.versions.Versions; import org.jackhuang.hmcl.ui.versions.Versions;
import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.TaskCancellationAction; import org.jackhuang.hmcl.util.TaskCancellationAction;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.versioning.VersionNumber; import org.jackhuang.hmcl.util.versioning.VersionNumber;
import java.io.File; import java.io.File;
import java.time.Instant;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Level; import java.util.logging.Level;
@@ -118,8 +119,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
List<Version> children = repository.getVersions().parallelStream() List<Version> children = repository.getVersions().parallelStream()
.filter(version -> !version.isHidden()) .filter(version -> !version.isHidden())
.sorted(Comparator .sorted(Comparator
.comparing((Version version) -> version.getReleaseTime() == null ? new Date(0L) .comparing((Version version) -> Lang.requireNonNullElse(version.getReleaseTime(), Instant.EPOCH))
: version.getReleaseTime())
.thenComparing(version -> VersionNumber.asVersion(repository.getGameVersion(version).orElse(version.getId())))) .thenComparing(version -> VersionNumber.asVersion(repository.getGameVersion(version).orElse(version.getId()))))
.collect(Collectors.toList()); .collect(Collectors.toList());
runInFX(() -> { runInFX(() -> {

View File

@@ -34,7 +34,7 @@ import org.jackhuang.hmcl.util.Holder;
import org.jackhuang.hmcl.util.io.HttpRequest; import org.jackhuang.hmcl.util.io.HttpRequest;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@@ -128,7 +128,7 @@ public class SponsorPage extends StackPane {
private final String name; private final String name;
@SerializedName("create_time") @SerializedName("create_time")
private final Date createTime; private final Instant createTime;
@SerializedName("money") @SerializedName("money")
private final BigDecimal money; private final BigDecimal money;
@@ -140,10 +140,10 @@ public class SponsorPage extends StackPane {
private final String afdianId; private final String afdianId;
public Sponsor() { public Sponsor() {
this("", new Date(), BigDecimal.ZERO, "", ""); this("", Instant.now(), BigDecimal.ZERO, "", "");
} }
public Sponsor(String name, Date createTime, BigDecimal money, String contact, String afdianId) { public Sponsor(String name, Instant createTime, BigDecimal money, String contact, String afdianId) {
this.name = name; this.name = name;
this.createTime = createTime; this.createTime = createTime;
this.money = money; this.money = money;
@@ -155,7 +155,7 @@ public class SponsorPage extends StackPane {
return name; return name;
} }
public Date getCreateTime() { public Instant getCreateTime() {
return createTime; return createTime;
} }

View File

@@ -382,7 +382,7 @@ public class DownloadPage extends Control implements DecoratorPage {
TwoLineListItem content = new TwoLineListItem(); TwoLineListItem content = new TwoLineListItem();
HBox.setHgrow(content, Priority.ALWAYS); HBox.setHgrow(content, Priority.ALWAYS);
content.setTitle(dataItem.getName()); content.setTitle(dataItem.getName());
content.setSubtitle(FORMATTER.format(dataItem.getDatePublished().toInstant())); content.setSubtitle(FORMATTER.format(dataItem.getDatePublished()));
switch (dataItem.getVersionType()) { switch (dataItem.getVersionType()) {
case Alpha: case Alpha:

View File

@@ -22,7 +22,7 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.ToStringBuilder; import org.jackhuang.hmcl.util.ToStringBuilder;
import org.jackhuang.hmcl.util.versioning.VersionNumber; import org.jackhuang.hmcl.util.versioning.VersionNumber;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -36,7 +36,7 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
private final String libraryId; private final String libraryId;
private final String gameVersion; private final String gameVersion;
private final String selfVersion; private final String selfVersion;
private final Date releaseDate; private final Instant releaseDate;
private final List<String> urls; private final List<String> urls;
private final Type type; private final Type type;
@@ -47,7 +47,7 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
* @param selfVersion the version string of the remote version. * @param selfVersion the version string of the remote version.
* @param urls the installer or universal jar original URL. * @param urls the installer or universal jar original URL.
*/ */
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Date releaseDate, List<String> urls) { public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Instant releaseDate, List<String> urls) {
this(libraryId, gameVersion, selfVersion, releaseDate, Type.UNCATEGORIZED, urls); this(libraryId, gameVersion, selfVersion, releaseDate, Type.UNCATEGORIZED, urls);
} }
@@ -58,7 +58,7 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
* @param selfVersion the version string of the remote version. * @param selfVersion the version string of the remote version.
* @param urls the installer or universal jar URL. * @param urls the installer or universal jar URL.
*/ */
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Date releaseDate, Type type, List<String> urls) { public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Instant releaseDate, Type type, List<String> urls) {
this.libraryId = Objects.requireNonNull(libraryId); this.libraryId = Objects.requireNonNull(libraryId);
this.gameVersion = Objects.requireNonNull(gameVersion); this.gameVersion = Objects.requireNonNull(gameVersion);
this.selfVersion = Objects.requireNonNull(selfVersion); this.selfVersion = Objects.requireNonNull(selfVersion);
@@ -83,7 +83,7 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
return getSelfVersion(); return getSelfVersion();
} }
public Date getReleaseDate() { public Instant getReleaseDate() {
return releaseDate; return releaseDate;
} }

View File

@@ -24,7 +24,7 @@ import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.mod.RemoteMod; import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
public class FabricAPIRemoteVersion extends RemoteVersion { public class FabricAPIRemoteVersion extends RemoteVersion {
@@ -38,7 +38,7 @@ public class FabricAPIRemoteVersion extends RemoteVersion {
* @param selfVersion the version string of the remote version. * @param selfVersion the version string of the remote version.
* @param urls the installer or universal jar original URL. * @param urls the installer or universal jar original URL.
*/ */
FabricAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Date datePublished, RemoteMod.Version version, List<String> urls) { FabricAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteMod.Version version, List<String> urls) {
super(LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId(), gameVersion, selfVersion, datePublished, urls); super(LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId(), gameVersion, selfVersion, datePublished, urls);
this.fullVersion = fullVersion; this.fullVersion = fullVersion;

View File

@@ -109,7 +109,7 @@ public final class ForgeBMCLVersionList extends VersionList<ForgeRemoteVersion>
} }
versions.put(gameVersion, new ForgeRemoteVersion( versions.put(gameVersion, new ForgeRemoteVersion(
version.getGameVersion(), version.getVersion(), releaseDate == null ? null : Date.from(releaseDate), urls)); version.getGameVersion(), version.getVersion(), releaseDate, urls));
} }
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();

View File

@@ -23,7 +23,7 @@ import org.jackhuang.hmcl.download.RemoteVersion;
import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
public class ForgeRemoteVersion extends RemoteVersion { public class ForgeRemoteVersion extends RemoteVersion {
@@ -34,7 +34,7 @@ public class ForgeRemoteVersion extends RemoteVersion {
* @param selfVersion the version string of the remote version. * @param selfVersion the version string of the remote version.
* @param url the installer or universal jar original URL. * @param url the installer or universal jar original URL.
*/ */
public ForgeRemoteVersion(String gameVersion, String selfVersion, Date releaseDate, List<String> url) { public ForgeRemoteVersion(String gameVersion, String selfVersion, Instant releaseDate, List<String> url) {
super(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), gameVersion, selfVersion, releaseDate, url); super(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), gameVersion, selfVersion, releaseDate, url);
} }

View File

@@ -25,7 +25,7 @@ import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Immutable; import org.jackhuang.hmcl.util.Immutable;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
/** /**
@@ -37,7 +37,7 @@ public final class GameRemoteVersion extends RemoteVersion {
private final ReleaseType type; private final ReleaseType type;
public GameRemoteVersion(String gameVersion, String selfVersion, List<String> url, ReleaseType type, Date releaseDate) { public GameRemoteVersion(String gameVersion, String selfVersion, List<String> url, ReleaseType type, Instant releaseDate) {
super(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId(), gameVersion, selfVersion, releaseDate, getReleaseType(type), url); super(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId(), gameVersion, selfVersion, releaseDate, getReleaseType(type), url);
this.type = type; this.type = type;
} }

View File

@@ -24,7 +24,7 @@ import org.jackhuang.hmcl.util.Constants;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.Validation; import org.jackhuang.hmcl.util.gson.Validation;
import java.util.Date; import java.time.Instant;
/** /**
* *
@@ -36,10 +36,10 @@ public final class GameRemoteVersionInfo implements Validation {
private final String gameVersion; private final String gameVersion;
@SerializedName("time") @SerializedName("time")
private final Date time; private final Instant time;
@SerializedName("releaseTime") @SerializedName("releaseTime")
private final Date releaseTime; private final Instant releaseTime;
@SerializedName("type") @SerializedName("type")
private final ReleaseType type; private final ReleaseType type;
@@ -48,14 +48,14 @@ public final class GameRemoteVersionInfo implements Validation {
private final String url; private final String url;
public GameRemoteVersionInfo() { public GameRemoteVersionInfo() {
this("", new Date(), new Date(), ReleaseType.UNKNOWN); this("", Instant.now(), Instant.now(), ReleaseType.UNKNOWN);
} }
public GameRemoteVersionInfo(String gameVersion, Date time, Date releaseTime, ReleaseType type) { public GameRemoteVersionInfo(String gameVersion, Instant time, Instant releaseTime, ReleaseType type) {
this(gameVersion, time, releaseTime, type, Constants.DEFAULT_LIBRARY_URL + gameVersion + "/" + gameVersion + ".json"); this(gameVersion, time, releaseTime, type, Constants.DEFAULT_LIBRARY_URL + gameVersion + "/" + gameVersion + ".json");
} }
public GameRemoteVersionInfo(String gameVersion, Date time, Date releaseTime, ReleaseType type, String url) { public GameRemoteVersionInfo(String gameVersion, Instant time, Instant releaseTime, ReleaseType type, String url) {
this.gameVersion = gameVersion; this.gameVersion = gameVersion;
this.time = time; this.time = time;
this.releaseTime = releaseTime; this.releaseTime = releaseTime;
@@ -67,11 +67,11 @@ public final class GameRemoteVersionInfo implements Validation {
return gameVersion; return gameVersion;
} }
public Date getTime() { public Instant getTime() {
return time; return time;
} }
public Date getReleaseTime() { public Instant getReleaseTime() {
return releaseTime; return releaseTime;
} }

View File

@@ -24,7 +24,7 @@ import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.mod.RemoteMod; import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
public class QuiltAPIRemoteVersion extends RemoteVersion { public class QuiltAPIRemoteVersion extends RemoteVersion {
@@ -38,7 +38,7 @@ public class QuiltAPIRemoteVersion extends RemoteVersion {
* @param selfVersion the version string of the remote version. * @param selfVersion the version string of the remote version.
* @param urls the installer or universal jar original URL. * @param urls the installer or universal jar original URL.
*/ */
QuiltAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Date datePublished, RemoteMod.Version version, List<String> urls) { QuiltAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteMod.Version version, List<String> urls) {
super(LibraryAnalyzer.LibraryType.QUILT_API.getPatchId(), gameVersion, selfVersion, datePublished, urls); super(LibraryAnalyzer.LibraryType.QUILT_API.getPatchId(), gameVersion, selfVersion, datePublished, urls);
this.fullVersion = fullVersion; this.fullVersion = fullVersion;

View File

@@ -18,8 +18,8 @@
package org.jackhuang.hmcl.game; package org.jackhuang.hmcl.game;
import java.io.File; import java.io.File;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
/** /**
* The Minecraft version for 1.5.x and earlier. * The Minecraft version for 1.5.x and earlier.
@@ -32,7 +32,7 @@ public class ClassicVersion extends Version {
super(true, "Classic", null, null, "${auth_player_name} ${auth_session} --workDir ${game_directory}", super(true, "Classic", null, null, "${auth_player_name} ${auth_session} --workDir ${game_directory}",
null, "net.minecraft.client.Minecraft", null, null, null, null, null, null, null, "net.minecraft.client.Minecraft", null, null, null, null, null, null,
Arrays.asList(new ClassicLibrary("lwjgl"), new ClassicLibrary("jinput"), new ClassicLibrary("lwjgl_util")), Arrays.asList(new ClassicLibrary("lwjgl"), new ClassicLibrary("jinput"), new ClassicLibrary("lwjgl_util")),
null, null, null, ReleaseType.UNKNOWN, new Date(), new Date(), 0, false, false, null); null, null, null, ReleaseType.UNKNOWN, Instant.now(), Instant.now(), 0, false, false, null);
} }
private static class ClassicLibrary extends Library { private static class ClassicLibrary extends Library {

View File

@@ -28,10 +28,10 @@ import org.jackhuang.hmcl.util.gson.JsonMap;
import org.jackhuang.hmcl.util.gson.Validation; import org.jackhuang.hmcl.util.gson.Validation;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -66,8 +66,8 @@ public class Version implements Comparable<Version>, Validation {
private final JsonMap<DownloadType, DownloadInfo> downloads; private final JsonMap<DownloadType, DownloadInfo> downloads;
private final JsonMap<DownloadType, LoggingInfo> logging; private final JsonMap<DownloadType, LoggingInfo> logging;
private final ReleaseType type; private final ReleaseType type;
private final Date time; private final Instant time;
private final Date releaseTime; private final Instant releaseTime;
private final Integer minimumLauncherVersion; private final Integer minimumLauncherVersion;
private final Boolean root; private final Boolean root;
private final Boolean hidden; private final Boolean hidden;
@@ -93,7 +93,7 @@ public class Version implements Comparable<Version>, Validation {
this(false, id, version, priority, null, arguments, mainClass, null, null, null, null, null, null, libraries, null, null, null, null, null, null, null, null, null, null); this(false, id, version, priority, null, arguments, mainClass, null, null, null, null, null, null, libraries, null, null, null, null, null, null, null, null, null, null);
} }
public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, GameJavaVersion javaVersion, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Boolean hidden, Boolean root, List<Version> patches) { public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, GameJavaVersion javaVersion, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Instant time, Instant releaseTime, Integer minimumLauncherVersion, Boolean hidden, Boolean root, List<Version> patches) {
this.resolved = resolved; this.resolved = resolved;
this.id = id; this.id = id;
this.version = version; this.version = version;
@@ -112,8 +112,8 @@ public class Version implements Comparable<Version>, Validation {
this.downloads = downloads == null ? null : new JsonMap<>(downloads); this.downloads = downloads == null ? null : new JsonMap<>(downloads);
this.logging = logging == null ? null : new JsonMap<>(logging); this.logging = logging == null ? null : new JsonMap<>(logging);
this.type = type; this.type = type;
this.time = time == null ? null : (Date) time.clone(); this.time = time;
this.releaseTime = releaseTime == null ? null : (Date) releaseTime.clone(); this.releaseTime = releaseTime;
this.minimumLauncherVersion = minimumLauncherVersion; this.minimumLauncherVersion = minimumLauncherVersion;
this.hidden = hidden; this.hidden = hidden;
this.root = root; this.root = root;
@@ -132,7 +132,7 @@ public class Version implements Comparable<Version>, Validation {
return mainClass; return mainClass;
} }
public Date getTime() { public Instant getTime() {
return time; return time;
} }
@@ -158,7 +158,7 @@ public class Version implements Comparable<Version>, Validation {
return type == null ? ReleaseType.UNKNOWN : type; return type == null ? ReleaseType.UNKNOWN : type;
} }
public Date getReleaseTime() { public Instant getReleaseTime() {
return releaseTime; return releaseTime;
} }

View File

@@ -24,7 +24,7 @@ import org.jackhuang.hmcl.util.gson.TolerableValidationException;
import org.jackhuang.hmcl.util.gson.Validation; import org.jackhuang.hmcl.util.gson.Validation;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -46,12 +46,12 @@ public class TLauncherVersion implements Validation {
private final JsonMap<DownloadType, DownloadInfo> downloads; private final JsonMap<DownloadType, DownloadInfo> downloads;
private final JsonMap<DownloadType, LoggingInfo> logging; private final JsonMap<DownloadType, LoggingInfo> logging;
private final ReleaseType type; private final ReleaseType type;
private final Date time; private final Instant time;
private final Date releaseTime; private final Instant releaseTime;
private final Integer minimumLauncherVersion; private final Integer minimumLauncherVersion;
private final Integer tlauncherVersion; private final Integer tlauncherVersion;
public TLauncherVersion(String id, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, @Nullable GameJavaVersion javaVersion, List<TLauncherLibrary> libraries, List<CompatibilityRule> compatibilityRules, JsonMap<DownloadType, DownloadInfo> downloads, JsonMap<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Integer tlauncherVersion) { public TLauncherVersion(String id, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, @Nullable GameJavaVersion javaVersion, List<TLauncherLibrary> libraries, List<CompatibilityRule> compatibilityRules, JsonMap<DownloadType, DownloadInfo> downloads, JsonMap<DownloadType, LoggingInfo> logging, ReleaseType type, Instant time, Instant releaseTime, Integer minimumLauncherVersion, Integer tlauncherVersion) {
this.id = id; this.id = id;
this.minecraftArguments = minecraftArguments; this.minecraftArguments = minecraftArguments;
this.arguments = arguments; this.arguments = arguments;

View File

@@ -22,7 +22,7 @@ import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.FileDownloadTask;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -218,14 +218,14 @@ public class RemoteMod {
private final String name; private final String name;
private final String version; private final String version;
private final String changelog; private final String changelog;
private final Date datePublished; private final Instant datePublished;
private final VersionType versionType; private final VersionType versionType;
private final File file; private final File file;
private final List<Dependency> dependencies; private final List<Dependency> dependencies;
private final List<String> gameVersions; private final List<String> gameVersions;
private final List<ModLoaderType> loaders; private final List<ModLoaderType> loaders;
public Version(IVersion self, String modid, String name, String version, String changelog, Date datePublished, VersionType versionType, File file, List<Dependency> dependencies, List<String> gameVersions, List<ModLoaderType> loaders) { public Version(IVersion self, String modid, String name, String version, String changelog, Instant datePublished, VersionType versionType, File file, List<Dependency> dependencies, List<String> gameVersions, List<ModLoaderType> loaders) {
this.self = self; this.self = self;
this.modid = modid; this.modid = modid;
this.name = name; this.name = name;
@@ -259,7 +259,7 @@ public class RemoteMod {
return changelog; return changelog;
} }
public Date getDatePublished() { public Instant getDatePublished() {
return datePublished; return datePublished;
} }

View File

@@ -26,6 +26,7 @@ import org.jackhuang.hmcl.util.Pair;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -58,15 +59,15 @@ public class CurseAddon implements RemoteMod.IMod {
private final int mainFileId; private final int mainFileId;
private final List<LatestFile> latestFiles; private final List<LatestFile> latestFiles;
private final List<LatestFileIndex> latestFileIndices; private final List<LatestFileIndex> latestFileIndices;
private final Date dateCreated; private final Instant dateCreated;
private final Date dateModified; private final Instant dateModified;
private final Date dateReleased; private final Instant dateReleased;
private final boolean allowModDistribution; private final boolean allowModDistribution;
private final int gamePopularityRank; private final int gamePopularityRank;
private final boolean isAvailable; private final boolean isAvailable;
private final int thumbsUpCount; private final int thumbsUpCount;
public CurseAddon(int id, int gameId, String name, String slug, Links links, String summary, int status, int downloadCount, boolean isFeatured, int primaryCategoryId, List<Category> categories, int classId, List<Author> authors, Logo logo, int mainFileId, List<LatestFile> latestFiles, List<LatestFileIndex> latestFileIndices, Date dateCreated, Date dateModified, Date dateReleased, boolean allowModDistribution, int gamePopularityRank, boolean isAvailable, int thumbsUpCount) { public CurseAddon(int id, int gameId, String name, String slug, Links links, String summary, int status, int downloadCount, boolean isFeatured, int primaryCategoryId, List<Category> categories, int classId, List<Author> authors, Logo logo, int mainFileId, List<LatestFile> latestFiles, List<LatestFileIndex> latestFileIndices, Instant dateCreated, Instant dateModified, Instant dateReleased, boolean allowModDistribution, int gamePopularityRank, boolean isAvailable, int thumbsUpCount) {
this.id = id; this.id = id;
this.gameId = gameId; this.gameId = gameId;
this.name = name; this.name = name;
@@ -161,15 +162,15 @@ public class CurseAddon implements RemoteMod.IMod {
return latestFileIndices; return latestFileIndices;
} }
public Date getDateCreated() { public Instant getDateCreated() {
return dateCreated; return dateCreated;
} }
public Date getDateModified() { public Instant getDateModified() {
return dateModified; return dateModified;
} }
public Date getDateReleased() { public Instant getDateReleased() {
return dateReleased; return dateReleased;
} }
@@ -438,7 +439,7 @@ public class CurseAddon implements RemoteMod.IMod {
private final int releaseType; private final int releaseType;
private final int fileStatus; private final int fileStatus;
private final List<LatestFileHash> hashes; private final List<LatestFileHash> hashes;
private final Date fileDate; private final Instant fileDate;
private final int fileLength; private final int fileLength;
private final int downloadCount; private final int downloadCount;
private final String downloadUrl; private final String downloadUrl;
@@ -448,7 +449,7 @@ public class CurseAddon implements RemoteMod.IMod {
private final boolean isServerPack; private final boolean isServerPack;
private final long fileFingerprint; private final long fileFingerprint;
public LatestFile(int id, int gameId, int modId, boolean isAvailable, String displayName, String fileName, int releaseType, int fileStatus, List<LatestFileHash> hashes, Date fileDate, int fileLength, int downloadCount, String downloadUrl, List<String> gameVersions, List<Dependency> dependencies, int alternateFileId, boolean isServerPack, long fileFingerprint) { public LatestFile(int id, int gameId, int modId, boolean isAvailable, String displayName, String fileName, int releaseType, int fileStatus, List<LatestFileHash> hashes, Instant fileDate, int fileLength, int downloadCount, String downloadUrl, List<String> gameVersions, List<Dependency> dependencies, int alternateFileId, boolean isServerPack, long fileFingerprint) {
this.id = id; this.id = id;
this.gameId = gameId; this.gameId = gameId;
this.modId = modId; this.modId = modId;
@@ -505,7 +506,7 @@ public class CurseAddon implements RemoteMod.IMod {
return hashes; return hashes;
} }
public Date getFileDate() { public Instant getFileDate() {
return fileDate; return fileDate;
} }
@@ -650,7 +651,7 @@ public class CurseAddon implements RemoteMod.IMod {
private final String slug; private final String slug;
private final String url; private final String url;
private final String iconUrl; private final String iconUrl;
private final Date dateModified; private final Instant dateModified;
private final boolean isClass; private final boolean isClass;
private final int classId; private final int classId;
private final int parentCategoryId; private final int parentCategoryId;
@@ -658,10 +659,10 @@ public class CurseAddon implements RemoteMod.IMod {
private transient final List<Category> subcategories; private transient final List<Category> subcategories;
public Category() { public Category() {
this(0, 0, "", "", "", "", new Date(), false, 0, 0); this(0, 0, "", "", "", "", Instant.now(), false, 0, 0);
} }
public Category(int id, int gameId, String name, String slug, String url, String iconUrl, Date dateModified, boolean isClass, int classId, int parentCategoryId) { public Category(int id, int gameId, String name, String slug, String url, String iconUrl, Instant dateModified, boolean isClass, int classId, int parentCategoryId) {
this.id = id; this.id = id;
this.gameId = gameId; this.gameId = gameId;
this.name = name; this.name = name;
@@ -700,7 +701,7 @@ public class CurseAddon implements RemoteMod.IMod {
return iconUrl; return iconUrl;
} }
public Date getDateModified() { public Instant getDateModified() {
return dateModified; return dateModified;
} }

View File

@@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -210,13 +211,13 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
private final String team; private final String team;
private final Date published; private final Instant published;
private final Date updated; private final Instant updated;
private final List<String> versions; private final List<String> versions;
public Project(String slug, String title, String description, List<String> categories, String body, String projectType, int downloads, String iconUrl, String id, String team, Date published, Date updated, List<String> versions) { public Project(String slug, String title, String description, List<String> categories, String body, String projectType, int downloads, String iconUrl, String id, String team, Instant published, Instant updated, List<String> versions) {
this.slug = slug; this.slug = slug;
this.title = title; this.title = title;
this.description = description; this.description = description;
@@ -272,11 +273,11 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
return team; return team;
} }
public Date getPublished() { public Instant getPublished() {
return published; return published;
} }
public Date getUpdated() { public Instant getUpdated() {
return updated; return updated;
} }
@@ -381,7 +382,7 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
private final String authorId; private final String authorId;
@SerializedName("date_published") @SerializedName("date_published")
private final Date datePublished; private final Instant datePublished;
private final int downloads; private final int downloads;
@@ -390,7 +391,7 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
private final List<ProjectVersionFile> files; private final List<ProjectVersionFile> files;
public ProjectVersion(String name, String versionNumber, String changelog, List<Dependency> dependencies, List<String> gameVersions, String versionType, List<String> loaders, boolean featured, String id, String projectId, String authorId, Date datePublished, int downloads, String changelogUrl, List<ProjectVersionFile> files) { public ProjectVersion(String name, String versionNumber, String changelog, List<Dependency> dependencies, List<String> gameVersions, String versionType, List<String> loaders, boolean featured, String id, String projectId, String authorId, Instant datePublished, int downloads, String changelogUrl, List<ProjectVersionFile> files) {
this.name = name; this.name = name;
this.versionNumber = versionNumber; this.versionNumber = versionNumber;
this.changelog = changelog; this.changelog = changelog;
@@ -452,7 +453,7 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
return authorId; return authorId;
} }
public Date getDatePublished() { public Instant getDatePublished() {
return datePublished; return datePublished;
} }
@@ -587,15 +588,15 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
private final List<String> versions; private final List<String> versions;
@SerializedName("date_created") @SerializedName("date_created")
private final Date dateCreated; private final Instant dateCreated;
@SerializedName("date_modified") @SerializedName("date_modified")
private final Date dateModified; private final Instant dateModified;
@SerializedName("latest_version") @SerializedName("latest_version")
private final String latestVersion; private final String latestVersion;
public ProjectSearchResult(String slug, String title, String description, List<String> categories, String projectType, int downloads, String iconUrl, String projectId, String author, List<String> versions, Date dateCreated, Date dateModified, String latestVersion) { public ProjectSearchResult(String slug, String title, String description, List<String> categories, String projectType, int downloads, String iconUrl, String projectId, String author, List<String> versions, Instant dateCreated, Instant dateModified, String latestVersion) {
this.slug = slug; this.slug = slug;
this.title = title; this.title = title;
this.description = description; this.description = description;
@@ -651,11 +652,11 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
return versions; return versions;
} }
public Date getDateCreated() { public Instant getDateCreated() {
return dateCreated; return dateCreated;
} }
public Date getDateModified() { public Instant getDateModified() {
return dateModified; return dateModified;
} }

View File

@@ -22,9 +22,10 @@ import org.jackhuang.hmcl.util.io.IOUtils;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.text.MessageFormat; import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.logging.*; import java.util.logging.*;
/** /**
@@ -120,35 +121,39 @@ public final class Logging {
} }
} }
private static final MessageFormat FORMAT = new MessageFormat("[{0,date,HH:mm:ss}] [{1}.{2}/{3}] {4}\n"); private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss").withZone(ZoneId.systemDefault());
private static String format(LogRecord record) { private static String format(LogRecord record) {
String message = filterForbiddenToken(record.getMessage()); String message = filterForbiddenToken(record.getMessage());
StringBuilder builder = new StringBuilder(128 + message.length());
builder.append('[');
TIME_FORMATTER.formatTo(Instant.ofEpochMilli(record.getMillis()), builder);
builder.append(']');
builder.append(" [")
.append(record.getSourceClassName())
.append('.')
.append(record.getSourceMethodName())
.append('/')
.append(record.getLevel().getName())
.append("] ")
.append(message)
.append('\n');
Throwable thrown = record.getThrown(); Throwable thrown = record.getThrown();
StringWriter writer;
StringBuffer buffer;
if (thrown == null) { if (thrown == null) {
writer = null; return builder.toString();
buffer = new StringBuffer(256);
} else { } else {
writer = new StringWriter(1024); StringWriter writer = new StringWriter(builder.length() + 2048);
buffer = writer.getBuffer(); writer.getBuffer().append(builder);
}
FORMAT.format(new Object[]{
new Date(record.getMillis()),
record.getSourceClassName(), record.getSourceMethodName(), record.getLevel().getName(),
message
}, buffer, null);
if (thrown != null) {
try (PrintWriter printWriter = new PrintWriter(writer)) { try (PrintWriter printWriter = new PrintWriter(writer)) {
thrown.printStackTrace(printWriter); thrown.printStackTrace(printWriter);
} }
return writer.toString();
} }
return buffer.toString();
} }
private static final class DefaultFormatter extends Formatter { private static final class DefaultFormatter extends Formatter {

View File

@@ -1,106 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util.gson;
import com.google.gson.*;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
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
*/
public final class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
public static final DateTypeAdapter INSTANCE = new DateTypeAdapter();
private DateTypeAdapter() {
}
@Override
public JsonElement serialize(Date t, Type type, JsonSerializationContext jsc) {
synchronized (EN_US_FORMAT) {
return new JsonPrimitive(serializeToString(t));
}
}
@Override
public Date deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
if (!(json instanceof JsonPrimitive))
throw new JsonParseException("The date should be a string value");
else {
Date date = deserializeToDate(json.getAsString());
if (type == Date.class)
return date;
else
throw new IllegalArgumentException(this.getClass().toString() + " cannot be deserialized to " + type);
}
}
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, ISO_DATE_TIME);
return Date.from(zonedDateTime.toInstant());
} catch (DateTimeParseException e) {
try {
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, e);
}
}
}
}
}
public static String serializeToString(Date date) {
synchronized (EN_US_FORMAT) {
String result = ISO_8601_FORMAT.format(date);
return result.substring(0, 22) + ":" + result.substring(22);
}
}
}

View File

@@ -20,9 +20,15 @@ package org.jackhuang.hmcl.util.gson;
import com.google.gson.*; import com.google.gson.*;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.time.Instant; import java.time.*;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME;
public final class InstantTypeAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant> { public final class InstantTypeAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant> {
public static final InstantTypeAdapter INSTANCE = new InstantTypeAdapter(); public static final InstantTypeAdapter INSTANCE = new InstantTypeAdapter();
@@ -31,21 +37,53 @@ public final class InstantTypeAdapter implements JsonSerializer<Instant>, JsonDe
} }
@Override @Override
public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public JsonElement serialize(Instant t, Type type, JsonSerializationContext jsc) {
if (!(json instanceof JsonPrimitive)) { return new JsonPrimitive(serializeToString(t, ZoneId.systemDefault()));
}
@Override
public Instant deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
if (!(json instanceof JsonPrimitive))
throw new JsonParseException("The instant should be a string value"); throw new JsonParseException("The instant should be a string value");
} else { else {
Instant instant = Instant.parse(json.getAsString()); Instant time = deserializeToInstant(json.getAsString());
if (typeOfT == Instant.class) { if (type == Instant.class)
return instant; return time;
} else { else
throw new IllegalArgumentException(this.getClass() + " cannot be deserialized to " + typeOfT); throw new IllegalArgumentException(this.getClass() + " cannot be deserialized to " + type);
}
}
private static final DateTimeFormatter EN_US_FORMAT = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM)
.withLocale(Locale.US)
.withZone(ZoneId.systemDefault());
private static final DateTimeFormatter ISO_DATE_TIME = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.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 Instant deserializeToInstant(String string) {
try {
return ZonedDateTime.parse(string, EN_US_FORMAT).toInstant();
} catch (DateTimeParseException ex1) {
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(string, ISO_DATE_TIME);
return zonedDateTime.toInstant();
} catch (DateTimeParseException e) {
try {
LocalDateTime localDateTime = LocalDateTime.parse(string, ISO_LOCAL_DATE_TIME);
return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
} catch (DateTimeParseException e2) {
throw new JsonParseException("Invalid instant: " + string, e);
}
} }
} }
} }
@Override public static String serializeToString(Instant instant, ZoneId zone) {
public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) { return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.ofInstant(instant, zone).truncatedTo(ChronoUnit.SECONDS));
return new JsonPrimitive(DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.systemDefault()).format(src));
} }
} }

View File

@@ -29,7 +29,6 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -113,7 +112,6 @@ public final class JsonUtils {
.enableComplexMapKeySerialization() .enableComplexMapKeySerialization()
.setPrettyPrinting() .setPrettyPrinting()
.registerTypeAdapter(Instant.class, InstantTypeAdapter.INSTANCE) .registerTypeAdapter(Instant.class, InstantTypeAdapter.INSTANCE)
.registerTypeAdapter(Date.class, DateTypeAdapter.INSTANCE)
.registerTypeAdapter(UUID.class, UUIDTypeAdapter.INSTANCE) .registerTypeAdapter(UUID.class, UUIDTypeAdapter.INSTANCE)
.registerTypeAdapter(File.class, FileTypeAdapter.INSTANCE) .registerTypeAdapter(File.class, FileTypeAdapter.INSTANCE)
.registerTypeAdapterFactory(ValidationTypeAdapterFactory.INSTANCE) .registerTypeAdapterFactory(ValidationTypeAdapterFactory.INSTANCE)

View File

@@ -2,29 +2,38 @@ package org.jackhuang.hmcl.util.gson;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class DateTypeAdapterTest { public class InstantTypeAdapterTest {
@Test @Test
public void parse() { public void testDeserialize() {
assertEquals( assertEquals(
LocalDateTime.of(2017, 6, 8, 4, 26, 33) LocalDateTime.of(2017, 6, 8, 4, 26, 33)
.atOffset(ZoneOffset.UTC).toInstant(), .atOffset(ZoneOffset.UTC).toInstant(),
DateTypeAdapter.deserializeToDate("2017-06-08T04:26:33+0000").toInstant()); InstantTypeAdapter.deserializeToInstant("2017-06-08T04:26:33+0000"));
assertEquals( assertEquals(
LocalDateTime.of(2021, 1, 3, 0, 53, 34) LocalDateTime.of(2021, 1, 3, 0, 53, 34)
.atOffset(ZoneOffset.UTC).toInstant(), .atOffset(ZoneOffset.UTC).toInstant(),
DateTypeAdapter.deserializeToDate("2021-01-03T00:53:34+00:00").toInstant()); InstantTypeAdapter.deserializeToInstant("2021-01-03T00:53:34+00:00"));
assertEquals( assertEquals(
LocalDateTime.of(2021, 1, 3, 0, 53, 34) LocalDateTime.of(2021, 1, 3, 0, 53, 34)
.atZone(ZoneId.systemDefault()).toInstant(), .atZone(ZoneId.systemDefault()).toInstant(),
DateTypeAdapter.deserializeToDate("2021-01-03T00:53:34").toInstant()); InstantTypeAdapter.deserializeToInstant("2021-01-03T00:53:34"));
}
@Test
public void testSerialize() {
assertEquals(
"2024-02-13T15:11:06+08:00",
InstantTypeAdapter.serializeToString(Instant.ofEpochMilli(1707808266154L), ZoneOffset.ofHours(8))
);
} }
} }