重构本地化支持 (#4632)
This commit is contained in:
@@ -19,7 +19,7 @@ package org.jackhuang.hmcl.util.i18n;
|
|||||||
|
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
import org.jackhuang.hmcl.util.i18n.translator.Translator;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -55,6 +55,10 @@ public final class I18n {
|
|||||||
return locale.getResourceBundle();
|
return locale.getResourceBundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Translator getTranslator() {
|
||||||
|
return locale.getTranslator();
|
||||||
|
}
|
||||||
|
|
||||||
public static String i18n(String key, Object... formatArgs) {
|
public static String i18n(String key, Object... formatArgs) {
|
||||||
return locale.i18n(key, formatArgs);
|
return locale.i18n(key, formatArgs);
|
||||||
}
|
}
|
||||||
@@ -64,22 +68,11 @@ public final class I18n {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String formatDateTime(TemporalAccessor time) {
|
public static String formatDateTime(TemporalAccessor time) {
|
||||||
return locale.formatDateTime(time);
|
return getTranslator().formatDateTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDisplaySelfVersion(RemoteVersion version) {
|
public static String getDisplaySelfVersion(RemoteVersion version) {
|
||||||
if (locale.getLocale().getLanguage().equals("lzh")) {
|
return getTranslator().getDisplayVersion(version);
|
||||||
if (version instanceof GameRemoteVersion)
|
|
||||||
return WenyanUtils.translateGameVersion(GameVersionNumber.asGameVersion(version.getSelfVersion()));
|
|
||||||
else
|
|
||||||
return WenyanUtils.translateGenericVersion(version.getSelfVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LocaleUtils.isEnglish(locale.getLocale()) && "Qabs".equals(LocaleUtils.getScript(locale.getLocale()))) {
|
|
||||||
return UpsideDownUtils.translate(version.getSelfVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
return version.getSelfVersion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the builtin localized resource with given name and suffix.
|
/// Find the builtin localized resource with given name and suffix.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.translator.Translator_lzh;
|
||||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -36,9 +37,9 @@ public final class MinecraftWiki {
|
|||||||
if (wikiVersion.startsWith("2.0"))
|
if (wikiVersion.startsWith("2.0"))
|
||||||
translatedVersion = "二點〇";
|
translatedVersion = "二點〇";
|
||||||
else if (wikiVersion.startsWith("1.0.0-rc2"))
|
else if (wikiVersion.startsWith("1.0.0-rc2"))
|
||||||
translatedVersion = WenyanUtils.translateGameVersion(GameVersionNumber.asGameVersion("1.0.0-rc2"));
|
translatedVersion = Translator_lzh.translateGameVersion(GameVersionNumber.asGameVersion("1.0.0-rc2"));
|
||||||
else
|
else
|
||||||
translatedVersion = WenyanUtils.translateGameVersion(gameVersion);
|
translatedVersion = Translator_lzh.translateGameVersion(gameVersion);
|
||||||
|
|
||||||
if (translatedVersion.equals(gameVersion.toString()) || gameVersion instanceof GameVersionNumber.Old) {
|
if (translatedVersion.equals(gameVersion.toString()) || gameVersion instanceof GameVersionNumber.Old) {
|
||||||
return getWikiLink(SupportedLocale.getLocale(LocaleUtils.LOCALE_ZH_HANT), version);
|
return getWikiLink(SupportedLocale.getLocale(LocaleUtils.LOCALE_ZH_HANT), version);
|
||||||
|
|||||||
@@ -24,12 +24,13 @@ import com.google.gson.stream.JsonToken;
|
|||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.translator.Translator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.time.ZoneId;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@@ -74,8 +75,8 @@ public final class SupportedLocale {
|
|||||||
private final Locale locale;
|
private final Locale locale;
|
||||||
private ResourceBundle resourceBundle;
|
private ResourceBundle resourceBundle;
|
||||||
private ResourceBundle localeNamesBundle;
|
private ResourceBundle localeNamesBundle;
|
||||||
private DateTimeFormatter dateTimeFormatter;
|
|
||||||
private List<Locale> candidateLocales;
|
private List<Locale> candidateLocales;
|
||||||
|
private Translator translator;
|
||||||
|
|
||||||
SupportedLocale() {
|
SupportedLocale() {
|
||||||
this.isDefault = true;
|
this.isDefault = true;
|
||||||
@@ -200,23 +201,6 @@ public final class SupportedLocale {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatDateTime(TemporalAccessor time) {
|
|
||||||
DateTimeFormatter formatter = dateTimeFormatter;
|
|
||||||
if (formatter == null) {
|
|
||||||
if (LocaleUtils.isEnglish(locale) && "Qabs".equals(locale.getScript())) {
|
|
||||||
return UpsideDownUtils.formatDateTime(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locale.getLanguage().equals("lzh")) {
|
|
||||||
return WenyanUtils.formatDateTime(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
formatter = dateTimeFormatter = DateTimeFormatter.ofPattern(getResourceBundle().getString("datetime.format"))
|
|
||||||
.withZone(ZoneId.systemDefault());
|
|
||||||
}
|
|
||||||
return formatter.format(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFcMatchPattern() {
|
public String getFcMatchPattern() {
|
||||||
String language = locale.getLanguage();
|
String language = locale.getLanguage();
|
||||||
String region = locale.getCountry();
|
String region = locale.getCountry();
|
||||||
@@ -252,6 +236,31 @@ public final class SupportedLocale {
|
|||||||
return region.isEmpty() ? language : language + "-" + region;
|
return region.isEmpty() ? language : language + "-" + region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Translator getTranslator() {
|
||||||
|
Translator translator = this.translator;
|
||||||
|
if (translator != null)
|
||||||
|
return translator;
|
||||||
|
|
||||||
|
List<Locale> candidateLocales = getCandidateLocales();
|
||||||
|
|
||||||
|
for (Locale candidateLocale : candidateLocales) {
|
||||||
|
String className = DefaultResourceBundleControl.INSTANCE.toBundleName(Translator.class.getSimpleName(), candidateLocale);
|
||||||
|
if (Translator.class.getResource(className + ".class") != null) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName(Translator.class.getPackageName() + "." + className);
|
||||||
|
|
||||||
|
MethodHandle constructor = MethodHandles.publicLookup()
|
||||||
|
.findConstructor(clazz, MethodType.methodType(void.class, SupportedLocale.class));
|
||||||
|
|
||||||
|
return this.translator = (Translator) constructor.invoke(this);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LOG.warning("Failed to create instance for " + className, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.translator = new Translator(this);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSameLanguage(SupportedLocale other) {
|
public boolean isSameLanguage(SupportedLocale other) {
|
||||||
return LocaleUtils.getRootLanguage(this.getLocale())
|
return LocaleUtils.getRootLanguage(this.getLocale())
|
||||||
.equals(LocaleUtils.getRootLanguage(other.getLocale()));
|
.equals(LocaleUtils.getRootLanguage(other.getLocale()));
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2025 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.i18n.translator;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.SupportedLocale;
|
||||||
|
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/// @author Glavo
|
||||||
|
public class Translator {
|
||||||
|
protected final SupportedLocale supportedLocale;
|
||||||
|
protected final Locale locale;
|
||||||
|
|
||||||
|
public Translator(SupportedLocale supportedLocale) {
|
||||||
|
this.supportedLocale = supportedLocale;
|
||||||
|
this.locale = supportedLocale.getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final SupportedLocale getSupportedLocale() {
|
||||||
|
return supportedLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Locale getLocale() {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayVersion(RemoteVersion remoteVersion) {
|
||||||
|
return remoteVersion.getSelfVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @see [#formatDateTime(TemporalAccessor)]
|
||||||
|
protected DateTimeFormatter dateTimeFormatter;
|
||||||
|
|
||||||
|
public String formatDateTime(TemporalAccessor time) {
|
||||||
|
DateTimeFormatter formatter = dateTimeFormatter;
|
||||||
|
if (formatter == null) {
|
||||||
|
formatter = dateTimeFormatter = DateTimeFormatter.ofPattern(supportedLocale.getResourceBundle().getString("datetime.format"))
|
||||||
|
.withZone(ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
return formatter.format(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,7 +15,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n.translator;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.SupportedLocale;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -30,13 +33,16 @@ import java.util.Map;
|
|||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public final class UpsideDownUtils {
|
public class Translator_en_Qabs extends Translator {
|
||||||
|
private static final DateTimeFormatter BASE_FORMATTER = DateTimeFormatter.ofPattern("MMM d, yyyy, h:mm:ss a")
|
||||||
|
.withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
private static final Map<Integer, Integer> MAPPER = loadMap();
|
private static final Map<Integer, Integer> MAPPER = loadMap();
|
||||||
|
|
||||||
private static Map<Integer, Integer> loadMap() {
|
private static Map<Integer, Integer> loadMap() {
|
||||||
var map = new LinkedHashMap<Integer, Integer>();
|
var map = new LinkedHashMap<Integer, Integer>();
|
||||||
|
|
||||||
InputStream inputStream = UpsideDownUtils.class.getResourceAsStream("/assets/lang/upside_down.txt");
|
InputStream inputStream = Translator_en_Qabs.class.getResourceAsStream("/assets/lang/upside_down.txt");
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
try (inputStream) {
|
try (inputStream) {
|
||||||
new String(inputStream.readAllBytes(), StandardCharsets.UTF_8).lines().forEach(line -> {
|
new String(inputStream.readAllBytes(), StandardCharsets.UTF_8).lines().forEach(line -> {
|
||||||
@@ -65,13 +71,17 @@ public final class UpsideDownUtils {
|
|||||||
return builder.reverse().toString();
|
return builder.reverse().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final DateTimeFormatter BASE_FORMATTER = DateTimeFormatter.ofPattern("MMM d, yyyy, h:mm:ss a")
|
public Translator_en_Qabs(SupportedLocale locale) {
|
||||||
.withZone(ZoneId.systemDefault());
|
super(locale);
|
||||||
|
}
|
||||||
|
|
||||||
public static String formatDateTime(TemporalAccessor time) {
|
@Override
|
||||||
|
public String getDisplayVersion(RemoteVersion remoteVersion) {
|
||||||
|
return translate(remoteVersion.getSelfVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String formatDateTime(TemporalAccessor time) {
|
||||||
return translate(BASE_FORMATTER.format(time));
|
return translate(BASE_FORMATTER.format(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpsideDownUtils() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -15,8 +15,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n.translator;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.SupportedLocale;
|
||||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -27,10 +30,8 @@ import java.util.Locale;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/// @author Glavo
|
||||||
* @author Glavo
|
public class Translator_lzh extends Translator {
|
||||||
*/
|
|
||||||
public final class WenyanUtils {
|
|
||||||
private static final String DOT = "點";
|
private static final String DOT = "點";
|
||||||
|
|
||||||
private static final String[] NUMBERS = {
|
private static final String[] NUMBERS = {
|
||||||
@@ -79,37 +80,8 @@ public final class WenyanUtils {
|
|||||||
builder.append(hour % 2 == 0 ? '正' : '初');
|
builder.append(hour % 2 == 0 ? '正' : '初');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String formatDateTime(TemporalAccessor time) {
|
|
||||||
LocalDateTime localDateTime;
|
|
||||||
if (time instanceof Instant)
|
|
||||||
localDateTime = ((Instant) time).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
||||||
else
|
|
||||||
localDateTime = LocalDateTime.from(time);
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder(16);
|
|
||||||
|
|
||||||
appendYear(builder, localDateTime.getYear());
|
|
||||||
builder.append('年');
|
|
||||||
builder.append(numberToString(localDateTime.getMonthValue()));
|
|
||||||
builder.append('月');
|
|
||||||
builder.append(numberToString(localDateTime.getDayOfMonth()));
|
|
||||||
builder.append('日');
|
|
||||||
|
|
||||||
builder.append(' ');
|
|
||||||
|
|
||||||
appendHour(builder, localDateTime.getHour());
|
|
||||||
builder.append(numberToString(localDateTime.getMinute()));
|
|
||||||
builder.append('分');
|
|
||||||
builder.append(numberToString(localDateTime.getSecond()));
|
|
||||||
builder.append('秒');
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String translateGameVersion(GameVersionNumber gameVersion) {
|
public static String translateGameVersion(GameVersionNumber gameVersion) {
|
||||||
if (gameVersion instanceof GameVersionNumber.Release) {
|
if (gameVersion instanceof GameVersionNumber.Release release) {
|
||||||
var release = (GameVersionNumber.Release) gameVersion;
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
appendDigitByDigit(builder, String.valueOf(release.getMajor()));
|
appendDigitByDigit(builder, String.valueOf(release.getMajor()));
|
||||||
builder.append(DOT);
|
builder.append(DOT);
|
||||||
@@ -120,6 +92,7 @@ public final class WenyanUtils {
|
|||||||
appendDigitByDigit(builder, String.valueOf(release.getPatch()));
|
appendDigitByDigit(builder, String.valueOf(release.getPatch()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
if (release.getEaType() == GameVersionNumber.Release.TYPE_GA) {
|
if (release.getEaType() == GameVersionNumber.Release.TYPE_GA) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (release.getEaType() == GameVersionNumber.Release.TYPE_PRE) {
|
} else if (release.getEaType() == GameVersionNumber.Release.TYPE_PRE) {
|
||||||
@@ -134,9 +107,7 @@ public final class WenyanUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
} else if (gameVersion instanceof GameVersionNumber.Snapshot) {
|
} else if (gameVersion instanceof GameVersionNumber.Snapshot snapshot) {
|
||||||
var snapshot = (GameVersionNumber.Snapshot) gameVersion;
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
appendDigitByDigit(builder, String.valueOf(snapshot.getYear()));
|
appendDigitByDigit(builder, String.valueOf(snapshot.getYear()));
|
||||||
@@ -152,35 +123,20 @@ public final class WenyanUtils {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
} else if (gameVersion instanceof GameVersionNumber.Special) {
|
} else if (gameVersion instanceof GameVersionNumber.Special) {
|
||||||
String version = gameVersion.toString();
|
String version = gameVersion.toString();
|
||||||
switch (version.toLowerCase(Locale.ROOT)) {
|
return switch (version.toLowerCase(Locale.ROOT)) {
|
||||||
case "2.0":
|
case "2.0" -> "二點〇";
|
||||||
return "二點〇";
|
case "2.0_blue" -> "二點〇藍";
|
||||||
case "2.0_blue":
|
case "2.0_red" -> "二點〇赤";
|
||||||
return "二點〇藍";
|
case "2.0_purple" -> "二點〇紫";
|
||||||
case "2.0_red":
|
case "1.rv-pre1" -> "一點真視之預一";
|
||||||
return "二點〇赤";
|
case "3d shareware v1.34" -> "躍然享件一點三四";
|
||||||
case "2.0_purple":
|
case "20w14infinite", "20w14~", "20w14∞" -> "二〇週一四宇";
|
||||||
return "二點〇紫";
|
case "22w13oneblockatatime" -> "二二週一三典";
|
||||||
case "1.rv-pre1":
|
case "23w13a_or_b" -> "二三週一三暨";
|
||||||
return "一點真視之預一";
|
case "24w14potato" -> "二四週一四芋";
|
||||||
case "3d shareware v1.34":
|
case "25w14craftmine" -> "二五週一四礦";
|
||||||
return "躍然享件一點三四";
|
default -> version;
|
||||||
case "20w14infinite":
|
};
|
||||||
case "20w14~":
|
|
||||||
case "20w14∞":
|
|
||||||
return "二〇週一四宇";
|
|
||||||
case "22w13oneblockatatime":
|
|
||||||
return "二二週一三典";
|
|
||||||
case "23w13a_or_b":
|
|
||||||
return "二三週一三暨";
|
|
||||||
case "24w14potato":
|
|
||||||
return "二四週一四芋";
|
|
||||||
case "25w14craftmine":
|
|
||||||
return "二五週一四礦";
|
|
||||||
default:
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return gameVersion.toString();
|
return gameVersion.toString();
|
||||||
}
|
}
|
||||||
@@ -211,6 +167,43 @@ public final class WenyanUtils {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WenyanUtils() {
|
public Translator_lzh(SupportedLocale locale) {
|
||||||
|
super(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayVersion(RemoteVersion remoteVersion) {
|
||||||
|
if (remoteVersion instanceof GameRemoteVersion)
|
||||||
|
return translateGameVersion(GameVersionNumber.asGameVersion(remoteVersion.getSelfVersion()));
|
||||||
|
else
|
||||||
|
return translateGenericVersion(remoteVersion.getSelfVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String formatDateTime(TemporalAccessor time) {
|
||||||
|
LocalDateTime localDateTime;
|
||||||
|
if (time instanceof Instant instant)
|
||||||
|
localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
else
|
||||||
|
localDateTime = LocalDateTime.from(time);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder(16);
|
||||||
|
|
||||||
|
appendYear(builder, localDateTime.getYear());
|
||||||
|
builder.append('年');
|
||||||
|
builder.append(numberToString(localDateTime.getMonthValue()));
|
||||||
|
builder.append('月');
|
||||||
|
builder.append(numberToString(localDateTime.getDayOfMonth()));
|
||||||
|
builder.append('日');
|
||||||
|
|
||||||
|
builder.append(' ');
|
||||||
|
|
||||||
|
appendHour(builder, localDateTime.getHour());
|
||||||
|
builder.append(numberToString(localDateTime.getMinute()));
|
||||||
|
builder.append('分');
|
||||||
|
builder.append(numberToString(localDateTime.getSecond()));
|
||||||
|
builder.append('秒');
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n.translator;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -26,33 +26,36 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* @author Glavo
|
* @author Glavo
|
||||||
*/
|
*/
|
||||||
public final class WenyanUtilsTest {
|
public final class TranslatorTest {
|
||||||
|
|
||||||
private static void assertYearToString(String value, int year) {
|
//region lzh
|
||||||
|
|
||||||
|
private static void assertYearToLZH(String value, int year) {
|
||||||
StringBuilder builder = new StringBuilder(2);
|
StringBuilder builder = new StringBuilder(2);
|
||||||
WenyanUtils.appendYear(builder, year);
|
Translator_lzh.appendYear(builder, year);
|
||||||
assertEquals(value, builder.toString());
|
assertEquals(value, builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testYearToString() {
|
public void testYearToLZH() {
|
||||||
assertYearToString("甲子", 1984);
|
assertYearToLZH("甲子", 1984);
|
||||||
assertYearToString("乙巳", 2025);
|
assertYearToLZH("乙巳", 2025);
|
||||||
assertYearToString("甲子", -2996);
|
assertYearToLZH("甲子", -2996);
|
||||||
assertYearToString("庚子", 1000);
|
assertYearToLZH("庚子", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHourToString() {
|
public void testHourToLZH() {
|
||||||
|
|
||||||
List<String> list = List.of(
|
List<String> list = List.of(
|
||||||
"子正", "丑初", "丑正", "寅初", "寅正", "卯初", "卯正", "辰初", "辰正", "巳初", "巳正", "午初",
|
"子正", "丑初", "丑正", "寅初", "寅正", "卯初", "卯正", "辰初", "辰正", "巳初", "巳正", "午初",
|
||||||
"午正", "未初", "未正", "申初", "申正", "酉初", "酉正", "戌初", "戌正", "亥初", "亥正", "子初"
|
"午正", "未初", "未正", "申初", "申正", "酉初", "酉正", "戌初", "戌正", "亥初", "亥正", "子初"
|
||||||
);
|
);
|
||||||
for (int hour = 0; hour < list.size(); hour++) {
|
for (int hour = 0; hour < list.size(); hour++) {
|
||||||
StringBuilder builder = new StringBuilder(2);
|
StringBuilder builder = new StringBuilder(2);
|
||||||
WenyanUtils.appendHour(builder, hour);
|
Translator_lzh.appendHour(builder, hour);
|
||||||
assertEquals(list.get(hour), builder.toString());
|
assertEquals(list.get(hour), builder.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user