Skip to content

Commit e16b308

Browse files
committed
Parse ZoneIds
1 parent c374bfb commit e16b308

File tree

5 files changed

+223
-8
lines changed

5 files changed

+223
-8
lines changed

src/main/java/com/coditory/quark/i18n/Currencies.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Locale;
1111
import java.util.Map;
1212
import java.util.Optional;
13+
import java.util.Set;
1314

1415
import static com.coditory.quark.i18n.Preconditions.expectNonNull;
1516
import static java.util.Collections.unmodifiableMap;
@@ -50,6 +51,7 @@ public final class Currencies {
5051
*/
5152
public static final Currency PLN = Currency.getInstance("PLN");
5253

54+
private static final Set<Currency> AVAILABLE_CURRENCIES = Currency.getAvailableCurrencies();
5355
private static final Map<Currency, Locale> LOCALE_BY_CURRENCY;
5456

5557
static {
@@ -107,9 +109,7 @@ public static Currency parseCurrency(@NotNull String value) {
107109
} catch (Exception e) {
108110
throw new IllegalArgumentException("Could not parse Currency: '" + value + "'");
109111
}
110-
boolean isAvailable = Currency.getAvailableCurrencies()
111-
.contains(currency);
112-
if (!isAvailable) {
112+
if (!AVAILABLE_CURRENCIES.contains(currency)) {
113113
throw new IllegalArgumentException("Currency not available: '" + value + "'");
114114
}
115115
return currency;
@@ -118,7 +118,8 @@ public static Currency parseCurrency(@NotNull String value) {
118118
@Nullable
119119
public static Currency parseCurrencyOrNull(@NotNull String value) {
120120
try {
121-
return parseCurrency(value);
121+
Currency currency = Currency.getInstance(value.toUpperCase(Locale.ROOT).trim());
122+
return AVAILABLE_CURRENCIES.contains(currency) ? currency : null;
122123
} catch (Exception e) {
123124
return null;
124125
}

src/main/java/com/coditory/quark/i18n/Locales.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public static Locale parseLocale(@NotNull String value) {
118118
expectNonNull(value, "value");
119119
Locale locale;
120120
try {
121-
locale = Locale.forLanguageTag(value.replace("_", "-").trim());
121+
locale = Locale.forLanguageTag(value);
122122
} catch (Exception e) {
123123
throw new IllegalArgumentException("Could not parse Locale: '" + value + "'");
124124
}
@@ -131,7 +131,8 @@ public static Locale parseLocale(@NotNull String value) {
131131
@Nullable
132132
public static Locale parseLocaleOrNull(@NotNull String value) {
133133
try {
134-
return parseLocale(value);
134+
Locale locale = Locale.forLanguageTag(value);
135+
return isAvailable(locale) ? locale : null;
135136
} catch (Exception e) {
136137
return null;
137138
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package com.coditory.quark.i18n;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
import java.time.ZoneId;
7+
import java.util.Optional;
8+
import java.util.Set;
9+
10+
import static com.coditory.quark.i18n.Preconditions.expectNonNull;
11+
12+
public class ZoneIds {
13+
// Australia/Darwin
14+
public static final ZoneId ACT = ZoneId.of("ACT", ZoneId.SHORT_IDS);
15+
// Australia/Sydney
16+
public static final ZoneId AET = ZoneId.of("AET", ZoneId.SHORT_IDS);
17+
// America/Argentina/Buenos_Aires
18+
public static final ZoneId AGT = ZoneId.of("AGT", ZoneId.SHORT_IDS);
19+
// Africa/Cairo
20+
public static final ZoneId ART = ZoneId.of("ART", ZoneId.SHORT_IDS);
21+
// America/Anchorage
22+
public static final ZoneId AST = ZoneId.of("AST", ZoneId.SHORT_IDS);
23+
// America/Sao_Paulo
24+
public static final ZoneId BET = ZoneId.of("BET", ZoneId.SHORT_IDS);
25+
// Asia/Dhaka
26+
public static final ZoneId BST = ZoneId.of("BST", ZoneId.SHORT_IDS);
27+
// Africa/Harare
28+
public static final ZoneId CAT = ZoneId.of("CAT", ZoneId.SHORT_IDS);
29+
// America/St_Johns
30+
public static final ZoneId CNT = ZoneId.of("CNT", ZoneId.SHORT_IDS);
31+
// America/Chicago
32+
public static final ZoneId CST = ZoneId.of("CST", ZoneId.SHORT_IDS);
33+
// Asia/Shanghai
34+
public static final ZoneId CTT = ZoneId.of("CTT", ZoneId.SHORT_IDS);
35+
// Africa/Addis_Ababa
36+
public static final ZoneId EAT = ZoneId.of("EAT", ZoneId.SHORT_IDS);
37+
// Europe/Paris
38+
public static final ZoneId ECT = ZoneId.of("ECT", ZoneId.SHORT_IDS);
39+
// America/Indiana/Indianapolis
40+
public static final ZoneId IET = ZoneId.of("IET", ZoneId.SHORT_IDS);
41+
// Asia/Kolkata
42+
public static final ZoneId IST = ZoneId.of("IST", ZoneId.SHORT_IDS);
43+
// Asia/Tokyo
44+
public static final ZoneId JST = ZoneId.of("JST", ZoneId.SHORT_IDS);
45+
// Pacific/Apia
46+
public static final ZoneId MIT = ZoneId.of("MIT", ZoneId.SHORT_IDS);
47+
// Asia/Yerevan
48+
public static final ZoneId NET = ZoneId.of("NET", ZoneId.SHORT_IDS);
49+
// Pacific/Auckland
50+
public static final ZoneId NST = ZoneId.of("NST", ZoneId.SHORT_IDS);
51+
// Asia/Karachi
52+
public static final ZoneId PLT = ZoneId.of("PLT", ZoneId.SHORT_IDS);
53+
// America/Phoenix
54+
public static final ZoneId PNT = ZoneId.of("PNT", ZoneId.SHORT_IDS);
55+
// America/Puerto_Rico
56+
public static final ZoneId PRT = ZoneId.of("PRT", ZoneId.SHORT_IDS);
57+
// America/Los_Angeles
58+
public static final ZoneId PST = ZoneId.of("PST", ZoneId.SHORT_IDS);
59+
// Pacific/Guadalcanal
60+
public static final ZoneId SST = ZoneId.of("SST", ZoneId.SHORT_IDS);
61+
// Asia/Ho_Chi_Minh
62+
public static final ZoneId VST = ZoneId.of("VST", ZoneId.SHORT_IDS);
63+
// -05:00
64+
public static final ZoneId EST = ZoneId.of("EST", ZoneId.SHORT_IDS);
65+
// -07:00
66+
public static final ZoneId MST = ZoneId.of("MST", ZoneId.SHORT_IDS);
67+
// -10:00
68+
public static final ZoneId HST = ZoneId.of("HST", ZoneId.SHORT_IDS);
69+
// UTC
70+
public static final ZoneId UTC = ZoneId.of("UTC");
71+
72+
public static class Europe {
73+
public static final ZoneId Amsterdam = ZoneId.of("Europe/Amsterdam");
74+
public static final ZoneId Berlin = ZoneId.of("Europe/Berlin");
75+
public static final ZoneId Brussels = ZoneId.of("Europe/Brussels");
76+
public static final ZoneId Copenhagen = ZoneId.of("Europe/Copenhagen");
77+
public static final ZoneId Dublin = ZoneId.of("Europe/Dublin");
78+
public static final ZoneId Warsaw = ZoneId.of("Europe/Warsaw");
79+
public static final ZoneId Paris = ZoneId.of("Europe/Paris");
80+
public static final ZoneId Zurich = ZoneId.of("Europe/Zurich");
81+
}
82+
83+
public static class America {
84+
public static final ZoneId Chicago = ZoneId.of("America/Chicago");
85+
public static final ZoneId LosAngeles = ZoneId.of("America/Los_Angeles");
86+
public static final ZoneId Phoenix = ZoneId.of("America/Phoenix");
87+
public static final ZoneId PuertoRico = ZoneId.of("America/Puerto_Rico");
88+
public static final ZoneId Vancouver = ZoneId.of("America/Vancouver");
89+
}
90+
91+
public static class Africa {
92+
public static final ZoneId Cairo = ZoneId.of("Africa/Cairo");
93+
public static final ZoneId Casablanca = ZoneId.of("Africa/Casablanca");
94+
public static final ZoneId Nairobi = ZoneId.of("Africa/Nairobi");
95+
public static final ZoneId Tunis = ZoneId.of("Africa/Tunis");
96+
}
97+
98+
public static class Asia {
99+
public static final ZoneId Baghdad = ZoneId.of("Asia/Baghdad");
100+
public static final ZoneId Baku = ZoneId.of("Asia/Baku");
101+
public static final ZoneId Bangkok = ZoneId.of("Asia/Bangkok");
102+
public static final ZoneId Beirut = ZoneId.of("Asia/Beirut");
103+
public static final ZoneId Damascus = ZoneId.of("Asia/Damascus");
104+
public static final ZoneId Dubai = ZoneId.of("Asia/Dubai");
105+
public static final ZoneId Saigon = ZoneId.of("Asia/Saigon");
106+
public static final ZoneId TelAviv = ZoneId.of("Asia/Tel_Aviv");
107+
public static final ZoneId Tokyo = ZoneId.of("Asia/Tokyo");
108+
}
109+
110+
private static final Set<String> AVAILABLE_ZONES = ZoneId.getAvailableZoneIds();
111+
112+
private ZoneIds() {
113+
throw new UnsupportedOperationException("Do not instantiate utility class");
114+
}
115+
116+
@NotNull
117+
public static ZoneId parseZoneId(@NotNull String value) {
118+
expectNonNull(value, "value");
119+
ZoneId zoneId;
120+
try {
121+
zoneId = ZoneId.of(value);
122+
} catch (Exception e) {
123+
throw new IllegalArgumentException("Could not parse ZoneId: '" + value + "'");
124+
}
125+
boolean isAvailable = AVAILABLE_ZONES
126+
.contains(zoneId.getId());
127+
if (!isAvailable) {
128+
throw new IllegalArgumentException("ZoneId not available: '" + value + "'");
129+
}
130+
return zoneId;
131+
}
132+
133+
@Nullable
134+
public static ZoneId parseZoneIdOrNull(@NotNull String value) {
135+
if (!AVAILABLE_ZONES.contains(value)) {
136+
return null;
137+
}
138+
try {
139+
return ZoneId.of(value);
140+
} catch (Exception e) {
141+
return null;
142+
}
143+
}
144+
145+
@NotNull
146+
public static ZoneId parseZoneIdOrDefault(@NotNull String value, @NotNull ZoneId defaultValue) {
147+
ZoneId result = parseZoneIdOrNull(value);
148+
return result == null ? defaultValue : result;
149+
}
150+
151+
@NotNull
152+
public static Optional<ZoneId> parseZoneIdOrEmpty(@NotNull String value) {
153+
return Optional.ofNullable(parseZoneIdOrNull(value));
154+
}
155+
}

src/test/groovy/com/coditory/quark/i18n/LocalesSpec.groovy

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class LocalesSpec extends Specification {
1717
value || expected
1818
"pl" || Locales.PL
1919
"pl-PL" || Locales.PL_PL
20-
"pl_PL" || Locales.PL_PL
21-
"PL_PL" || Locales.PL_PL
20+
"pl-pl" || Locales.PL_PL
21+
"PL-PL" || Locales.PL_PL
2222
"xx" || null
2323
"xx-XX" || null
2424
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.coditory.quark.i18n
2+
3+
import spock.lang.Specification
4+
import spock.lang.Unroll
5+
6+
import static com.coditory.quark.i18n.ZoneIds.parseZoneId
7+
import static com.coditory.quark.i18n.ZoneIds.parseZoneIdOrDefault
8+
import static com.coditory.quark.i18n.ZoneIds.parseZoneIdOrEmpty
9+
import static com.coditory.quark.i18n.ZoneIds.parseZoneIdOrNull
10+
11+
class ZoneIdsSpec extends Specification {
12+
@Unroll
13+
def "should parse ZoneId value: #value"() {
14+
expect:
15+
parseZoneIdOrNull(value) == expected
16+
where:
17+
value || expected
18+
"America/Los_Angeles" || ZoneIds.PST
19+
"Europe/Warsaw" || ZoneIds.Europe.Warsaw
20+
"UTC" || ZoneIds.UTC
21+
"Neverland/TreeHouse" || null
22+
"Xyz" || null
23+
}
24+
25+
@Unroll
26+
def "should parse optional ZoneId"() {
27+
expect:
28+
parseZoneIdOrEmpty(value) == expected
29+
30+
where:
31+
value || expected
32+
"Europe/Warsaw" || Optional.of(ZoneIds.Europe.Warsaw)
33+
"Neverland/TreeHouse" || Optional.empty()
34+
}
35+
36+
@Unroll
37+
def "should parse ZoneId or return default value"() {
38+
expect:
39+
parseZoneIdOrDefault(value, defaultValue) == expected
40+
where:
41+
value | defaultValue || expected
42+
"Neverland/TreeHouse" | ZoneIds.PST || ZoneIds.PST
43+
"America/Los_Angeles" | ZoneIds.ACT || ZoneIds.PST
44+
}
45+
46+
def "should parse ZoneId or throw error"() {
47+
when:
48+
parseZoneId("America/Los_Angeles") == ZoneIds.America.LosAngeles
49+
then:
50+
noExceptionThrown()
51+
52+
when:
53+
parseZoneId("Neverland/TreeHouse")
54+
then:
55+
IllegalArgumentException e = thrown(IllegalArgumentException)
56+
e.message == "Could not parse ZoneId: 'Neverland/TreeHouse'"
57+
}
58+
}

0 commit comments

Comments
 (0)