LocalDateTime 的用法

Java 中 LocalDateTime 的全面用法

1. 创建 LocalDateTime 实例

1.1 当前时间

// 获取当前日期时间
LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间: " + now);  // 2026-01-21T10:30:15.123

// 获取当前时间(指定时区)
LocalDateTime nowInZone = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));

1.2 指定时间创建

// 通过指定年月日时分秒
LocalDateTime dateTime1 = LocalDateTime.of(2024, 12, 25, 14, 30, 45);
LocalDateTime dateTime2 = LocalDateTime.of(2024, Month.DECEMBER, 25, 14, 30, 45);

// 通过 LocalDate 和 LocalTime 组合
LocalDate date = LocalDate.of(2024, 12, 25);
LocalTime time = LocalTime.of(14, 30, 45);
LocalDateTime dateTime3 = LocalDateTime.of(date, time);

1.3 解析字符串

// ISO 格式解析
LocalDateTime dt1 = LocalDateTime.parse("2024-12-25T14:30:45");

// 自定义格式解析
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime dt2 = LocalDateTime.parse("2024/12/25 14:30:45", formatter);

// 中文日期解析
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
LocalDateTime dt3 = LocalDateTime.parse("2024年12月25日 14时30分45秒", chineseFormatter);

2. 获取日期时间信息

LocalDateTime dt = LocalDateTime.now();

// 获取日期部分
int year = dt.getYear();          // 年
Month month = dt.getMonth();      // 月份枚举
int monthValue = dt.getMonthValue(); // 月份数值
int dayOfMonth = dt.getDayOfMonth(); // 当月第几天
int dayOfYear = dt.getDayOfYear();   // 当年第几天
DayOfWeek dayOfWeek = dt.getDayOfWeek(); // 星期几枚举
int dayOfWeekValue = dt.getDayOfWeek().getValue(); // 星期几数值(1=周一)

// 获取时间部分
int hour = dt.getHour();         // 时
int minute = dt.getMinute();     // 分
int second = dt.getSecond();     // 秒
int nano = dt.getNano();         // 纳秒

3. 日期时间计算

3.1 加减操作

LocalDateTime dt = LocalDateTime.now();

// 加法
LocalDateTime plusYears = dt.plusYears(1);      // 加1年
LocalDateTime plusMonths = dt.plusMonths(2);    // 加2月
LocalDateTime plusWeeks = dt.plusWeeks(3);      // 加3周
LocalDateTime plusDays = dt.plusDays(7);        // 加7天
LocalDateTime plusHours = dt.plusHours(3);      // 加3小时
LocalDateTime plusMinutes = dt.plusMinutes(30); // 加30分钟
LocalDateTime plusSeconds = dt.plusSeconds(45); // 加45秒

// 减法
LocalDateTime minusYears = dt.minusYears(1);    // 减1年
LocalDateTime minusHours = dt.minusHours(2);    // 减2小时

// 链式调用
LocalDateTime result = dt.plusDays(7).minusHours(3);

3.2 使用 TemporalAmount

LocalDateTime dt = LocalDateTime.now();

// 使用 Period(日期部分)
Period oneMonth = Period.ofMonths(1);
LocalDateTime nextMonth = dt.plus(oneMonth);

// 使用 Duration(时间部分)
Duration twoHours = Duration.ofHours(2);
LocalDateTime later = dt.plus(twoHours);

// 组合使用
LocalDateTime combined = dt.plus(oneMonth).plus(twoHours);

4. 日期时间比较

LocalDateTime dt1 = LocalDateTime.parse("2024-12-25T14:30:00");
LocalDateTime dt2 = LocalDateTime.parse("2024-12-26T10:00:00");

// 比较
boolean isBefore = dt1.isBefore(dt2);  // true
boolean isAfter = dt1.isAfter(dt2);    // false
boolean isEqual = dt1.isEqual(dt2);    // false

// 获取时间差
Duration duration = Duration.between(dt1, dt2);
long hours = duration.toHours();       // 19小时
long minutes = duration.toMinutes();   // 1170分钟

// 比较日期部分
boolean sameDay = dt1.toLocalDate().isEqual(dt2.toLocalDate());  // false

5. 格式化输出

LocalDateTime dt = LocalDateTime.now();

// 默认格式
String defaultFormat = dt.toString();  // 2024-12-25T14:30:45.123

// 自定义格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format1 = dt.format(formatter1);  // 2024-12-25 14:30:45

DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
String format2 = dt.format(formatter2);  // 2024年12月25日 14时30分45秒

DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("EEE, MMM dd, yyyy hh:mm a", Locale.US);
String format3 = dt.format(formatter3);  // Wed, Dec 25, 2024 02:30 PM

// 预定义格式
String isoFormat = dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

6. 与其它类型转换

6.1 与字符串互转

// LocalDateTime -> String
LocalDateTime dt = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
String str = dt.format(formatter);

// String -> LocalDateTime
LocalDateTime parsed = LocalDateTime.parse(str, formatter);

6.2 与 Date 互转

// LocalDateTime -> Date
LocalDateTime ldt = LocalDateTime.now();
Date date = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

// Date -> LocalDateTime
Date oldDate = new Date();
LocalDateTime newLdt = oldDate.toInstant()
    .atZone(ZoneId.systemDefault())
    .toLocalDateTime();

6.3 与 Timestamp 互转

// LocalDateTime -> Timestamp
LocalDateTime ldt = LocalDateTime.now();
Timestamp timestamp = Timestamp.valueOf(ldt);

