change name to DateFormatManager

This commit is contained in:
Looly 2024-10-11 09:07:24 +08:00
parent ae1f3635ce
commit 03681f3d40
12 changed files with 116 additions and 69 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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)));
}

View File

@ -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));
}

View File

@ -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)

View File

@ -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;

View File

@ -26,13 +26,14 @@ import java.util.Map;
import java.util.function.Function;
/**
* 全局自定义格式<br>
* 用于定义用户指定的日期格式和输出日期的关系
* 自定义格式化管理器用于自定义日期格式化和解析逻辑<br>
* 一般通过{@link #getInstance()}使用全局单例对象<br>
* 通过{@link #registerFormatter(String, Function)}注册自定义格式化规则注册后使用{@link #format(Date, CharSequence)}格式化为日期字符串<br>
* 通过{@link #registerParser(String, Function)}注册自定义解析规则注册后使用{@link #parse(CharSequence, String)}解析日期字符串<br>
*
* @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<CharSequence, Function<Date, String>> formatterMap;
private static final Map<CharSequence, Function<CharSequence, Date>> 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<CharSequence, Function<Date, String>> formatterMap;
private final Map<CharSequence, Function<CharSequence, Date>> 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<Date, String> func) {
public DateFormatManager registerFormatter(final String format, final Function<Date, String> 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<CharSequence, Date> func) {
public DateFormatManager registerParser(final String format, final Function<CharSequence, Date> 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<Date, String> 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<Date, String> 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<CharSequence, Date> func = parserMap.get(format);
if (null != func) {
return func.apply(dateStr);
}
}
return null;
}
// endregion
}

View File

@ -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;

View File

@ -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<Date>, 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);

View File

@ -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<TemporalAccess
final Object value;
// 默认为时间戳
if (null == format || GlobalCustomFormat.FORMAT_MILLISECONDS.equals(format)) {
if (null == format || DateFormatManager.FORMAT_MILLISECONDS.equals(format)) {
value = TimeUtil.toEpochMilli(bean);
} else if (GlobalCustomFormat.FORMAT_SECONDS.equals(format)) {
} else if (DateFormatManager.FORMAT_SECONDS.equals(format)) {
value = Math.floorDiv(TimeUtil.toEpochMilli(bean), 1000L);
} else {
value = TimeUtil.format(bean, format);

View File

@ -22,7 +22,7 @@ import org.dromara.hutool.core.annotation.PropIgnore;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.date.DateFormatPool;
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.io.resource.ResourceUtil;
import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.text.StrUtil;
@ -491,7 +491,7 @@ public class JSONObjectTest {
@Test
public void setDateFormatSecondsTest() {
// 自定义格式为只有秒的时间戳一般用于JWT
final JSONConfig jsonConfig = JSONConfig.of().setDateFormat(GlobalCustomFormat.FORMAT_SECONDS);
final JSONConfig jsonConfig = JSONConfig.of().setDateFormat(DateFormatManager.FORMAT_SECONDS);
final Date date = DateUtil.parse("2020-06-05 11:16:11");
final JSONObject json = new JSONObject(jsonConfig);
@ -507,7 +507,7 @@ public class JSONObjectTest {
@Test
public void setCustomDateFormatTest() {
final JSONConfig jsonConfig = JSONConfig.of();
jsonConfig.setDateFormat(GlobalCustomFormat.FORMAT_SECONDS);
jsonConfig.setDateFormat(DateFormatManager.FORMAT_SECONDS);
final Date date = DateUtil.parse("2020-06-05 11:16:11");
final JSONObject json = new JSONObject(jsonConfig);

View File

@ -19,7 +19,7 @@ package org.dromara.hutool.json.jwt;
import lombok.Data;
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.json.JSONConfig;
import org.dromara.hutool.json.JSONObject;
import org.dromara.hutool.json.JSONUtil;
@ -41,7 +41,7 @@ public class IssueI6IS5BTest {
final JwtToken jwtToken = new JwtToken();
jwtToken.setIat(iat);
final JSONObject payloadsData = JSONUtil.parseObj(jwtToken, JSONConfig.of().setDateFormat(GlobalCustomFormat.FORMAT_SECONDS));
final JSONObject payloadsData = JSONUtil.parseObj(jwtToken, JSONConfig.of().setDateFormat(DateFormatManager.FORMAT_SECONDS));
final String token = JWTUtil.createToken(payloadsData, "123".getBytes(StandardCharsets.UTF_8));
Assertions.assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Nzc3NzI4MDB9.SXU_mm1wT5lNoK-Dq5Y8f3BItv_44zuAlyeWLqajpXg", token);
@ -62,7 +62,7 @@ public class IssueI6IS5BTest {
final JwtToken2 jwtToken = new JwtToken2();
jwtToken.setIat(iat);
final JSONObject payloadsData = JSONUtil.parseObj(jwtToken, JSONConfig.of().setDateFormat(GlobalCustomFormat.FORMAT_SECONDS));
final JSONObject payloadsData = JSONUtil.parseObj(jwtToken, JSONConfig.of().setDateFormat(DateFormatManager.FORMAT_SECONDS));
final String token = JWTUtil.createToken(payloadsData, "123".getBytes(StandardCharsets.UTF_8));
Assertions.assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Nzc3NzI4MDB9.SXU_mm1wT5lNoK-Dq5Y8f3BItv_44zuAlyeWLqajpXg", token);