← 返回首页
📅

Java日期时间API详解:LocalDate、LocalTime、LocalDateTime

📂 java ⏱ 4 min 794 words

Java日期时间API详解:LocalDate、LocalTime、LocalDateTime

概述

Java 8引入了全新的日期时间API(java.time包),提供了更强大、更易用的日期时间处理能力。新的API是不可变的、线程安全的,解决了旧API(Date、Calendar)的许多问题。

1. LocalDate

import java.time.LocalDate;
import java.time.Month;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;

public class LocalDateExample {
    public static void main(String[] args) {
        // 创建LocalDate
        LocalDate today = LocalDate.now();
        System.out.println("今天: " + today);
        
        LocalDate specificDate = LocalDate.of(2024, Month.JANUARY, 15);
        System.out.println("特定日期: " + specificDate);
        
        LocalDate fromString = LocalDate.parse("2024-01-15");
        System.out.println("从字符串解析: " + fromString);
        
        // 获取日期信息
        System.out.println("年: " + today.getYear());
        System.out.println("月: " + today.getMonth());
        System.out.println("月份数字: " + today.getMonthValue());
        System.out.println("日: " + today.getDayOfMonth());
        System.out.println("星期: " + today.getDayOfWeek());
        System.out.println("一年中的第几天: " + today.getDayOfYear());
        
        // 日期操作
        LocalDate tomorrow = today.plusDays(1);
        System.out.println("明天: " + tomorrow);
        
        LocalDate nextWeek = today.plusWeeks(1);
        System.out.println("下周: " + nextWeek);
        
        LocalDate nextMonth = today.plusMonths(1);
        System.out.println("下个月: " + nextMonth);
        
        LocalDate lastMonth = today.minusMonths(1);
        System.out.println("上个月: " + lastMonth);
        
        // 日期调整
        LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        System.out.println("下周一: " + nextMonday);
        
        LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("本月最后一天: " + lastDayOfMonth);
        
        // 日期比较
        System.out.println("是否在之后: " + today.isAfter(specificDate));
        System.out.println("是否在之前: " + today.isBefore(specificDate));
        System.out.println("是否相等: " + today.equals(specificDate));
    }
}

2. LocalTime

import java.time.LocalTime;

public class LocalTimeExample {
    public static void main(String[] args) {
        // 创建LocalTime
        LocalTime now = LocalTime.now();
        System.out.println("现在: " + now);
        
        LocalTime specificTime = LocalTime.of(14, 30, 0);
        System.out.println("特定时间: " + specificTime);
        
        LocalTime fromString = LocalTime.parse("14:30:00");
        System.out.println("从字符串解析: " + fromString);
        
        // 获取时间信息
        System.out.println("时: " + now.getHour());
        System.out.println("分: " + now.getMinute());
        System.out.println("秒: " + now.getSecond());
        System.out.println("纳秒: " + now.getNano());
        
        // 时间操作
        LocalTime later = now.plusHours(2);
        System.out.println("两小时后: " + later);
        
        LocalTime earlier = now.minusMinutes(30);
        System.out.println("30分钟前: " + earlier);
        
        // 时间比较
        System.out.println("是否在之后: " + now.isAfter(specificTime));
        System.out.println("是否在之前: " + now.isBefore(specificTime));
    }
}

3. LocalDateTime

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeExample {
    public static void main(String[] args) {
        // 创建LocalDateTime
        LocalDateTime now = LocalDateTime.now();
        System.out.println("现在: " + now);
        
        LocalDateTime specificDateTime = LocalDateTime.of(2024, 1, 15, 14, 30);
        System.out.println("特定日期时间: " + specificDateTime);
        
        // 从LocalDate和LocalTime组合
        LocalDateTime combined = LocalDateTime.of(
            LocalDate.of(2024, 1, 15),
            LocalTime.of(14, 30)
        );
        System.out.println("组合: " + combined);
        
        // 日期时间操作
        LocalDateTime tomorrow = now.plusDays(1).plusHours(2);
        System.out.println("明天此时加2小时: " + tomorrow);
        
        // 格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatted = now.format(formatter);
        System.out.println("格式化: " + formatted);
        
        // 解析
        LocalDateTime parsed = LocalDateTime.parse("2024-01-15 14:30:00", formatter);
        System.out.println("解析: " + parsed);
        
        // 提取日期和时间
        System.out.println("日期: " + now.toLocalDate());
        System.out.println("时间: " + now.toLocalTime());
    }
}

4. Instant和Duration

import java.time.Instant;
import java.time.Duration;
import java.time.temporal.ChronoUnit;

