Java8时间API案例

wen java案例 1

Java 8 时间API完整案例指南

Java 8引入了全新的日期时间API(java.time包),解决了旧API的线程安全性和设计问题,下面通过完整案例来学习。

Java8时间API案例

环境准备

import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
import java.util.*;
import java.util.stream.*;

基础日期时间操作

1 获取当前日期时间

public class BasicDateTimeDemo {
    public static void main(String[] args) {
        // 当前日期
        LocalDate today = LocalDate.now();
        System.out.println("当前日期: " + today);
        // 当前时间
        LocalTime currentTime = LocalTime.now();
        System.out.println("当前时间: " + currentTime);
        // 当前日期时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println("当前日期时间: " + currentDateTime);
        // 带时区的日期时间
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        System.out.println("带时区的日期时间: " + zonedDateTime);
        // 指定时区
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println("东京时间: " + tokyoTime);
    }
}

2 创建指定日期时间

public class CreateDateTimeDemo {
    public static void main(String[] args) {
        // 创建指定日期
        LocalDate date = LocalDate.of(2024, 3, 15);
        System.out.println("指定日期: " + date);
        // 创建指定时间
        LocalTime time = LocalTime.of(14, 30, 45, 100);
        System.out.println("指定时间: " + time);
        // 创建指定日期时间
        LocalDateTime dateTime = LocalDateTime.of(2024, 3, 15, 14, 30, 45);
        System.out.println("指定日期时间: " + dateTime);
        // 从字符串解析
        LocalDate parsedDate = LocalDate.parse("2024-03-15");
        System.out.println("解析日期: " + parsedDate);
        LocalDateTime parsedDateTime = LocalDateTime.parse("2024-03-15T14:30:45");
        System.out.println("解析日期时间: " + parsedDateTime);
        // 使用自定义格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        LocalDate customDate = LocalDate.parse("2024/03/15", formatter);
        System.out.println("自定义格式日期: " + customDate);
    }
}

日期时间操作

1 加减操作

public class DateTimeArithmeticDemo {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        // 加天、周、月、年
        LocalDate plusDays = today.plusDays(10);
        LocalDate plusWeeks = today.plusWeeks(2);
        LocalDate plusMonths = today.plusMonths(3);
        LocalDate plusYears = today.plusYears(1);
        System.out.println(" " + today);
        System.out.println("加10天: " + plusDays);
        System.out.println("加2周: " + plusWeeks);
        System.out.println("加3月: " + plusMonths);
        System.out.println("加1年: " + plusYears);
        // 减天、周、月、年
        LocalDate minusDays = today.minusDays(5);
        LocalDate minusMonths = today.minusMonths(2);
        System.out.println("减5天: " + minusDays);
        System.out.println("减2月: " + minusMonths);
        // 使用TemporalAmount
        LocalDate plusPeriod = today.plus(Period.ofYears(1).plusMonths(2).plusDays(3));
        System.out.println("加1年2月3天: " + plusPeriod);
        // 时间加减
        LocalTime time = LocalTime.of(10, 30);
        LocalTime plusHours = time.plusHours(2);
        LocalTime minusMinutes = time.minusMinutes(45);
        System.out.println("时间加2小时: " + plusHours);
        System.out.println("时间减45分钟: " + minusMinutes);
    }
}

2 日期时间修改

public class DateTimeModifyDemo {
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.of(2024, 3, 15, 14, 30, 45);
        System.out.println("原始: " + dateTime);
        // 修改年份
        LocalDateTime withYear = dateTime.withYear(2025);
        System.out.println("修改年份: " + withYear);
        // 修改月份
        LocalDateTime withMonth = dateTime.withMonth(12);
        System.out.println("修改月份: " + withMonth);
        // 修改天
        LocalDateTime withDay = dateTime.withDayOfMonth(1);
        System.out.println("修改天: " + withDay);
        // 修改小时
        LocalDateTime withHour = dateTime.withHour(9);
        System.out.println("修改小时: " + withHour);
        // 修改时间部分
        LocalDateTime withTime = dateTime.with(LocalTime.NOON);
        System.out.println("修改为中午: " + withTime);
        // 修改日期部分
        LocalDateTime withDate = dateTime.with(LocalDate.of(2023, 1, 1));
        System.out.println("修改日期: " + withDate);
        // 使用ChronoField
        LocalDateTime withField = dateTime.with(ChronoField.DAY_OF_WEEK, 1); // 设为星期一
        System.out.println("设为周一: " + withField);
    }
}

