Skip to content

Commit 12eda02

Browse files
committed
Fix some literals in DurationFormatter
It wasn't detecting 's' as a literal in something like "HH'h 'mm'm 'ss's'", but all other literals worked for some reason, this fixes that I also improved the general code of the formatter to just be a bit nicer lmao
1 parent 920e041 commit 12eda02

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

src/main/java/xyz/srnyx/javautilities/manipulation/DurationFormatter.java

+41-24
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,31 @@ public static String formatDuration(long durationMillis, @NotNull String format)
5656
*/
5757
@NotNull
5858
public static String formatDuration(long durationMillis, @NotNull String format, boolean padWithZeros) {
59+
// Get tokens
5960
final char[] array = format.toCharArray();
60-
final List<Token> list = new ArrayList<>(array.length);
61-
61+
final List<Token> tokens = new ArrayList<>(array.length);
6262
boolean inLiteral = false;
63-
StringBuilder lexxBuilder = null;
63+
StringBuilder literalBuilder = null;
6464
Token previous = null;
65-
for (final char ch : array) {
66-
if (inLiteral && ch != '\'') {
67-
lexxBuilder.append(ch);
65+
for (final char character : array) {
66+
// Literal
67+
if (inLiteral && character != '\'') {
68+
literalBuilder.append(character);
6869
continue;
6970
}
7071

71-
switch (ch) {
72+
switch (character) {
7273
case '\'':
74+
// Literal
7375
if (inLiteral) {
74-
lexxBuilder = null;
7576
inLiteral = false;
77+
literalBuilder = null;
7678
} else {
77-
lexxBuilder = new StringBuilder();
78-
list.add(new Token(lexxBuilder));
7979
inLiteral = true;
80+
literalBuilder = new StringBuilder();
81+
tokens.add(new Token(literalBuilder, true));
8082
}
83+
previous = null;
8184
break;
8285
case 'y':
8386
case 'M':
@@ -86,25 +89,30 @@ public static String formatDuration(long durationMillis, @NotNull String format,
8689
case 'm':
8790
case 's':
8891
case 'S':
89-
final String value = String.valueOf(ch);
92+
literalBuilder = null;
93+
94+
// Same as previous token, increment count
95+
final String value = String.valueOf(character);
9096
if (previous != null && previous.value.toString().equals(value)) {
9197
previous.count++;
92-
} else {
93-
final Token token = new Token(new StringBuilder(value));
94-
list.add(token);
95-
previous = token;
98+
break;
9699
}
97-
lexxBuilder = null;
100+
101+
// New token
102+
final Token token = new Token(new StringBuilder(value), false);
103+
tokens.add(token);
104+
previous = token;
98105
break;
99106
default:
100-
if (lexxBuilder == null) {
101-
lexxBuilder = new StringBuilder();
102-
list.add(new Token(lexxBuilder));
107+
// Doesn't match any token, treat as literal
108+
if (literalBuilder == null) {
109+
literalBuilder = new StringBuilder();
110+
tokens.add(new Token(literalBuilder, true));
103111
}
104-
lexxBuilder.append(ch);
112+
literalBuilder.append(character);
113+
previous = null;
105114
}
106115
}
107-
final Token[] tokens = list.toArray(new Token[0]);
108116

109117
int years = 0;
110118
int months = 0;
@@ -151,6 +159,13 @@ public static String formatDuration(long durationMillis, @NotNull String format,
151159
boolean lastOutputSeconds = false;
152160
for (final Token token : tokens) {
153161
final String value = token.value.toString();
162+
163+
// Literal
164+
if (token.literal) {
165+
builder.append(value);
166+
continue;
167+
}
168+
154169
final int count = token.count;
155170
switch (value) {
156171
case "y":
@@ -212,14 +227,16 @@ private DurationFormatter() {
212227
private static class Token {
213228
@NotNull private final StringBuilder value;
214229
private int count = 1;
230+
private final boolean literal;
215231

216232
/**
217233
* Wraps a token around a value. A value would be something like a 'Y'
218234
*
219235
* @param value to wrap
220236
*/
221-
private Token(@NotNull StringBuilder value) {
237+
private Token(@NotNull StringBuilder value, boolean literal) {
222238
this.value = value;
239+
this.literal = literal;
223240
}
224241

225242
/**
@@ -231,8 +248,8 @@ private Token(@NotNull StringBuilder value) {
231248
* @return boolean <code>true</code> if contained
232249
*/
233250
@Contract(pure = true)
234-
static boolean containsTokenWithValue(@NotNull Token[] tokens, @NotNull String value) {
235-
for (final Token token : tokens) if (token.value.toString().equals(value)) return true;
251+
static boolean containsTokenWithValue(@NotNull List<Token> tokens, @NotNull String value) {
252+
for (final Token token : tokens) if (!token.literal && token.value.toString().equals(value)) return true;
236253
return false;
237254
}
238255
}

0 commit comments

Comments
 (0)