diff --git a/context/src/main/java/io/micronaut/runtime/converters/time/TimeConverterRegistrar.java b/context/src/main/java/io/micronaut/runtime/converters/time/TimeConverterRegistrar.java index 5637c1cf163..a1ca99a4166 100644 --- a/context/src/main/java/io/micronaut/runtime/converters/time/TimeConverterRegistrar.java +++ b/context/src/main/java/io/micronaut/runtime/converters/time/TimeConverterRegistrar.java @@ -44,8 +44,10 @@ import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalQuery; import java.util.Date; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import java.util.function.Function; import java.util.regex.Matcher; @@ -82,6 +84,8 @@ public class TimeConverterRegistrar implements TypeConverterRegistrar { private static final Pattern DURATION_MATCHER = Pattern.compile("^(-?\\d+)([unsmhd])(s?)$"); private static final int MILLIS = 3; + private final Map formattersCache = new ConcurrentHashMap<>(); + @NextMajorVersion("Consider deletion of LocalDate and LocalDateTime converters") @Override public void register(MutableConversionService conversionService) { @@ -184,7 +188,7 @@ private void addTemporalStringConverters(MutableCon // try explicit format first Optional format = context.getAnnotationMetadata().stringValue(Format.class); if (format.isPresent()) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format.get(), context.getLocale()); + DateTimeFormatter formatter = getFormatter(format.get(), context); try { T converted = formatter.parse(object, query); return Optional.of(converted); @@ -216,7 +220,7 @@ private void addTemporalStringConverters(MutableCon // try explicit format first Optional format = context.getAnnotationMetadata().stringValue(Format.class); if (format.isPresent()) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format.get(), context.getLocale()); + DateTimeFormatter formatter = getFormatter(format.get(), context); try { CharSequence converted = formatter.format(object); return Optional.of(converted); @@ -242,6 +246,18 @@ private void addTemporalStringConverters(MutableCon }); } + private DateTimeFormatter getFormatter(String pattern, ConversionContext context) { + var key = pattern + context.getLocale(); + var cachedFormater = formattersCache.get(key); + if (cachedFormater != null) { + return cachedFormater; + } + var formatter = DateTimeFormatter.ofPattern(pattern, context.getLocale()); + formattersCache.put(key, formatter); + + return formatter; + } + private void addTemporalToDateConverter(MutableConversionService conversionService, Class temporalType, Function toInstant) { conversionService.addConverter(temporalType, Date.class, (T object, Class targetType, ConversionContext context) -> Optional.of(Date.from(toInstant.apply(object)))); }