From 03681f3d40dc9072c4a417c84718b29661e571e7 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 11 Oct 2024 09:07:24 +0800 Subject: [PATCH] change name to DateFormatManager --- .../impl/TemporalAccessorConverter.java | 4 +- .../hutool/core/date/CalendarUtil.java | 7 +- .../dromara/hutool/core/date/DateTime.java | 6 +- .../dromara/hutool/core/date/DateUtil.java | 12 +- .../core/date/TemporalAccessorUtil.java | 7 +- .../dromara/hutool/core/date/TimeUtil.java | 7 +- ...stomFormat.java => DateFormatManager.java} | 114 ++++++++++++------ .../org/dromara/hutool/json/jwt/Claims.java | 4 +- .../json/serializer/impl/DateTypeAdapter.java | 6 +- .../serializer/impl/TemporalTypeAdapter.java | 6 +- .../dromara/hutool/json/JSONObjectTest.java | 6 +- .../hutool/json/jwt/IssueI6IS5BTest.java | 6 +- 12 files changed, 116 insertions(+), 69 deletions(-) rename hutool-core/src/main/java/org/dromara/hutool/core/date/format/{GlobalCustomFormat.java => DateFormatManager.java} (51%) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java index 126b42620..40f546d4f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java @@ -20,7 +20,7 @@ import org.dromara.hutool.core.convert.AbstractConverter; import org.dromara.hutool.core.date.DateTime; import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.date.TimeUtil; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; @@ -195,7 +195,7 @@ public class TemporalAccessorConverter extends AbstractConverter { } final Instant instant; - if (GlobalCustomFormat.FORMAT_SECONDS.equals(this.format)) { + if (DateFormatManager.FORMAT_SECONDS.equals(this.format)) { // https://gitee.com/dromara/hutool/issues/I6IS5B // Unix时间戳 instant = Instant.ofEpochSecond(time); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java index 9637acc20..af10664cf 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java @@ -19,7 +19,7 @@ package org.dromara.hutool.core.date; import org.dromara.hutool.core.comparator.CompareUtil; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.math.ChineseNumberFormatter; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.date.format.parser.DateParser; import org.dromara.hutool.core.date.format.parser.FastDateParser; import org.dromara.hutool.core.date.format.parser.PositionDateParser; @@ -755,9 +755,10 @@ public class CalendarUtil { final Calendar calendar = Calendar.getInstance(tz, lcl); calendar.setLenient(lenient); + final DateFormatManager formatManager = DateFormatManager.getInstance(); for (final String parsePattern : parsePatterns) { - if (GlobalCustomFormat.isCustomFormat(parsePattern)) { - final Date parse = GlobalCustomFormat.parse(str, parsePattern); + if (formatManager.isCustomParse(parsePattern)) { + final Date parse = formatManager.parse(str, parsePattern); if (null == parse) { continue; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java index 0f936c147..ef1e41f0e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java @@ -18,7 +18,7 @@ package org.dromara.hutool.core.date; import org.dromara.hutool.core.date.format.DatePrinter; import org.dromara.hutool.core.date.format.FastDateFormat; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.date.format.parser.DateParser; import org.dromara.hutool.core.date.format.parser.PositionDateParser; import org.dromara.hutool.core.lang.Assert; @@ -297,8 +297,8 @@ public class DateTime extends Date { * @see DateFormatPool */ public DateTime(final CharSequence dateStr, final String format) { - this(GlobalCustomFormat.isCustomFormat(format) - ? GlobalCustomFormat.parse(dateStr, format) + this(DateFormatManager.getInstance().isCustomFormat(format) + ? DateFormatManager.getInstance().parse(dateStr, format) : parse(dateStr, DateUtil.newSimpleFormat(format))); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java index 15c4b3454..52d977d00 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java @@ -20,7 +20,7 @@ import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.comparator.CompareUtil; import org.dromara.hutool.core.date.format.DatePrinter; import org.dromara.hutool.core.date.format.FastDateFormat; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.date.format.parser.PositionDateParser; import org.dromara.hutool.core.date.format.parser.RegisterDateParser; import org.dromara.hutool.core.lang.Assert; @@ -546,8 +546,9 @@ public class DateUtil { } // 检查自定义格式 - if (GlobalCustomFormat.isCustomFormat(format)) { - return GlobalCustomFormat.format(date, format); + final DateFormatManager formatManager = DateFormatManager.getInstance(); + if (formatManager.isCustomFormat(format)) { + return formatManager.format(date, format); } TimeZone timeZone = null; @@ -751,9 +752,10 @@ public class DateUtil { * @since 4.5.18 */ public static DateTime parse(final CharSequence dateStr, final String format, final Locale locale) { - if (GlobalCustomFormat.isCustomFormat(format)) { + final DateFormatManager formatManager = DateFormatManager.getInstance(); + if (formatManager.isCustomFormat(format)) { // 自定义格式化器忽略Locale - return new DateTime(GlobalCustomFormat.parse(dateStr, format)); + return new DateTime(formatManager.parse(dateStr, format)); } return new DateTime(dateStr, DateUtil.newSimpleFormat(format, locale, null)); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/TemporalAccessorUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/TemporalAccessorUtil.java index 0cfc1bb61..b8ab74ef2 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/TemporalAccessorUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/TemporalAccessorUtil.java @@ -16,7 +16,7 @@ package org.dromara.hutool.core.date; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.text.StrUtil; import java.time.DayOfWeek; @@ -118,8 +118,9 @@ public class TemporalAccessorUtil extends TemporalUtil{ } // 检查自定义格式 - if(GlobalCustomFormat.isCustomFormat(format)){ - return GlobalCustomFormat.format(time, format); + final DateFormatManager formatManager = DateFormatManager.getInstance(); + if(formatManager.isCustomFormat(format)){ + return formatManager.format(time, format); } final DateTimeFormatter formatter = StrUtil.isBlank(format) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java index 6699ec9a4..902041257 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java @@ -16,7 +16,7 @@ package org.dromara.hutool.core.date; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.func.LambdaUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; @@ -333,8 +333,9 @@ public class TimeUtil extends TemporalAccessorUtil { return null; } - if (GlobalCustomFormat.isCustomFormat(format)) { - return of(GlobalCustomFormat.parse(text, format)); + final DateFormatManager formatManager = DateFormatManager.getInstance(); + if (formatManager.isCustomFormat(format)) { + return of(formatManager.parse(text, format)); } DateTimeFormatter formatter = null; diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/DateFormatManager.java similarity index 51% rename from hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java rename to hutool-core/src/main/java/org/dromara/hutool/core/date/format/DateFormatManager.java index 47dff225c..3ff967be9 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/DateFormatManager.java @@ -26,13 +26,14 @@ import java.util.Map; import java.util.function.Function; /** - * 全局自定义格式
- * 用于定义用户指定的日期格式和输出日期的关系 + * 自定义格式化管理器,用于自定义日期格式化和解析逻辑
+ * 一般通过{@link #getInstance()}使用全局单例对象。
+ * 通过{@link #registerFormatter(String, Function)}注册自定义格式化规则,注册后使用{@link #format(Date, CharSequence)}格式化为日期字符串
+ * 通过{@link #registerParser(String, Function)}注册自定义解析规则,注册后使用{@link #parse(CharSequence, String)}解析日期字符串
* * @author looly - * @since 5.7.2 */ -public class GlobalCustomFormat { +public class DateFormatManager { /** * 格式:秒时间戳(Unix时间戳) @@ -43,31 +44,56 @@ public class GlobalCustomFormat { */ public static final String FORMAT_MILLISECONDS = "#SSS"; - private static final Map> formatterMap; - private static final Map> parserMap; + /** + * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 + */ + private static class SingletonHolder { + /** + * 静态初始化器,由JVM来保证线程安全 + */ + private static final DateFormatManager INSTANCE = new DateFormatManager(); + } - static { + /** + * 获得单例的 DateFormatManager + * + * @return DateFormatManager + */ + public static DateFormatManager getInstance() { + return SingletonHolder.INSTANCE; + } + + private final Map> formatterMap; + private final Map> parserMap; + + /** + * 构造 + */ + public DateFormatManager() { formatterMap = new SafeConcurrentHashMap<>(); parserMap = new SafeConcurrentHashMap<>(); // Hutool预设的几种自定义格式 - putFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000L))); - putParser(FORMAT_SECONDS, (dateStr) -> DateUtil.date(Math.multiplyExact(Long.parseLong(dateStr.toString()), 1000L))); + registerFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000L))); + registerParser(FORMAT_SECONDS, (dateStr) -> DateUtil.date(Math.multiplyExact(Long.parseLong(dateStr.toString()), 1000L))); - putFormatter(FORMAT_MILLISECONDS, (date) -> String.valueOf(date.getTime())); - putParser(FORMAT_MILLISECONDS, (dateStr) -> DateUtil.date(Long.parseLong(dateStr.toString()))); + registerFormatter(FORMAT_MILLISECONDS, (date) -> String.valueOf(date.getTime())); + registerParser(FORMAT_MILLISECONDS, (dateStr) -> DateUtil.date(Long.parseLong(dateStr.toString()))); } + // region ----- register /** * 加入日期格式化规则 * * @param format 格式 * @param func 格式化函数 + * @return this */ - public static void putFormatter(final String format, final Function func) { + public DateFormatManager registerFormatter(final String format, final Function func) { Assert.notNull(format, "Format must be not null !"); Assert.notNull(func, "Function must be not null !"); formatterMap.put(format, func); + return this; } /** @@ -75,39 +101,25 @@ public class GlobalCustomFormat { * * @param format 格式 * @param func 解析函数 + * @return this */ - public static void putParser(final String format, final Function func) { + public DateFormatManager registerParser(final String format, final Function func) { Assert.notNull(format, "Format must be not null !"); Assert.notNull(func, "Function must be not null !"); parserMap.put(format, func); + return this; } + // endregion + // region ----- format /** * 检查指定格式是否为自定义格式 * * @param format 格式 * @return 是否为自定义格式 */ - public static boolean isCustomFormat(final String format) { - return formatterMap.containsKey(format); - } - - /** - * 使用自定义格式格式化日期 - * - * @param date 日期 - * @param format 自定义格式 - * @return 格式化后的日期 - */ - public static String format(final Date date, final CharSequence format) { - if (null != formatterMap) { - final Function func = formatterMap.get(format); - if (null != func) { - return func.apply(date); - } - } - - return null; + public boolean isCustomFormat(final String format) { + return null != formatterMap && formatterMap.containsKey(format); } /** @@ -117,10 +129,40 @@ public class GlobalCustomFormat { * @param format 自定义格式 * @return 格式化后的日期 */ - public static String format(final TemporalAccessor temporalAccessor, final CharSequence format) { + public String format(final TemporalAccessor temporalAccessor, final CharSequence format) { return format(DateUtil.date(temporalAccessor), format); } + /** + * 使用自定义格式格式化日期 + * + * @param date 日期 + * @param format 自定义格式 + * @return 格式化后的日期 + */ + public String format(final Date date, final CharSequence format) { + if (null != formatterMap) { + final Function func = formatterMap.get(format); + if (null != func) { + return func.apply(date); + } + } + + return null; + } + // endregion + + // region ----- parse + /** + * 检查指定格式是否为自定义格式 + * + * @param format 格式 + * @return 是否为自定义格式 + */ + public boolean isCustomParse(final String format) { + return null != parserMap && parserMap.containsKey(format); + } + /** * 使用自定义格式解析日期 * @@ -128,14 +170,14 @@ public class GlobalCustomFormat { * @param format 自定义格式 * @return 格式化后的日期 */ - public static Date parse(final CharSequence dateStr, final String format) { + public Date parse(final CharSequence dateStr, final String format) { if (null != parserMap) { final Function func = parserMap.get(format); if (null != func) { return func.apply(dateStr); } } - return null; } + // endregion } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/Claims.java b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/Claims.java index 33085901b..f2528fe84 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/Claims.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/Claims.java @@ -17,7 +17,7 @@ package org.dromara.hutool.json.jwt; import org.dromara.hutool.core.codec.binary.Base64; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.json.JSONConfig; @@ -38,7 +38,7 @@ public class Claims implements Serializable { private static final long serialVersionUID = 1L; // 时间使用秒级时间戳表示 - private final JSONConfig CONFIG = JSONConfig.of().setDateFormat(GlobalCustomFormat.FORMAT_SECONDS); + private final JSONConfig CONFIG = JSONConfig.of().setDateFormat(DateFormatManager.FORMAT_SECONDS); private JSONObject claimJSON; diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DateTypeAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DateTypeAdapter.java index de4a28417..a4a176fd3 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DateTypeAdapter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DateTypeAdapter.java @@ -18,7 +18,7 @@ package org.dromara.hutool.json.serializer.impl; import org.dromara.hutool.core.convert.impl.DateConverter; import org.dromara.hutool.core.date.DateUtil; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.json.JSON; @@ -61,9 +61,9 @@ public class DateTypeAdapter implements MatcherJSONSerializer, MatcherJSON final Object value; // 默认为时间戳 - if(null == format || GlobalCustomFormat.FORMAT_MILLISECONDS.equals(format)){ + if(null == format || DateFormatManager.FORMAT_MILLISECONDS.equals(format)){ value = bean.getTime(); - } else if(GlobalCustomFormat.FORMAT_SECONDS.equals(format)){ + } else if(DateFormatManager.FORMAT_SECONDS.equals(format)){ value = Math.floorDiv(bean.getTime(), 1000L); } else { value = DateUtil.format(bean, format); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/TemporalTypeAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/TemporalTypeAdapter.java index a5f09da35..9ba22fa6f 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/TemporalTypeAdapter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/TemporalTypeAdapter.java @@ -18,7 +18,7 @@ package org.dromara.hutool.json.serializer.impl; import org.dromara.hutool.core.convert.impl.TemporalAccessorConverter; import org.dromara.hutool.core.date.TimeUtil; -import org.dromara.hutool.core.date.format.GlobalCustomFormat; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Opt; import org.dromara.hutool.core.math.NumberUtil; @@ -90,9 +90,9 @@ public class TemporalTypeAdapter implements MatcherJSONSerializer