摘要:主要功能包括解析不同格式的时间字符串、生成默认时间值以及处理时间参数。它能识别"yyyy-MM-dd"或"yyyy-MM-dd HH:mm:ss"两种格式的时间输入,对于仅日期的输入会自动补全时间部分(起始时间补全为00:00:00,结束时间补全为23:59:59),并对非法格式抛出明确异常。该类提供了生成默认时间的方法,包括返回一个月前00:00:00的默认起始时间和返回当天23:59:59的默认结束时间,同时提供了处理时间参数的方法,可以自动处理空值情况并应用默认值。
关键词:Java;时间处理;工具类;日期时间解析
一、引言
在Java开发中,对时间的处理是一个常见需求。不同业务场景可能需要对时间进行不同格式的解析、设置默认时间值以及处理用户输入的时间参数等操作。TimeUtils类旨在提供一套统一且便捷的方法来满足这些需求,提高代码的复用性和开发效率。
二、TimeUtils类设计
2.1 类结构与成员变量
TimeUtils类包含两个私有静态常量DATE_FORMATTER和DATETIME_FORMATTER,分别定义了日期格式"yyyy - MM - dd"和日期时间格式"yyyy - MM - dd HH:mm:ss",用于时间的格式化和解析。
// 日期格式: yyyy-MM-dd
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 日期时间格式: yyyy-MM-dd HH:mm:ss
private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");2.2 时间解析方法
parseTime方法用于解析输入的时间字符串,并根据isStartTime标志设置具体时间。它首先尝试按完整日期时间格式解析,如果失败则尝试按日期格式解析,并根据isStartTime决定设置为当天的起始时间(00:00:00)或结束时间(23:59:59)。如果两种解析都失败,则抛出RuntimeException。
public static String parseTime(String timeStr, boolean isStartTime) {
try {
// 尝试按完整日期时间格式解析
LocalDateTime dateTime = LocalDateTime.parse(timeStr, DATETIME_FORMATTER);
return dateTime.format(DATETIME_FORMATTER);
} catch (Exception e1) {
try {
// 尝试按日期格式解析
LocalDate date = LocalDate.parse(timeStr, DATE_FORMATTER);
if (isStartTime) {
// 起始时间设置为当天的00:00:00
return date.atStartOfDay().format(DATETIME_FORMATTER);
} else {
// 结束时间设置为当天的23:59:59
return date.atTime(23, 59, 59).format(DATETIME_FORMATTER);
}
} catch (Exception e2) {
throw new RuntimeException("时间格式错误,支持格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss", e2);
}
}
}2.3 获取默认时间方法
getDefaultStartTime方法返回一个月前的起始时间(00:00:00),getDefaultEndTime方法返回当天的结束时间(23:59:59)。(看标题四,选择更多款式时间设置,比如获取当天时间)
public static String getDefaultStartTime() {
return LocalDate.now()
.minus(1, ChronoUnit.MONTHS)
.atStartOfDay()
.format(DATETIME_FORMATTER);
}
public static String getDefaultEndTime() {
return LocalDate.now()
.atTime(23, 59, 59)
.format(DATETIME_FORMATTER);
}现在是2025-07-01
.一个月前就是2025-06-01.
2.4 时间参数处理方法
processStartTime和processEndTime方法分别用于处理起始时间和结束时间参数。如果输入的时间字符串为空或空白,将返回默认的起始或结束时间;否则,调用parseTime方法进行解析。
public static String processStartTime(String startTime) {
if (StringUtils.isBlank(startTime)) {
return getDefaultStartTime();
}
return parseTime(startTime, true);
}
public static String processEndTime(String endTime) {
if (StringUtils.isBlank(endTime)) {
return getDefaultEndTime();
}
return parseTime(endTime, false);
}三、TimeUtilsDemo类调用
TimeUtilsDemo类通过多个示例展示了TimeUtils类的使用方法。
- 解析完整日期时间格式:输入完整的日期时间字符串
"2023 - 01 - 15 14:30:00",输出保持相同格式。
// 示例1: 解析完整日期时间格式
String time1 = "2023-01-15 14:30:00";
String parsed1 = TimeUtils.parseTime(time1, true);
System.out.println("解析完整日期时间格式:");
System.out.println("输入: " + time1);
System.out.println("输出: " + parsed1);
System.out.println();- 解析仅日期格式(起始时间):输入仅包含日期的字符串
"2023 - 01 - 15",输出为当天起始时间"2023 - 01 - 15 00:00:00"。
// 示例2: 解析仅日期格式(起始时间)
String time2 = "2023-01-15";
String parsed2 = TimeUtils.parseTime(time2, true);
System.out.println("解析仅日期格式(起始时间):");
System.out.println("输入: " + time2);
System.out.println("输出: " + parsed2);
System.out.println();- 解析仅日期格式(结束时间):输入仅包含日期的字符串
"2023 - 01 - 15",输出为当天结束时间"2023 - 01 - 15 23:59:59"。
// 示例3: 解析仅日期格式(结束时间)
String time3 = "2023-01-15";
String parsed3 = TimeUtils.parseTime(time3, false);
System.out.println("解析仅日期格式(结束时间):");
System.out.println("输入: " + time3);
System.out.println("输出: " + parsed3);
System.out.println();- 处理空白起始时间:输入空白字符串,输出默认起始时间。
// 示例4: 处理空白起始时间(应返回默认值)
String time4 = "";
String parsed4 = TimeUtils.processStartTime(time4);
System.out.println("处理空白起始时间:");
System.out.println("输入: \"" + time4 + "\"");
System.out.println("输出: " + parsed4);
System.out.println();- 处理空白结束时间:输入空白字符串,输出默认结束时间。
// 示例5: 处理空白结束时间(应返回默认值)
String time5 = "";
String parsed5 = TimeUtils.processEndTime(time5);
System.out.println("处理空白结束时间:");
System.out.println("输入: \"" + time5 + "\"");
System.out.println("输出: " + parsed5);
System.out.println();- 处理有效起始时间:输入有效日期字符串,输出解析后的起始时间。
// 示例6: 处理有效起始时间
String time6 = "2023-01-15";
String parsed6 = TimeUtils.processStartTime(time6);
System.out.println("处理有效起始时间:");
System.out.println("输入: " + time6);
System.out.println("输出: " + parsed6);
System.out.println();- 处理有效结束时间:输入有效日期字符串,输出解析后的结束时间。
// 示例7: 处理有效结束时间
String time7 = "2023-01-15";
String parsed7 = TimeUtils.processEndTime(time7);
System.out.println("处理有效结束时间:");
System.out.println("输入: " + time7);
System.out.println("输出: " + parsed7);解析完整日期时间格式:
输入: 2023-01-15 14:30:00
输出: 2023-01-15 14:30:00
解析仅日期格式(起始时间):
输入: 2023-01-15
输出: 2023-01-15 00:00:00
解析仅日期格式(结束时间):
输入: 2023-01-15
输出: 2023-01-15 23:59:59
处理空白起始时间:
输入: ""
输出: 2025-06-09 00:00:00
处理空白结束时间:
输入: ""
输出: 2025-07-09 23:59:59
处理有效起始时间:
输入: 2023-01-15
输出: 2023-01-15 00:00:00
处理有效结束时间:
输入: 2023-01-15
输出: 2023-01-15 23:59:59
Process finished with exit code 0如果你想修改 getDefaultStartTime() 方法,使其返回不同的默认起始时间(而不是固定的"一个月前的00:00:00"),以下是几种常见的调整方式及对应的代码实现:
四、更改初始时间设置
1. 修改为固定日期(如2025-01-01 00:00:00)
public static String getDefaultStartTime() {
return LocalDate.parse("2025-01-01") // 直接指定固定日期
.atStartOfDay() // 设置为当天的00:00:00
.format(DATETIME_FORMATTER); // 格式化为字符串
}2. 修改为当前日期的00:00:00(当天起始时间)
public static String getDefaultStartTime() {
return LocalDate.now() // 当前日期
.atStartOfDay() // 设置为当天的00:00:00
.format(DATETIME_FORMATTER); // 格式化为字符串
}3. 修改为N天前的00:00:00(如7天前)
public static String getDefaultStartTime() {
return LocalDate.now()
.minus(7, ChronoUnit.DAYS) // 减去7天(可调整天数)
.atStartOfDay() // 设置为当天的00:00:00
.format(DATETIME_FORMATTER); // 格式化为字符串
}4. 修改为自定义日期(通过参数动态传入)
如果希望更灵活地指定日期,可以改为带参数的方法:
/**
* 获取自定义起始时间(默认00:00:00)
* @param daysOffset 相对于当前日期的偏移天数(正数为未来,负数为过去)
* @return 格式化后的起始时间字符串
*/
public static String getDefaultStartTime(int daysOffset) {
return LocalDate.now()
.minus(daysOffset, ChronoUnit.DAYS) // 按偏移天数计算日期
.atStartOfDay() // 设置为00:00:00
.format(DATETIME_FORMATTER); // 格式化为字符串
}
// 调用示例:获取3天前的起始时间
String startTime = getDefaultStartTime(3); // 3天前
String startTime = getDefaultStartTime(-5); // 5天后(未来)5. 修改为指定月份的1号00:00:00(如每月1号)
public static String getDefaultStartTime() {
return LocalDate.now()
.withDayOfMonth(1) // 设置为当月1号
.atStartOfDay() // 设置为00:00:00
.format(DATETIME_FORMATTER); // 格式化为字符串
}6. 完全自定义日期时间(精确到小时分钟秒)
如果需要更精确的控制(如固定时间点):
public static String getDefaultStartTime() {
return LocalDateTime.of(2023, 1, 1, 8, 30, 0) // 指定2023-01-01 08:30:00
.format(DATETIME_FORMATTER); // 复用已定义的格式化器
}如何选择?
场景 | 推荐方法 |
固定历史日期 | 方法1(直接指定日期) |
当天起始时间 | 方法2 |
过去N天 | 方法3(调整天数) |
动态调整日期 | 方法4(带参数) |
每月1号统计 | 方法5 |
精确时间点 | 方法6 |
五、完整代码
package com.example.utils;
import org.apache.commons.lang3.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
/**
* 时间处理工具类
*/
public class TimeUtils {
// 日期格式: yyyy-MM-dd
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 日期时间格式: yyyy-MM-dd HH:mm:ss
private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 解析时间字符串,根据是否为起始时间设置具体时间
* @param timeStr 时间字符串,格式可为 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss
* @param isStartTime 是否为起始时间
* @return 格式化后的时间字符串,格式为 yyyy-MM-dd HH:mm:ss
* @throws RuntimeException 如果时间格式错误
*/
public static String parseTime(String timeStr, boolean isStartTime) {
try {
// 尝试按完整日期时间格式解析
LocalDateTime dateTime = LocalDateTime.parse(timeStr, DATETIME_FORMATTER);
return dateTime.format(DATETIME_FORMATTER);
} catch (Exception e1) {
try {
// 尝试按日期格式解析
LocalDate date = LocalDate.parse(timeStr, DATE_FORMATTER);
if (isStartTime) {
// 起始时间设置为当天的00:00:00
return date.atStartOfDay().format(DATETIME_FORMATTER);
} else {
// 结束时间设置为当天的23:59:59
return date.atTime(23, 59, 59).format(DATETIME_FORMATTER);
}
} catch (Exception e2) {
throw new RuntimeException("时间格式错误,支持格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss", e2);
}
}
}
/**
* 获取默认起始时间(一个月前的00:00:00)
* @return 格式化后的时间字符串
*/
public static String getDefaultStartTime() {
return LocalDate.now()
.minus(1, ChronoUnit.MONTHS)
.atStartOfDay()
.format(DATETIME_FORMATTER);
}
/**
* 获取默认结束时间(当天的23:59:59)
* @return 格式化后的时间字符串
*/
public static String getDefaultEndTime() {
return LocalDate.now()
.atTime(23, 59, 59)
.format(DATETIME_FORMATTER);
}
/**
* 处理起始时间参数
* @param startTime 输入的起始时间字符串(可为null或空)
* @return 处理后的起始时间字符串
*/
public static String processStartTime(String startTime) {
if (StringUtils.isBlank(startTime)) {
return getDefaultStartTime();
}
return parseTime(startTime, true);
}
/**
* 处理结束时间参数
* @param endTime 输入的结束时间字符串(可为null或空)
* @return 处理后的结束时间字符串
*/
public static String processEndTime(String endTime) {
if (StringUtils.isBlank(endTime)) {
return getDefaultEndTime();
}
return parseTime(endTime, false);
}
}
















