哪些Java案例展示了时间处理?

wen java案例 239

本文目录导读:

哪些Java案例展示了时间处理?

  1. 核心案例:新旧 API 对比与基础操作
  2. 时间计算与操作
  3. 时区处理
  4. 与数据库/系统交互
  5. 实际业务案例:日历与时间范围
  6. 常见陷阱与注意事项

Java 中时间处理的案例非常丰富,涵盖了从早期的 java.util.Date、Calendar 到现代的 java.time(JSR-310)包,现代 Java 开发强烈推荐使用 java.time 包,因为它解决了旧 API 的线程安全、设计混乱等问题。

以下是一些典型的 Java 时间处理案例,按功能分类展示:


核心案例:新旧 API 对比与基础操作

场景:获取当前时间、格式化、解析。

旧 API(不推荐):

// 1. 获取当前时间
Date now = new Date();
System.out.println(now); // 输出:Tue Oct 24 10:30:00 CST 2023
// 2. 格式化(线程不安全)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(now);
System.out.println(formatted); // 输出:2023-10-24 10:30:00
// 3. 解析
String dateStr = "2023-10-24 10:30:00";
try {
    Date parsed = sdf.parse(dateStr);
} catch (ParseException e) {
    e.printStackTrace();
}

新 API(推荐):

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 1. 获取当前时间(不可变、线程安全)
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 输出:2023-10-24T10:30:00
// 2. 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(formatter);
System.out.println(formatted); // 输出:2023-10-24 10:30:00
// 3. 解析
String dateStr = "2023-10-24 10:30:00";
LocalDateTime parsed = LocalDateTime.parse(dateStr, formatter);

关键点:新 API 的 LocalDate、LocalTime、LocalDateTime 是不可变对象,所有操作返回新实例,天然线程安全。


时间计算与操作

场景:加减天数、月份,获取前后日期,计算两个时间的差值。

import java.time.LocalDate;
import java.time.Period;
import java.time.Duration;
import java.time.LocalDateTime;
public class TimeCalculationExample {
    public static void main(String[] args) {
        // 1. 日期加减
        LocalDate today = LocalDate.now();
        LocalDate nextWeek = today.plusDays(7);
        LocalDate lastMonth = today.minusMonths(1);
        LocalDate nextYear = today.plusYears(1);
        System.out.println(" " + today);
        System.out.println("一周后: " + nextWeek);
        // 2. 计算两个日期之间的天数差
        LocalDate start = LocalDate.of(2023, 1, 1);
        LocalDate end = LocalDate.of(2023, 12, 31);
        Period period = Period.between(start, end);
        System.out.println("间隔: " + period.getYears() + "年, " 
                           + period.getMonths() + "月, " 
                           + period.getDays() + "天");
        // 3. 计算两个时间之间的精确秒/毫秒差
        LocalDateTime time1 = LocalDateTime.of(2023, 10, 24, 10, 0, 0);
        LocalDateTime time2 = LocalDateTime.of(2023, 10, 24, 12, 30, 0);
        Duration duration = Duration.between(time1, time2);
        System.out.println("时间差: " + duration.toHours() + "小时, " 
                           + duration.toMinutes() + "分钟");
    }
}

关键点:Period 适用于日期(年月日),Duration 适用于时间(时分秒纳秒)。


时区处理

场景:不同时区的时间转换、获取时区时间。

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class TimeZoneExample {
    public static void main(String[] args) {
        // 1. 获取当前时区时间(系统默认时区)
        ZonedDateTime nowInLocal = ZonedDateTime.now();
        System.out.println("本地时区: " + nowInLocal);
        // 2. 获取指定时区时间
        ZoneId tokyoZone = ZoneId.of("Asia/Tokyo");
        ZonedDateTime nowInTokyo = ZonedDateTime.now(tokyoZone);
        System.out.println("东京时间: " + nowInTokyo);
        // 3. 时区转换(从北京时间转为纽约时间)
        ZoneId beijingZone = ZoneId.of("Asia/Shanghai");
        ZoneId newYorkZone = ZoneId.of("America/New_York");
        ZonedDateTime beijingTime = ZonedDateTime.of(
            LocalDateTime.now(), beijingZone
        );
        ZonedDateTime newYorkTime = beijingTime.withZoneSameInstant(newYorkZone);
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV");
        System.out.println("北京: " + beijingTime.format(format));
        System.out.println("纽约: " + newYorkTime.format(format));
    }
}