日期时间比较

public class DateTimeCompareDemo {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2024, 3, 15);
        LocalDate date2 = LocalDate.of(2024, 3, 20);
        // 比较日期
        System.out.println("date1是否在date2之前: " + date1.isBefore(date2));
        System.out.println("date1是否在date2之后: " + date1.isAfter(date2));
        System.out.println("date1是否等于date2: " + date1.isEqual(date2));
        // compareTo方法
        int comparison = date1.compareTo(date2);
        System.out.println("比较结果: " + comparison); // 负数表示date1在date2之前
        // 时间比较
        LocalTime time1 = LocalTime.of(10, 30);
        LocalTime time2 = LocalTime.of(11, 30);
        System.out.println("time1是否早于time2: " + time1.isBefore(time2));
        // 日期时间比较
        LocalDateTime dt1 = LocalDateTime.of(2024, 3, 15, 10, 30);
        LocalDateTime dt2 = LocalDateTime.of(2024, 3, 15, 11, 30);
        System.out.println("dt1是否早于dt2: " + dt1.isBefore(dt2));
        // 判断是否闰年
        System.out.println("2024是闰年吗: " + date1.isLeapYear());
        // 检查日期有效性
        System.out.println("2月29日是否有效: " + Year.isLeap(2024));
    }
}

日期时间间隔

public class DurationPeriodDemo {
    public static void main(String[] args) {
        // Period: 日期之间的间隔(年、月、日)
        LocalDate startDate = LocalDate.of(2023, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 3, 15);
        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());
        // Duration: 时间之间的间隔(小时、分钟、秒)
        LocalTime startTime = LocalTime.of(10, 30, 0);
        LocalTime endTime = LocalTime.of(14, 45, 30);
        Duration duration = Duration.between(startTime, endTime);
        System.out.println("时间间隔: " + duration);
        System.out.println("间隔小时: " + duration.toHours());
        System.out.println("间隔分钟: " + duration.toMinutes());
        System.out.println("间隔秒: " + duration.getSeconds());
        // 使用ChronoUnit计算
        LocalDateTime startDateTime = LocalDateTime.of(2024, 3, 1, 10, 30);
        LocalDateTime endDateTime = LocalDateTime.of(2024, 3, 15, 14, 45);
        long daysBetween = ChronoUnit.DAYS.between(startDateTime, endDateTime);
        long hoursBetween = ChronoUnit.HOURS.between(startDateTime, endDateTime);
        long minutesBetween = ChronoUnit.MINUTES.between(startDateTime, endDateTime);
        System.out.println("日期时间间隔天数: " + daysBetween);
        System.out.println("日期时间间隔小时: " + hoursBetween);
        System.out.println("日期时间间隔分钟: " + minutesBetween);
        // 创建指定的Period和Duration
        Period customPeriod = Period.of(2, 3, 5); // 2年3月5天
        Duration customDuration = Duration.ofHours(24).plusMinutes(30); // 24小时30分钟
        System.out.println("自定义间隔: " + customPeriod + " 和 " + customDuration);
    }
}

格式化和解析

public class DateTimeFormatDemo {
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.now();
        // 内置格式
        System.out.println("ISO日期: " + dateTime.format(DateTimeFormatter.ISO_DATE));
        System.out.println("ISO日期时间: " + dateTime.format(DateTimeFormatter.ISO_DATE_TIME));
        System.out.println("BASIC_ISO日期: " + dateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
        // 自定义格式
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        System.out.println("自定义格式: " + dateTime.format(customFormatter));
        // 多种格式模式
        String[] patterns = {
            "yyyy-MM-dd",
            "yyyy/MM/dd",
            "dd-MM-yyyy",
            "MMM dd, yyyy",
            "EEEE, MMM dd yyyy HH:mm:ss",
            "yyyy年MM月dd日 EEEE HH时mm分ss秒"
        };
        for (String pattern : patterns) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            System.out.println(pattern + " => " + dateTime.format(formatter));
        }
        // 解析字符串
        DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        LocalDate parsedDate = LocalDate.parse("2024/03/15", parseFormatter);
        System.out.println("解析结果: " + parsedDate);
        // 使用Locale
        DateTimeFormatter localeFormatter = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy", Locale.US);
        System.out.println("美国格式: " + dateTime.format(localeFormatter));
        // 使用DateTimeFormatterBuilder
        DateTimeFormatter complexFormatter = new DateTimeFormatterBuilder()
            .appendPattern("yyyy-MM-dd")
            .appendLiteral(" at ")
            .appendPattern("HH:mm")
            .toFormatter();
        System.out.println("复杂格式: " + dateTime.format(complexFormatter));
    }
}

