1. 概述

本文将介绍在 Java 中如何从一个日期对象中提取年(Year)、月(Month)和日(Day)的整数值

我们会覆盖三种主流方式:

  • 使用传统的 java.util.DateCalendar
  • 处理 java.sql.Timestamp
  • 使用 Java 8 引入的现代日期时间 API(java.time

⚠️ 为什么要用新 API?因为老的 DateCalendar 设计存在诸多问题:线程不安全、API 设计混乱、月份从 0 开始等。Java 8 的 java.time 包解决了这些问题,代码更清晰、更安全。

如果你还没用过 Java 8 的时间类,建议先看这篇入门文章:Java 8 日期时间 API 简介

本文所有示例代码已上传至 GitHub:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-date-operations-1


2. 使用 LocalDate(推荐方式)

LocalDate 是 Java 8 java.time 包中最常用的日期类之一,仅表示日期(不含时间)

它提供了直观的方法直接获取年、月、日,无需中间转换,简单粗暴又安全

假设我们有一个 LocalDate 实例:

LocalDate localDate = LocalDate.of(2023, 10, 25);

2.1. 获取年份

直接调用 getYear()

int year = localDate.getYear(); // 返回 2023

2.2. 获取月份

使用 getMonthValue() 获取月份数值:

int month = localDate.getMonthValue(); // 返回 10(10月)

📌 注意:LocalDate 的月份从 1 开始计数,1 表示一月,12 表示十二月。这和人类直觉一致,避免踩坑。

❌ 对比老的 Calendar,它的月份是从 0 开始的,一月是 0,非常容易出错。

2.3. 获取日

使用 getDayOfMonth() 获取当月的第几天:

int day = localDate.getDayOfMonth(); // 返回 25

3. 使用 java.util.Date(旧方式,不推荐)

⚠️ Date 类本身没有提供直接获取年月日的方法,必须借助 Calendar 中转。

步骤:

  1. 创建 Calendar 实例
  2. Date 设置进去
  3. 调用 get() 方法提取字段

示例代码:

Date date = new Date(); // 当前时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

3.1. 获取年份

int year = calendar.get(Calendar.YEAR); // 返回 2023

3.2. 获取月份

int month = calendar.get(Calendar.MONTH); // 返回 9(注意!10月返回9)

📌 大坑警告:Calendar.MONTH 是从 0 开始的!

  • 一月 → 0
  • 十月 → 9
    这个设计反人类,极易导致 bug,务必小心。

3.3. 获取日

int day = calendar.get(Calendar.DAY_OF_MONTH); // 返回 25

✅ 建议:除非维护老系统,否则不要用这种方式。


4. 使用 java.sql.Timestamp

Timestamp 通常用于数据库操作,表示带纳秒精度的时间戳。

但它本身也不支持直接提取年月日,仍需通过 Calendar 中转

步骤:

  1. 创建 Calendar 实例
  2. Timestamp 设置进去
  3. 使用 get() 提取字段

示例代码:

Timestamp timestamp = new Timestamp(System.currentTimeMillis());
Calendar calendar = Calendar.getInstance();
calendar.setTime(timestamp);

之后提取方式与 Date 完全一致:

int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);        // 注意:仍是 0 起始
int day = calendar.get(Calendar.DAY_OF_MONTH);

⚠️ 虽然 Timestamp 继承自 Date,但其 getYear()getMonth() 等方法已被标记为 @Deprecated不要使用


5. 总结

方式 是否推荐 关键点
LocalDate 强烈推荐 月份从 1 开始,API 简洁,线程安全
Date + Calendar 不推荐 月份从 0 开始,易出错,API 冗长
⚠️ Timestamp + Calendar 仅限数据库场景 同上,注意弃用方法

📌 最佳实践建议:

  • 新项目一律使用 java.time 包(如 LocalDate
  • 老项目迁移时,优先替换 Date/Calendar 相关逻辑
  • 遇到 Timestamp,可先转为 InstantLocalDateTime,再提取字段,避免依赖 Calendar

完整代码示例见 GitHub:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-date-operations-1


原始标题:Extracting Year, Month and Day from Date in Java | Baeldung