Skip to content

Commit 15364cf

Browse files
committed
Polishing
1 parent 9785901 commit 15364cf

File tree

2 files changed

+82
-80
lines changed

2 files changed

+82
-80
lines changed

spring-context/src/main/java/org/springframework/format/annotation/DurationFormat.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,19 @@
5353
*/
5454
Unit defaultUnit() default Unit.MILLIS;
5555

56+
5657
/**
5758
* {@link Duration} format styles.
5859
*/
5960
enum Style {
6061

62+
/**
63+
* ISO-8601 formatting.
64+
* <p>This is what the JDK uses in {@link Duration#parse(CharSequence)}
65+
* and {@link Duration#toString()}.
66+
*/
67+
ISO8601,
68+
6169
/**
6270
* Simple formatting based on a short suffix, for example '1s'.
6371
* <p>Supported unit suffixes include: {@code ns, us, ms, s, m, h, d}.
@@ -72,13 +80,6 @@ enum Style {
7280
*/
7381
SIMPLE,
7482

75-
/**
76-
* ISO-8601 formatting.
77-
* <p>This is what the JDK uses in {@link Duration#parse(CharSequence)}
78-
* and {@link Duration#toString()}.
79-
*/
80-
ISO8601,
81-
8283
/**
8384
* Like {@link #SIMPLE}, but allows multiple segments ordered from
8485
* largest-to-smallest units of time, like {@code 1h12m27s}.
@@ -90,6 +91,7 @@ enum Style {
9091
COMPOSITE
9192
}
9293

94+
9395
/**
9496
* {@link Duration} format unit, which mirrors a subset of {@link ChronoUnit} and
9597
* allows conversion to and from a supported {@code ChronoUnit} as well as
@@ -227,7 +229,6 @@ public static Unit fromSuffix(String suffix) {
227229
}
228230
throw new IllegalArgumentException("'" + suffix + "' is not a valid simple duration Unit");
229231
}
230-
231232
}
232233

233234
}

spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java

Lines changed: 73 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
/**
2929
* Support {@code Duration} parsing and printing in several styles, as listed in
3030
* {@link DurationFormat.Style}.
31+
*
3132
* <p>Some styles may not enforce any unit to be present, defaulting to {@code DurationFormat.Unit#MILLIS}
3233
* in that case. Methods in this class offer overloads that take a {@link DurationFormat.Unit} to
3334
* be used as a fall-back instead of the ultimate MILLIS default.
@@ -39,36 +40,13 @@
3940
*/
4041
public abstract class DurationFormatterUtils {
4142

42-
private DurationFormatterUtils() {
43-
// singleton
44-
}
43+
private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$");
4544

46-
/**
47-
* Parse the given value to a duration.
48-
* @param value the value to parse
49-
* @param style the style in which to parse
50-
* @return a duration
51-
*/
52-
public static Duration parse(String value, DurationFormat.Style style) {
53-
return parse(value, style, null);
54-
}
45+
private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$");
46+
47+
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" +
48+
"\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
5549

56-
/**
57-
* Parse the given value to a duration.
58-
* @param value the value to parse
59-
* @param style the style in which to parse
60-
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
61-
* will default to ms)
62-
* @return a duration
63-
*/
64-
public static Duration parse(String value, DurationFormat.Style style, @Nullable DurationFormat.Unit unit) {
65-
Assert.hasText(value, () -> "Value must not be empty");
66-
return switch (style) {
67-
case ISO8601 -> parseIso8601(value);
68-
case SIMPLE -> parseSimple(value, unit);
69-
case COMPOSITE -> parseComposite(value);
70-
};
71-
}
7250

7351
/**
7452
* Print the specified duration in the specified style.
@@ -97,27 +75,30 @@ public static String print(Duration value, DurationFormat.Style style, @Nullable
9775
}
9876

9977
/**
100-
* Detect the style then parse the value to return a duration.
78+
* Parse the given value to a duration.
10179
* @param value the value to parse
102-
* @return the parsed duration
103-
* @throws IllegalArgumentException if the value is not a known style or cannot be
104-
* parsed
80+
* @param style the style in which to parse
81+
* @return a duration
10582
*/
106-
public static Duration detectAndParse(String value) {
107-
return detectAndParse(value, null);
83+
public static Duration parse(String value, DurationFormat.Style style) {
84+
return parse(value, style, null);
10885
}
10986

11087
/**
111-
* Detect the style then parse the value to return a duration.
88+
* Parse the given value to a duration.
11289
* @param value the value to parse
90+
* @param style the style in which to parse
11391
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
11492
* will default to ms)
115-
* @return the parsed duration
116-
* @throws IllegalArgumentException if the value is not a known style or cannot be
117-
* parsed
93+
* @return a duration
11894
*/
119-
public static Duration detectAndParse(String value, @Nullable DurationFormat.Unit unit) {
120-
return parse(value, detect(value), unit);
95+
public static Duration parse(String value, DurationFormat.Style style, @Nullable DurationFormat.Unit unit) {
96+
Assert.hasText(value, () -> "Value must not be empty");
97+
return switch (style) {
98+
case ISO8601 -> parseIso8601(value);
99+
case SIMPLE -> parseSimple(value, unit);
100+
case COMPOSITE -> parseComposite(value);
101+
};
121102
}
122103

123104
/**
@@ -141,10 +122,30 @@ public static DurationFormat.Style detect(String value) {
141122
throw new IllegalArgumentException("'" + value + "' is not a valid duration, cannot detect any known style");
142123
}
143124

144-
private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$");
145-
private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$");
146-
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" +
147-
"\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$");
125+
/**
126+
* Detect the style then parse the value to return a duration.
127+
* @param value the value to parse
128+
* @return the parsed duration
129+
* @throws IllegalArgumentException if the value is not a known style or cannot be
130+
* parsed
131+
*/
132+
public static Duration detectAndParse(String value) {
133+
return detectAndParse(value, null);
134+
}
135+
136+
/**
137+
* Detect the style then parse the value to return a duration.
138+
* @param value the value to parse
139+
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
140+
* will default to ms)
141+
* @return the parsed duration
142+
* @throws IllegalArgumentException if the value is not a known style or cannot be
143+
* parsed
144+
*/
145+
public static Duration detectAndParse(String value, @Nullable DurationFormat.Unit unit) {
146+
return parse(value, detect(value), unit);
147+
}
148+
148149

149150
private static Duration parseIso8601(String value) {
150151
try {
@@ -155,6 +156,11 @@ private static Duration parseIso8601(String value) {
155156
}
156157
}
157158

159+
private static String printSimple(Duration duration, @Nullable DurationFormat.Unit unit) {
160+
unit = (unit == null ? DurationFormat.Unit.MILLIS : unit);
161+
return unit.print(duration);
162+
}
163+
158164
private static Duration parseSimple(String text, @Nullable DurationFormat.Unit fallbackUnit) {
159165
try {
160166
Matcher matcher = SIMPLE_PATTERN.matcher(text);
@@ -171,34 +177,6 @@ private static Duration parseSimple(String text, @Nullable DurationFormat.Unit f
171177
}
172178
}
173179

174-
private static String printSimple(Duration duration, @Nullable DurationFormat.Unit unit) {
175-
unit = (unit == null ? DurationFormat.Unit.MILLIS : unit);
176-
return unit.print(duration);
177-
}
178-
179-
private static Duration parseComposite(String text) {
180-
try {
181-
Matcher matcher = COMPOSITE_PATTERN.matcher(text);
182-
Assert.state(matcher.matches() && matcher.groupCount() > 1, "Does not match composite duration pattern");
183-
String sign = matcher.group(1);
184-
boolean negative = sign != null && sign.equals("-");
185-
186-
Duration result = Duration.ZERO;
187-
DurationFormat.Unit[] units = DurationFormat.Unit.values();
188-
for (int i = 2; i < matcher.groupCount() + 1; i++) {
189-
String segment = matcher.group(i);
190-
if (StringUtils.hasText(segment)) {
191-
DurationFormat.Unit unit = units[units.length - i + 1];
192-
result = result.plus(unit.parse(segment.replace(unit.asSuffix(), "")));
193-
}
194-
}
195-
return negative ? result.negated() : result;
196-
}
197-
catch (Exception ex) {
198-
throw new IllegalArgumentException("'" + text + "' is not a valid composite duration", ex);
199-
}
200-
}
201-
202180
private static String printComposite(Duration duration) {
203181
if (duration.isZero()) {
204182
return DurationFormat.Unit.SECONDS.print(duration);
@@ -243,4 +221,27 @@ private static String printComposite(Duration duration) {
243221
return result.toString();
244222
}
245223

224+
private static Duration parseComposite(String text) {
225+
try {
226+
Matcher matcher = COMPOSITE_PATTERN.matcher(text);
227+
Assert.state(matcher.matches() && matcher.groupCount() > 1, "Does not match composite duration pattern");
228+
String sign = matcher.group(1);
229+
boolean negative = sign != null && sign.equals("-");
230+
231+
Duration result = Duration.ZERO;
232+
DurationFormat.Unit[] units = DurationFormat.Unit.values();
233+
for (int i = 2; i < matcher.groupCount() + 1; i++) {
234+
String segment = matcher.group(i);
235+
if (StringUtils.hasText(segment)) {
236+
DurationFormat.Unit unit = units[units.length - i + 1];
237+
result = result.plus(unit.parse(segment.replace(unit.asSuffix(), "")));
238+
}
239+
}
240+
return negative ? result.negated() : result;
241+
}
242+
catch (Exception ex) {
243+
throw new IllegalArgumentException("'" + text + "' is not a valid composite duration", ex);
244+
}
245+
}
246+
246247
}

0 commit comments

Comments
 (0)