时区处理

public class ZoneHandleDemo {
    public static void main(String[] args) {
        // 所有时区
        Set<String> allZones = ZoneId.getAvailableZoneIds();
        System.out.println("可用时区数量: " + allZones.size());
        // 常用时区
        String[] commonZones = {"Asia/Shanghai", "Asia/Tokyo", "America/New_York", "Europe/London"};
        // 显示不同时区的时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("本地时间: " + now);
        for (String zoneId : commonZones) {
            ZonedDateTime zonedDateTime = now.atZone(ZoneId.of(zoneId));
            System.out.println(zoneId + ": " + zonedDateTime);
        }
        // 时区转换
        ZonedDateTime shanghaiTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime tokyoTime = shanghaiTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
        ZonedDateTime newYorkTime = shanghaiTime.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("\n上海时间: " + shanghaiTime);
        System.out.println("东京时间: " + tokyoTime);
        System.out.println("纽约时间: " + newYorkTime);
        // 与UTC的偏移量
        ZoneOffset offset = ZoneOffset.of("+08:00");
        OffsetDateTime offsetTime = OffsetDateTime.now(offset);
        System.out.println("带偏移时间: " + offsetTime);
        // 使用ZoneOffset计算
        LocalDateTime baseTime = LocalDateTime.of(2024, 3, 15, 12, 0);
        ZonedDateTime utcTime = baseTime.atZone(ZoneOffset.UTC);
        ZonedDateTime cstTime = utcTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
        System.out.println("UTC时间: " + utcTime);
        System.out.println("中国时间: " + cstTime);
    }
}

日期时间工具类

public class DateTimeUtilsDemo {
    public static void main(String[] args) {
        // 获取日期各部分
        LocalDateTime now = LocalDateTime.now();
        System.out.println("年: " + now.getYear());
        System.out.println("月: " + now.getMonthValue());
        System.out.println("日: " + now.getDayOfMonth());
        System.out.println("小时: " + now.getHour());
        System.out.println("分钟: " + now.getMinute());
        System.out.println("秒: " + now.getSecond());
        // 获取星期和月份名称
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        Month month = now.getMonth();
        System.out.println("星期: " + dayOfWeek);
        System.out.println("月份: " + month);
        System.out.println("今天是星期几: " + dayOfWeek.getValue()); // 1-7
        // 日期调整器
        LocalDate date = LocalDate.of(2024, 3, 15);
        // 当月最后一天
        LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
        // 下个月第一天
        LocalDate firstDayOfNextMonth = date.with(TemporalAdjusters.firstDayOfNextMonth());
        // 当月第一个星期一
        LocalDate firstMonday = date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        // 这个月的第二个星期日
        LocalDate secondSunday = date.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SUNDAY));
        System.out.println("当月最后一天: " + lastDayOfMonth);
        System.out.println("下月第一天: " + firstDayOfNextMonth);
        System.out.println("当月第一个周一: " + firstMonday);
        System.out.println("当月第二个周日: " + secondSunday);
    }
}

综合案例:日期时间处理工具

