!1227 perf(core): 时间格式化工具支持自定义设置单位

Merge pull request !1227 from 蒋小小/v6-dev
This commit is contained in:
Looly 2024-06-17 07:25:23 +00:00 committed by Gitee
commit bf19e86f4e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 85 additions and 15 deletions

View File

@ -15,6 +15,7 @@ package org.dromara.hutool.core.date;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.function.Function;
/** /**
* 时长格式化器用于格式化输出两个日期相差的时长<br> * 时长格式化器用于格式化输出两个日期相差的时长<br>
@ -30,6 +31,10 @@ import java.io.Serializable;
public class BetweenFormatter implements Serializable { public class BetweenFormatter implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 单位格式化器
*/
public static Function<Level, String> DEFAULT_LEVEL_FORMATTER = (level) -> level.name;
/** /**
* 时长毫秒数 * 时长毫秒数
*/ */
@ -47,6 +52,14 @@ public class BetweenFormatter implements Serializable {
* 如为{@code true}输出 1小时3秒{@code false}输出 1小时0分3秒 * 如为{@code true}输出 1小时3秒{@code false}输出 1小时0分3秒
*/ */
private boolean simpleMode = true; private boolean simpleMode = true;
/**
* 格式化器
*/
private Function<Level, String> levelFormatter = DEFAULT_LEVEL_FORMATTER;
/**
* 分隔符
*/
private String separator = StrUtil.EMPTY;
/** /**
* 创建 BetweenFormatter * 创建 BetweenFormatter
@ -105,14 +118,14 @@ public class BetweenFormatter implements Serializable {
// //
if (isLevelCountValid(levelCount) && day > 0) { if (isLevelCountValid(levelCount) && day > 0) {
sb.append(day).append(Level.DAY.name); sb.append(day).append(levelFormatter.apply(Level.DAY)).append(separator);
levelCount++; levelCount++;
} }
// //
if (isLevelCountValid(levelCount) && level >= Level.HOUR.ordinal()) { if (isLevelCountValid(levelCount) && level >= Level.HOUR.ordinal()) {
if (hour > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) { if (hour > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) {
sb.append(hour).append(Level.HOUR.name); sb.append(hour).append(levelFormatter.apply(Level.HOUR)).append(separator);
levelCount++; levelCount++;
} }
} }
@ -120,7 +133,7 @@ public class BetweenFormatter implements Serializable {
// //
if (isLevelCountValid(levelCount) && level >= Level.MINUTE.ordinal()) { if (isLevelCountValid(levelCount) && level >= Level.MINUTE.ordinal()) {
if (minute > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) { if (minute > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) {
sb.append(minute).append(Level.MINUTE.name); sb.append(minute).append(levelFormatter.apply(Level.MINUTE)).append(separator);
levelCount++; levelCount++;
} }
} }
@ -128,23 +141,27 @@ public class BetweenFormatter implements Serializable {
// //
if (isLevelCountValid(levelCount) && level >= Level.SECOND.ordinal()) { if (isLevelCountValid(levelCount) && level >= Level.SECOND.ordinal()) {
if (second > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) { if (second > 0 || (!this.simpleMode && StrUtil.isNotEmpty(sb))) {
sb.append(second).append(Level.SECOND.name); sb.append(second).append(levelFormatter.apply(Level.SECOND)).append(separator);
levelCount++; levelCount++;
} }
} }
// 毫秒 // 毫秒
if (isLevelCountValid(levelCount) && millisecond > 0 && level >= Level.MILLISECOND.ordinal()) { if (isLevelCountValid(levelCount) && millisecond > 0 && level >= Level.MILLISECOND.ordinal()) {
sb.append(millisecond).append(Level.MILLISECOND.name); sb.append(millisecond).append(levelFormatter.apply(Level.MILLISECOND)).append(separator);
// levelCount++; // levelCount++;
} }
} }
if (StrUtil.isEmpty(sb)) { if (StrUtil.isEmpty(sb)) {
sb.append(0).append(this.level.name); sb.append(0).append(levelFormatter.apply(this.level));
} else {
if (StrUtil.isNotEmpty(separator)) {
sb.delete(sb.length() - separator.length(), sb.length());
} }
}
return sb.toString(); // 自定义实现最后可能存在空格
return sb.toString().trim();
} }
/** /**
@ -199,6 +216,28 @@ public class BetweenFormatter implements Serializable {
return this; return this;
} }
/**
* 设置级别格式化器
*
* @param levelFormatter 级别格式化器
* @return this
*/
public BetweenFormatter setLevelFormatter(Function<Level, String> levelFormatter) {
this.levelFormatter = levelFormatter;
return this;
}
/**
* 设置分隔符
*
* @param separator 分割符
* @return this
*/
public BetweenFormatter setSeparator(String separator) {
this.separator = separator == null ? StrUtil.EMPTY : separator;
return this;
}
/** /**
* 格式化等级枚举 * 格式化等级枚举
* *

View File

@ -12,11 +12,31 @@
package org.dromara.hutool.core.date; package org.dromara.hutool.core.date;
import org.dromara.hutool.core.text.StrUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.function.Function;
public class BetweenFormatterTest { public class BetweenFormatterTest {
Function<BetweenFormatter.Level, String> levelFormatterEn = level -> {
switch (level) {
case DAY:
return " day";
case HOUR:
return " hour";
case MINUTE:
return " minute";
case SECOND:
return " second";
case MILLISECOND:
return " millisecond";
default:
return " " + level.name();
}
};
@Test @Test
public void formatTest() { public void formatTest() {
final long betweenMs = DateUtil.betweenMs(DateUtil.parse("2017-01-01 22:59:59"), DateUtil.parse("2017-01-02 23:59:58")); final long betweenMs = DateUtil.betweenMs(DateUtil.parse("2017-01-01 22:59:59"), DateUtil.parse("2017-01-02 23:59:58"));
@ -24,6 +44,14 @@ public class BetweenFormatterTest {
Assertions.assertEquals(formatter.toString(), "1天"); Assertions.assertEquals(formatter.toString(), "1天");
} }
@Test
public void formatTestEn() {
final long betweenMs = DateUtil.betweenMs(DateUtil.parse("2017-01-01 22:59:59"), DateUtil.parse("2017-01-02 23:59:58"));
final BetweenFormatter formatter = new BetweenFormatter(betweenMs, BetweenFormatter.Level.MILLISECOND, 1);
formatter.setLevelFormatter(levelFormatterEn);
Assertions.assertEquals(formatter.toString(), "1 day");
}
@Test @Test
public void formatBetweenTest() { public void formatBetweenTest() {
final long betweenMs = DateUtil.betweenMs(DateUtil.parse("2018-07-16 11:23:19"), DateUtil.parse("2018-07-16 11:23:20")); final long betweenMs = DateUtil.betweenMs(DateUtil.parse("2018-07-16 11:23:19"), DateUtil.parse("2018-07-16 11:23:20"));
@ -54,5 +82,8 @@ public class BetweenFormatterTest {
s = BetweenFormatter.of(3600000, BetweenFormatter.Level.MILLISECOND).setSimpleMode(false).format(); s = BetweenFormatter.of(3600000, BetweenFormatter.Level.MILLISECOND).setSimpleMode(false).format();
Assertions.assertEquals("1小时0分0秒", s); Assertions.assertEquals("1小时0分0秒", s);
s = BetweenFormatter.of(3600000, BetweenFormatter.Level.MILLISECOND).setSimpleMode(false).setLevelFormatter(levelFormatterEn).setSeparator(",").format();
Assertions.assertEquals("1 hour,0 minute,0 second", s);
} }
} }