// Timestamp -> LocalDateTime
LocalDateTime fromTimestamp = timestamp.toLocalDateTime();

6.4 与 LocalDate/LocalTime 转换

LocalDateTime dt = LocalDateTime.now();

// 拆分为日期和时间
LocalDate date = dt.toLocalDate();  // 只获取日期部分
LocalTime time = dt.toLocalTime();  // 只获取时间部分

// 重新组合
LocalDateTime newDateTime = LocalDateTime.of(date, time);

7. 实际应用场景

7.1 验证日期

// 判断是否是特定日期
public boolean isChristmas(LocalDateTime dateTime) {
    return dateTime.getMonth() == Month.DECEMBER && dateTime.getDayOfMonth() == 25;
}

// 判断是否在工作时间内
public boolean isWorkingHours(LocalDateTime dateTime) {
    LocalTime time = dateTime.toLocalTime();
    return time.isAfter(LocalTime.of(9, 0)) 
        && time.isBefore(LocalTime.of(18, 0))
        && dateTime.getDayOfWeek().getValue() <= 5;  // 周一到周五
}

7.2 计算时间差

public String getTimeAgo(LocalDateTime pastTime) {
    Duration duration = Duration.between(pastTime, LocalDateTime.now());
    
    if (duration.toMinutes() < 1) {
        return "刚刚";
    } else if (duration.toHours() < 1) {
        return duration.toMinutes() + "分钟前";
    } else if (duration.toDays() < 1) {
        return duration.toHours() + "小时前";
    } else {
        return duration.toDays() + "天前";
    }
}

7.3 定时任务示例

// 计算下次执行时间
public LocalDateTime calculateNextExecution(LocalDateTime lastExecution, Duration interval) {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime nextExecution = lastExecution.plus(interval);
    
    // 如果下次执行时间已过,找到下一个可执行时间
    while (nextExecution.isBefore(now)) {
        nextExecution = nextExecution.plus(interval);
    }
    
    return nextExecution;
}

8. 数据库操作(JPA/Hibernate)

@Entity
@Table(name = "orders")
public class Order {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String orderNo;
    
    // 直接映射
    @Column(name = "create_time")
    private LocalDateTime createTime;
    
    @Column(name = "update_time")
    private LocalDateTime updateTime;
    
    // 自动设置创建和更新时间
    @PrePersist
    protected void onCreate() {
        createTime = LocalDateTime.now();
        updateTime = createTime;
    }
    
    @PreUpdate
    protected void onUpdate() {
        updateTime = LocalDateTime.now();
    }
    
    // 业务方法:计算过期时间
    public LocalDateTime getExpireTime() {
        return createTime.plusDays(30);  // 30天后过期
    }
    
    // 判断是否过期
    public boolean isExpired() {
        return LocalDateTime.now().isAfter(getExpireTime());
    }
}

9. 实用工具类示例

public class DateTimeUtils {
    
    // 获取当天开始时间
    public static LocalDateTime getStartOfDay(LocalDateTime dateTime) {
        return dateTime.toLocalDate().atStartOfDay();
    }
    
    // 获取当天结束时间
    public static LocalDateTime getEndOfDay(LocalDateTime dateTime) {
        return dateTime.toLocalDate().atTime(LocalTime.MAX);
    }
    
    // 获取本周第一天
    public static LocalDateTime getStartOfWeek(LocalDateTime dateTime) {
        return dateTime.minusDays(dateTime.getDayOfWeek().getValue() - 1)
                      .toLocalDate()
                      .atStartOfDay();
    }
    
    // 获取本月第一天
    public static LocalDateTime getStartOfMonth(LocalDateTime dateTime) {
        return dateTime.withDayOfMonth(1)
                      .toLocalDate()
                      .atStartOfDay();
    }
    
    // 格式化显示
    public static String formatDateTime(LocalDateTime dateTime, String pattern) {
        if (dateTime == null) return "";
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }
    
    // 判断两个时间是否在同一周
    public static boolean isSameWeek(LocalDateTime dt1, LocalDateTime dt2) {
        LocalDateTime startOfWeek1 = getStartOfWeek(dt1);
        LocalDateTime startOfWeek2 = getStartOfWeek(dt2);
        return startOfWeek1.isEqual(startOfWeek2);
    }
}

10. 常见注意事项

// 1. 不可变性(每次操作都返回新对象)
LocalDateTime original = LocalDateTime.now();
LocalDateTime modified = original.plusDays(1);
System.out.println(original == modified);  // false

// 2. 时区处理
LocalDateTime localDateTime = LocalDateTime.now();  // 不带时区
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));  // 带时区

// 3. 空值处理
public void processDateTime(@Nullable LocalDateTime dateTime) {
    if (dateTime == null) {
        dateTime = LocalDateTime.now();  // 设置默认值
    }
    // 处理逻辑
}

// 4. 序列化(配合 Jackson)
// 在配置文件中添加:
// spring.jackson.serialization.write-dates-as-timestamps=false
// spring.jackson.time-zone=Asia/Shanghai

总结

  1. LocalDateTime 是不可变和线程安全的
  2. 所有修改操作都返回新对象
  3. 非常适合表示不含时区的本地日期时间
  4. 与 MySQL 的 datetime 类型完美对应
  5. 建议新项目全部使用 java.time 包
posted @ 2026-01-21 11:14  棠仔517890027  阅读(20)  评论(0)    收藏  举报