相信大家在Java后端项目开发中,都遇到过需要格式化的时间字段,比如createTime, deliveryTime, lockTime等等。 parse,format傻傻分不清。本文介绍一下OffsetDateTime工具类,时间相关需求用它就够了。
OffsetDateTime
OffsetDateTime 是 Java 8 中引入的一个日期时间类,用于表示带有时区偏移的日期和时间。它本质上是一个不可变的日期时间对象,包含了年、月、日、时、分、秒、纳秒以及与 UTC 的时区偏移量。
OffsetDateTime 特点
- 可精确到纳秒: 可以存储纳秒级别的时间信息。
- 包含时区偏移: 它可以处理全球任何地点的日期和时间,带有与UTC/格林威治时间的偏移量。
- 不可变性: 一旦创建,就不能修改,保证了线程安全。
- 链式方法调用:OffsetDateTime 提供了大量的方法来进行日期和时间的计算,比如加减日期、时间单位等。由于其不变性,这些方法返回的是修改后的新对象,支持链式调用,使代码更加清晰。
最佳实践
场景1 Web或者APP显示约定的时间格式
mysql,tidb或者oceanbase等存的时间字段直接吐给前端,显示的是时间戳。一些业务场景时间戳肯定不行,最常用的是yyyy-MM-dd HH:mm:ss格式。
public class FormatDateDemo1{
public String parseTimeStamp(String timeStamp){
String pattern = "yyyy-MM-dd HH:mm:ss";
OffsetDateTime lockTime = OffsetDateTime.parse(timeStamp, DateTimeFormatter.ofPattern(pattern))
return lockTime.format(DateTimeFormatter.ofPattern(pattern));
}
场景2 定时任务扫表,处理业务逻辑
假如现在有一个定时任务,任务的使用参考Elastic-Job中的cron表达式妙用,定时任务的触发(0 0/5 * * * ?)是每5分钟1次。每次扫描前5分钟订单表中生成的数据,不能重复,用于后续的业务逻辑处理。那么,问题来了,* * * 00:00:00的时间如何处理?
public class FormatDateDemo2{
public LockDto processStartTime(){
OffsetDateTime nowTime = OffsetDateTime.now();
int hour = offsetDateTimeDay.getHour();
int minute = offsetDateTimeDay.getMinute();
OffsetDateTime curTime = nowTime;
// 不满足的时间区间[* * * 00:00:00, * * * 00:05:00]
if (!(hour == 0 && minute <= 5)) {
curTime = curTime.minusMinutes(5);
}
String pattern = "yyyy-MM-dd HH:mm:ss";
String startTime = curTime.format(DateTimeFormatter.ofPattern(pattern));
String endTime = nowTime.format(DateTimeFormatter.ofPattern(pattern));
return LockDto.Builder.startTime(startTime).endTime(endTime).build();
}
@Data
@Builder
public static class LockDto{
private String startTime;
private String endTime;
}
}