public class DateTimeUtility {
    // 1. 计算年龄
    public static int calculateAge(LocalDate birthDate) {
        return Period.between(birthDate, LocalDate.now()).getYears();
    }
    // 2. 格式化日期
    public static String formatDate(LocalDate date, String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }
    // 3. 获取日期所在季度
    public static int getQuarter(LocalDate date) {
        return (date.getMonthValue() - 1) / 3 + 1;
    }
    // 4. 判断是否工作日
    public static boolean isWorkingDay(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        return day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY;
    }
    // 5. 获取两个日期之间所有日期
    public static List<LocalDate> getDatesBetween(LocalDate start, LocalDate end) {
        return Stream.iterate(start, date -> date.plusDays(1))
                .limit(ChronoUnit.DAYS.between(start, end) + 1)
                .collect(Collectors.toList());
    }
    // 6. 日期时间转时间戳并返回
    public static long toTimestamp(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    // 7. 时间戳转日期时间
    public static LocalDateTime fromTimestamp(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
    }
    public static void main(String[] args) {
        // 测试各种方法
        LocalDate birthDate = LocalDate.of(1990, 5, 15);
        System.out.println("年龄: " + calculateAge(birthDate));
        LocalDate today = LocalDate.now();
        System.out.println("格式化日期: " + formatDate(today, "yyyy年MM月dd日"));
        System.out.println("所在季度: " + getQuarter(today) + "季度");
        System.out.println("是否工作日: " + (isWorkingDay(today) ? "是" : "否"));
        // 获取本周的日期
        LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDate sunday = monday.plusDays(6);
        List<LocalDate> weekDates = getDatesBetween(monday, sunday);
        System.out.println("本周日期: " + weekDates);
        // 时间戳转换
        long timestamp = toTimestamp(LocalDateTime.now());
        System.out.println("时间戳: " + timestamp);
        System.out.println("还原时间: " + fromTimestamp(timestamp));
    }
}

实际应用案例

public class RealWorldApplications {
    public static void main(String[] args) {
        // 场景1:会议安排
        LocalDateTime meetingStart = LocalDateTime.of(2024, 3, 15, 10, 0);
        LocalDateTime meetingEnd = meetingStart.plusHours(2).plusMinutes(30);
        Duration meetingDuration = Duration.between(meetingStart, meetingEnd);
        System.out.println("会议时长: " + meetingDuration.toMinutes() + "分钟");
        // 场景2:订单超时处理
        LocalDateTime orderTime = LocalDateTime.now().minusMinutes(30);
        Duration timeout = Duration.between(orderTime, LocalDateTime.now());
        boolean isExpired = timeout.toMinutes() > 30;
        System.out.println("订单是否超时: " + (isExpired ? "已超时" : "未超时"));
        // 场景3:日历事件
        LocalDate today = LocalDate.now();
        LocalDate eventDate = today.plusDays(7);
        boolean isUpcoming = eventDate.isAfter(today) && eventDate.isBefore(today.plusWeeks(2));
        System.out.println("事件是否在两周内: " + isUpcoming);
        // 场景4:生日提醒
        LocalDate personBirthday = LocalDate.of(1990, 3, 15);
        LocalDate nextBirthday = personBirthday.withYear(today.getYear());
        if (nextBirthday.isBefore(today)) {
            nextBirthday = nextBirthday.plusYears(1);
        }
        long daysUntilBirthday = ChronoUnit.DAYS.between(today, nextBirthday);
        System.out.println("距离生日还有: " + daysUntilBirthday + "天");
        // 场景5:日志时间处理
        LocalDateTime logTime = LocalDateTime.now();
        String logTimestamp = logTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println("日志时间戳: " + logTimestamp);
        // 场景6:时间范围判断
        LocalTime now = LocalTime.now();
        LocalTime startWork = LocalTime.of(9, 0);
        LocalTime endWork = LocalTime.of(18, 0);
        boolean isWorking = !now.isBefore(startWork) && !now.isAfter(endWork);
        System.out.println("是否在工作时间: " + (isWorking ? "是" : "否"));
    }
}

Java 8时间API的优势:

  1. 不可变性:所有类都是不可变的,线程安全
  2. 清晰的方法名:如 plusDays(), minusMonths(), withYear()
  3. 丰富的格式化选项:支持自定义模式和本地化
  4. 完整的时区支持:可以轻松处理不同时区的转换
  5. 精确的时间计算:支持纳秒级别的精度
  6. 与旧API的兼容:提供了 toInstant() 等方法转换

这些API使得Java中的日期时间处理变得简单、清晰且不易出错。

抱歉,评论功能暂时关闭!