日期处理是Java开发中的基础需求,无论是日志记录、业务逻辑处理还是数据存储,获取当前日期都是常见操作,Java在不同版本中提供了多种日期时间API,从早期的Date和Calendar到Java 8引入的java.time包,功能不断完善,使用体验也逐步优化,本文将系统介绍Java中获取当前日期的方法,涵盖不同版本的特点及实际应用场景。

Java 8之前的日期获取方式
在Java 8之前,获取当前日期主要依赖java.util.Date和java.util.Calendar两个类,但它们存在设计缺陷,使用时需注意细节。
使用Date类
Date类是最基础的日期时间表示,直接通过new Date()即可获取当前日期时间(包含年、月、日、时、分、秒、毫秒),但需要注意:
Date的月份是从0开始计数的(0代表1月),获取月份时需手动加1。- 其
toString()方法返回的字符串格式固定,但Date本身不包含时区信息,默认使用JVM默认时区。
示例代码:
Date now = new Date();
int year = now.getYear() + 1900; // 年份需加1900
int month = now.getMonth() + 1; // 月份需加1
int day = now.getDate();
System.out.println("当前日期:" + year + "-" + month + "-" + day);
使用Calendar类
Calendar类是对Date的改进,提供了更灵活的日期操作,但使用相对繁琐,通过Calendar.getInstance()获取实例后,可通过get()方法指定字段获取日期信息。
示例代码:
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // 月份仍需加1
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println("当前日期:" + year + "-" + month + "-" + day);
缺点:Date和Calendar均为可变类,线程不安全;API设计不够直观(如月份从0计数),且部分方法已标记过时(如Date的构造方法)。
Java 8及以上:java.time包的日期获取方式
Java 8引入了全新的java.time包,彻底解决了旧API的痛点,提供了不可变、线程安全且API直观的日期时间类,获取当前日期的核心类包括LocalDate、LocalDateTime和ZonedDateTime。
LocalDate:仅表示日期
LocalDate不包含时间信息,适用于仅需要日期的场景(如生日、纪念日),通过LocalDate.now()可直接获取当前日期(默认JVM时区),或指定时区获取特定区域的日期。

示例代码:
// 获取当前日期(默认时区)
LocalDate today = LocalDate.now();
System.out.println("当前日期:" + today); // 格式:2026-10-01
// 指定时区获取日期
LocalDate todayShanghai = LocalDate.now(ZoneId.of("Asia/Shanghai"));
System.out.println("上海当前日期:" + todayShanghai);
LocalDateTime:包含日期和时间
LocalDateTime是LocalDate和LocalTime的组合,表示日期和时间(不含时区),适用于大多数业务场景,通过LocalDateTime.now()获取当前日期时间。
示例代码:
LocalDateTime now = LocalDateTime.now();
System.out.println("当前日期时间:" + now); // 格式:2026-10-01T15:30:45.123
ZonedDateTime:带时区的日期时间
若需处理跨时区业务(如全球用户下单时间),可使用ZonedDateTime,它包含日期、时间和时区信息,通过ZonedDateTime.now(ZoneId)获取指定时区的当前日期时间。
示例代码:
ZonedDateTime nowNewYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println("纽约当前日期时间:" + nowNewYork);
时区处理:ZoneId与ZoneOffset
时区是日期时间处理中的关键概念,尤其在全球化应用中必不可少。java.time通过ZoneId和ZoneOffset管理时区:
ZoneId:表示时区ID(如”Asia/Shanghai”、”UTC”),通过ZoneId.of()获取。ZoneOffset:表示时区偏移量(如UTC+8),适用于简单时区场景。
示例:将LocalDateTime转换为指定时区的ZonedDateTime
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Europe/London"));
System.out.println("伦敦时间:" + zonedDateTime);
日期格式化与解析:DateTimeFormatter
获取日期后,常需将其格式化为字符串或解析字符串为日期。DateTimeFormatter是Java 8提供的格式化工具,支持预定义格式(如ISO_LOCAL_DATE)和自定义格式(如yyyy-MM-dd)。

格式化日期为字符串
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = today.format(formatter);
System.out.println("格式化日期:" + formattedDate); // 输出:2026年10月01日
解析字符串为日期
String dateStr = "2026-10-01";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate parsedDate = LocalDate.parse(dateStr, parser);
System.out.println("解析后的日期:" + parsedDate);
注意:自定义格式需与字符串格式严格匹配,否则会抛出DateTimeParseException。
常见问题与解决方案
Date与LocalDate的转换
旧代码可能仍使用Date,需与LocalDate互转:
// Date转LocalDate Date date = new Date(); LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); // LocalDate转Date Date convertedDate = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
日期加减计算
java.time提供了丰富的日期计算方法,如plusDays()、minusMonths()等:
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("明天:" + tomorrow);
System.out.println("上月:" + lastMonth);
获取特定日期(如月初、月末)
使用TemporalAdjusters工具类可快速获取特定日期:
LocalDate today = LocalDate.now();
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("本月第一天:" + firstDayOfMonth);
System.out.println("本月最后一天:" + lastDayOfMonth);
Java中获取当前日期的方法随版本迭代不断优化:Java 8之前的Date和Calendar功能有限且存在缺陷,而Java 8及以上的java.time包提供了不可变、线程安全且API直观的LocalDate、LocalDateTime等类,配合DateTimeFormatter和ZoneId,可灵活处理日期格式化、时区转换等复杂场景,在实际开发中,推荐优先使用java.time包中的API,以提升代码的可读性和健壮性。











