Java案例怎么处理日期时间?

wen java案例 11

本文目录导读:

Java案例怎么处理日期时间?

  1. 核心方案:java.time 包 (Java 8+)
  2. 旧版方案(谨慎使用,仅维护旧代码)
  3. 常见问题与最佳实践

在Java中处理日期和时间,根据你使用的Java版本,主要有三套方案。强烈建议新项目使用 java.time 包(Java 8+),因为它设计更优秀、线程安全且操作方便。

以下是完整的处理指南和实战案例。

核心方案:java.time 包 (Java 8+)

这是现代Java处理日期时间的标准方式,包含以下核心类:

  • LocalDate:只包含日期(年月日)
  • LocalTime:只包含时间(时分秒纳秒)
  • LocalDateTime:包含日期和时间(不含时区)
  • ZonedDateTime:包含日期、时间和时区
  • Instant:时间戳(机器时间,从1970-01-01T00:00:00Z开始)
  • DateTimeFormatter:格式化和解析

案例1:获取当前日期、时间、时间戳

import java.time.*;
import java.time.format.DateTimeFormatter;
public class DateDemo {
    public static void main(String[] args) {
        // 当前日期(2024-01-15)
        LocalDate today = LocalDate.now();
        System.out.println("当前日期: " + today); // 2024-01-15
        // 当前时间(14:30:25.123)
        LocalTime nowTime = LocalTime.now();
        System.out.println("当前时间: " + nowTime); // 14:30:25.123
        // 当前日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前日期时间: " + now); // 2024-01-15T14:30:25.123
        // 时间戳(适合跨时区使用)
        Instant instant = Instant.now();
        System.out.println("当前时间戳: " + instant); // 2024-01-15T06:30:25.123Z
        // 带时区的日期时间
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println("上海时间: " + zdt); // 2024-01-15T14:30:25.123+08:00[Asia/Shanghai]
    }
}

案例2:字符串与日期互转(格式化/解析)

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class FormatDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 日期 -> 字符串
        LocalDateTime now = LocalDateTime.now();
        String formatted = now.format(formatter);
        System.out.println("格式化后: " + formatted); // 2024-01-15 14:30:25
        // 字符串 -> 日期
        String dateStr = "2024-12-25 10:30:00";
        LocalDateTime parsed = LocalDateTime.parse(dateStr, formatter);
        System.out.println("解析后: " + parsed); // 2024-12-25T10:30
        // 常用格式化符号:
        // yyyy: 年, MM: 月, dd: 日
        // HH: 24小时制, hh: 12小时制, mm: 分, ss: 秒
        // E: 星期几, a: 上午/下午
    }
}

案例3:日期加减、比较、计算差值

import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class DateCalcDemo {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now(); // 2024-01-15
        // 加10天
        LocalDate tenDaysLater = today.plusDays(10);
        System.out.println("10天后: " + tenDaysLater); // 2024-01-25
        // 减3个月
        LocalDate threeMonthsAgo = today.minusMonths(3);
        System.out.println("3月前: " + threeMonthsAgo); // 2023-10-15
        // 计算两个日期之间的天数差
        LocalDate start = LocalDate.of(2024, 1, 1);
        LocalDate end = LocalDate.of(2024, 1, 15);
        long daysBetween = ChronoUnit.DAYS.between(start, end);
        System.out.println("相差天数: " + daysBetween); // 14
        // 计算两个日期之间的年月日差 (Period)
        Period period = Period.between(start, end);
        System.out.println("相差: " + period.getDays() + "天"); // 14天
        // 比较日期:isAfter, isBefore, isEqual
        LocalDate date1 = LocalDate.of(2024, 6, 1);
        LocalDate date2 = LocalDate.of(2024, 6, 15);
        System.out.println("date1在date2之前? " + date1.isBefore(date2)); // true
    }
}

案例4:获取某月的第一天、最后一天、星期几

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
public class DateAdjustDemo {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now(); // 2024-01-15
        // 本月的第一天
        LocalDate firstDay = today.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println("本月第一天: " + firstDay); // 2024-01-01
        // 本月的最后一天
        LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("本月最后一天: " + lastDay); // 2024-01-31
        // 下一个周一
        LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        System.out.println("下一个周一: " + nextMonday);
        // 当前日期是星期几
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        System.out.println("今天是星期: " + dayOfWeek); // MONDAY
        System.out.println("星期几数字: " + dayOfWeek.getValue()); // 1 (周一=1, 周日=7)
    }
}

案例5:时区转换

import java.time.*;
public class TimeZoneDemo {
    public static void main(String[] args) {
        // 将北京时间转换为纽约时间
        ZonedDateTime shanghaiTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println("上海: " + shanghaiTime);
        // 转换为纽约时间
        ZonedDateTime newYorkTime = shanghaiTime.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("纽约: " + newYorkTime);
        // 跨时区的时间差
        Instant instant = Instant.now(); // UTC时间
        System.out.println("UTC: " + instant);
    }
}

旧版方案(谨慎使用,仅维护旧代码)

如果你还在维护Java 7或更早的代码,会用到 java.util.Datejava.util.Calendar但请注意:它们可变、线程不安全,设计混乱。

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class OldDateDemo {
    public static void main(String[] args) throws Exception {
        // 获取当前时间
        Date now = new Date();
        System.out.println("当前时间: " + now); // Thu Jan 15 14:30:25 CST 2024
        // 格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formatted = sdf.format(now);
        System.out.println("格式化: " + formatted);
        // 字符串转日期
        Date parsed = sdf.parse("2024-12-25 10:30:00");
        System.out.println("解析: " + parsed);
        // 日期加减 (使用Calendar)
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        cal.add(Calendar.DAY_OF_MONTH, 10); // 加10天
        Date futureDate = cal.getTime();
        System.out.println("10天后: " + sdf.format(futureDate));
    }
}

常见问题与最佳实践

  1. 项目中使用哪个版本?

    • Java 8+:只用 java.time 包(JSR 310)。
    • Java 6/7:引入 ThreeTen-Backport 库(几乎和 java.time API一致)。
  2. 前端传字符串,后端如何处理?

    • 使用 @DateTimeFormat + @JsonFormat 注解(Spring框架)或自定义反序列化器。
    • 接收格式建议统一为 yyyy-MM-dd / yyyy-MM-dd'T'HH:mm:ss (ISO 8601标准)。
  3. 存储到数据库(MySQL为例)

    • 字段类型:DATE -> LocalDateDATETIME / TIMESTAMP -> LocalDateTime
    • 建议统一使用 TIMESTAMP 并设置 time_zone='+00:00' 存储UTC时间,应用层转为本地时区。
  4. 线程安全问题

    • SimpleDateFormat 是线程不安全的,不要定义为 static 全局变量。DateTimeFormatter 是线程安全的,可以放心使用。
  5. 性能问题

    • java.timeInstantDate 更精确(纳秒级)。
    • 频繁格式化时,将 DateTimeFormatter.ofPattern("...") 提取为 static final 常量。
需求 Java 8+ 方案 旧方案(不推荐)
获取当前时间 LocalDateTime.now() new Date()
格式化 DateTimeFormatter SimpleDateFormat(线程不安全)
日期加减 .plusDays(), .minusMonths() Calendar.add()
计算差值 ChronoUnit.between(), Period 手动计算毫秒差
时区处理 ZonedDateTime, ZoneId TimeZone, Calendar
时间戳 Instant.now() System.currentTimeMillis()

建议:除非必须维护遗留系统,否则直接拥抱 java.time

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