关键点:ZonedDateTime 用于带时区的日期时间,ZoneId 用于标识时区,withZoneSameInstant 用于在不同时区间转换。


与数据库/系统交互

场景:与数据库中的 TIMESTAMP、DATE 类型互转,与旧 java.util.Date 互转。

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
public class InteropExample {
    public static void main(String[] args) {
        // 1. LocalDateTime 转 java.util.Date
        LocalDateTime localDateTime = LocalDateTime.now();
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        Date date = Date.from(instant);
        System.out.println("LocalDateTime -> Date: " + date);
        // 2. java.util.Date 转 LocalDateTime
        Date legacyDate = new Date();
        Instant legacyInstant = legacyDate.toInstant();
        LocalDateTime localFromLegacy = LocalDateTime.ofInstant(
            legacyInstant, ZoneId.systemDefault()
        );
        System.out.println("Date -> LocalDateTime: " + localFromLegacy);
        // 3. 与数据库交互 (JDBC 4.2+)
        // 数据库插入: preparedStatement.setObject(1, LocalDate.now());
        // 数据库读取: LocalDate date = resultSet.getObject("column", LocalDate.class);
        System.out.println("Java 8+ JDBC 直接支持 LocalDate/LocalDateTime");
    }
}

关键点:

  • Java 8+ 的 JDBC 驱动直接支持 LocalDate、LocalTime、LocalDateTime 类型。
  • Instant 是一个时间线上的瞬时点,可用于与旧 API 互转。

实际业务案例:日历与时间范围

场景:计算某个月有多少天、判断闰年、获取工作日等。

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
public class CalendarExample {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        // 1. 当月第一天和最后一天
        LocalDate firstDay = today.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("当月第一天: " + firstDay + ", 最后一天: " + lastDay);
        // 2. 下个周五
        LocalDate nextFriday = today.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        System.out.println("下周五: " + nextFriday);
        // 3. 判断闰年
        boolean isLeap = today.isLeapYear();
        System.out.println(today.getYear() + " 是闰年吗? " + isLeap);
        // 4. 获取当月天数
        int daysInMonth = today.lengthOfMonth();
        System.out.println("本月有 " + daysInMonth + " 天");
    }
}

关键点:TemporalAdjusters 类提供了丰富的日期调整器,如 firstDayOfMonth()、next(DayOfWeek) 等。


常见陷阱与注意事项

案例:线程安全问题(旧 API 失败案例)

// 错误做法(多线程环境下)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 多个线程同时调用 parse() 会抛出异常或产生错误结果
// 正确做法
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// DateTimeFormatter 是线程安全的

案例:时间精度问题

// java.util.Date 的精度是毫秒
// LocalDateTime 的精度是纳秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now.getNano()); // 输出纳秒部分,如 123456789

功能分类 推荐使用类 旧类(不推荐) 主要优势
日期(无时间) LocalDate java.sql.Date 清晰、不可变
时间(无日期) LocalTime java.sql.Time 清晰、不可变
日期+时间 LocalDateTime java.util.Date 不可变、线程安全
带时区 ZonedDateTime Calendar、TimeZone 更语义化、易用
格式化解析 DateTimeFormatter SimpleDateFormat 线程安全、不可变

推荐学习路径:

  1. 掌握 LocalDate、LocalTime、LocalDateTime 的创建与基础运算。
  2. 学会使用 DateTimeFormatter 进行格式化。
  3. 理解时区概念,使用 ZonedDateTime 处理跨时区问题。
  4. 熟悉 Period 和 Duration 做时间差值计算。
  5. 了解与数据库和旧系统的互转方式。

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