public class InstantDurationExample {
    public static void main(String[] args) {
        // Instant:时间戳
        Instant now = Instant.now();
        System.out.println("现在: " + now);
        
        Instant fromMillis = Instant.ofEpochMilli(1705312200000L);
        System.out.println("从毫秒: " + fromMillis);
        
        Instant fromSeconds = Instant.ofEpochSecond(1705312200);
        System.out.println("从秒: " + fromSeconds);
        
        // Duration:时间间隔
        Instant start = Instant.now();
        // 模拟一些操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Instant end = Instant.now();
        
        Duration duration = Duration.between(start, end);
        System.out.println("持续时间: " + duration);
        System.out.println("秒: " + duration.getSeconds());
        System.out.println("毫秒: " + duration.toMillis());
        
        // Duration计算
        Duration twoHours = Duration.ofHours(2);
        Duration thirtyMinutes = Duration.ofMinutes(30);
        Duration total = twoHours.plus(thirtyMinutes);
        System.out.println("总时间: " + total);
        System.out.println("总分钟: " + total.toMinutes());
    }
}

5. Period

import java.time.Period;
import java.time.LocalDate;

public class PeriodExample {
    public static void main(String[] args) {
        // Period:日期间隔
        LocalDate startDate = LocalDate.of(2024, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);
        
        Period period = Period.between(startDate, endDate);
        System.out.println("期间: " + period);
        System.out.println("年: " + period.getYears());
        System.out.println("月: " + period.getMonths());
        System.out.println("天: " + period.getDays());
        
        // Period计算
        Period twoYears = Period.ofYears(2);
        Period threeMonths = Period.ofMonths(3);
        Period tenDays = Period.ofDays(10);
        
        Period total = twoYears.plus(threeMonths).plus(tenDays);
        System.out.println("总期间: " + total);
        
        // 使用Period调整日期
        LocalDate futureDate = LocalDate.now().plus(total);
        System.out.println("未来日期: " + futureDate);
    }
}

6. ZonedDateTime和时区

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class ZonedDateTimeExample {
    public static void main(String[] args) {
        // 获取当前时区的日期时间
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println("现在: " + now);
        
        // 指定时区
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println("东京时间: " + tokyoTime);
        
        ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
        System.out.println("纽约时间: " + newYorkTime);
        
        // 时区转换
        ZonedDateTime converted = now.withZoneSameInstant(ZoneId.of("Europe/London"));
        System.out.println("伦敦时间: " + converted);
        
        // 格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
        String formatted = now.format(formatter);
        System.out.println("格式化: " + formatted);
    }
}

7. 实际应用示例

日期工具类

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class DateUtils {
    private static final DateTimeFormatter DATE_FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
    private static final DateTimeFormatter DATETIME_FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    // 获取当前日期字符串
    public static String getCurrentDate() {
        return LocalDate.now().format(DATE_FORMATTER);
    }
    
    // 获取当前日期时间字符串
    public static String getCurrentDateTime() {
        return LocalDateTime.now().format(DATETIME_FORMATTER);
    }
    
    // 计算两个日期之间的天数
    public static long daysBetween(LocalDate start, LocalDate end) {
        return ChronoUnit.DAYS.between(start, end);
    }
    
    // 计算两个日期之间的月数
    public static long monthsBetween(LocalDate start, LocalDate end) {
        return ChronoUnit.MONTHS.between(start, end);
    }
    
    // 判断是否是闰年
    public static boolean isLeapYear(int year) {
        return Year.isLeap(year);
    }
    
    // 获取某月的天数
    public static int getDaysInMonth(int year, int month) {
        return YearMonth.of(year, month).lengthOfMonth();
    }
    
    // 日期字符串转LocalDate
    public static LocalDate parseDate(String dateStr) {
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }
    
    // 日期时间字符串转LocalDateTime
    public static LocalDateTime parseDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    }
    
    public static void main(String[] args) {
        System.out.println("当前日期: " + getCurrentDate());
        System.out.println("当前日期时间: " + getCurrentDateTime());
        
        LocalDate start = LocalDate.of(2024, 1, 1);
        LocalDate end = LocalDate.of(2024, 12, 31);
        System.out.println("2024年天数: " + daysBetween(start, end));
        
        System.out.println("2024年是否闰年: " + isLeapYear(2024));
        System.out.println("2024年2月天数: " + getDaysInMonth(2024, 2));
    }
}

8. 最佳实践

  1. 使用新API:优先使用java.time包,而不是Date和Calendar
  2. 不可变对象:LocalDate、LocalTime等都是不可变的,线程安全
  3. 使用DateTimeFormatter:格式化日期时间
  4. 时区处理:使用ZonedDateTime处理时区相关操作
  5. 避免使用Date:Date是可变的,线程不安全

总结

Java 8引入的新日期时间API提供了更强大、更易用的日期时间处理能力。掌握LocalDate、LocalTime、LocalDateTime等类的使用,是现代Java编程的重要技能。