-
Notifications
You must be signed in to change notification settings - Fork 38.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple style of parsing/printing Durations #30396
Support multiple style of parsing/printing Durations #30396
Conversation
Note: the first commit was closer to the arrangement found in Boot, but there was too much logic in the |
*/ | ||
class DurationFormatter implements Formatter<Duration> { | ||
class DurationFormatter implements Formatter<Duration> { //TODO why is this one package-private ? make public and change since taglet ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jhoeller I was wondering if there was a particular reason this Formatter
has been kept package-private so far?
7890f10
to
7b54503
Compare
third iteration (missing a bit of documentation) is reintroducing |
I might be a bit biased, but I personally quite liked the logic being in the I also think it's a bit easier to use. E.g. Perhaps the enum can be extracted from the annotation and moved to the These tests in Spring Boot show how that API might look when being used. |
Spring Framework has I like the idea of moving the unit class outside of the annotation package. It looks like it would improve the usability of the code and address the concern of having too much code in the annotation package. |
I went that route for consistency with Framework current package arrangement, with some extra effort in avoiding too much logic in the annotation. The trouble with moving the edit: to be clear I'm not against making further changes here, as ensuring good compatibility/migrability with what Boot has is definitely a priority, but this felt like the best arrangement to me so far. |
I missed the existing I wonder what I think as it stands AFAICT we don't have any other public utils classes under E.g., in private static Duration toDuration(String value, TimeUnit timeUnit) {
new DurationFormatter(timeUnit).parse(value);
} |
I've just reviewed this PR and rebased against the main branch. There were some changes on the /**
* Execute the annotated method with a fixed period between the end of the
* last invocation and the start of the next.
* <p>The duration String can be in several formats:
* <ul>
* <li>a plain integer — which is interpreted to represent a duration in
* milliseconds by default unless overridden via {@link #timeUnit()} (prefer
* using {@link #fixedDelay()} in that case)</li>
* <li>any of the known {@link org.springframework.format.annotation.DurationFormat.Style
* DurationFormat.Style}: the {@link org.springframework.format.annotation.DurationFormat.Style#ISO8601 ISO8601}
* style or the {@link org.springframework.format.annotation.DurationFormat.Style#SIMPLE SIMPLE} style
* — using the {@link #timeUnit()} as fallback if the string doesn't contain an explicit unit</li>
* <li>one of the above, with Spring-style "${...}" placeholders as well as SpEL expressions</li>
* </ul>
* @return the delay as a String value — for example a placeholder,
* or a {@link org.springframework.format.annotation.DurationFormat.Style#ISO8601 java.time.Duration} compliant value
* or a {@link org.springframework.format.annotation.DurationFormat.Style#SIMPLE simple format} compliant value
* @since 3.2.2
* @see #fixedDelay()
*/
I've tried that approach, and this involves moving the detection code to the private static Duration toDuration(String value, TimeUnit timeUnit) {
DurationFormat.Unit unit = DurationFormat.Unit.fromChronoUnit(timeUnit.toChronoUnit());
DurationFormat.Style style = DurationFormat.Style.detect(value);
try {
return new DurationFormatter(style, unit).parse(value, null);
} catch (ParseException exc) {
throw new IllegalArgumentException(exc);
}
} As Simon said:
I think we don't have enough information at this point to decide whether this arrangement is good enough for Spring Boot. I'm rescheduling this to 6.1.x as we need to find a proper time to experiment with both Spring Framework and Spring Boot SNAPSHOTs. |
There's a comment on spring-projects/spring-boot#37562 (comment) which might be relevant to this feature. It would be nice to support Kotlin |
This commit introduces a notion of different styles for the formatting
of
Duration
.The
DurationFormat
annotation is added to ease selection of a style,which are represented as
DurationFormat.Style
enum, as well as asupported time unit represented as
DurationFormat.Unit
enum.DurationFormatter
has been retroffited to take such aStyle
,optionally, at construction. The default is still the JDK style aka
ISO-8601.
This introduces the new
SIMPLE
style which uses a single number + ashort human-readable suffix. For instance
-3ms
or2h
.This has the same semantics as the
DurationStyle
in Spring Boot andis intended as a replacement for that feature, providing access to the
feature to projects that only depend on Spring Framework.
Finally, the
@Scheduled
annotation is improved by adding detectionof the style and parsing for the String versions of initial delay, fixed
delay and fixed rate.
See gh-22013
See gh-22474