Java 实例 – 获取年份、月份等(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在 Java 开发中,日期和时间的处理是一个高频需求,无论是记录用户注册时间、计算订单有效期,还是分析业务数据的时间趋势,都离不开对年份、月份等时间信息的获取与操作。对于编程初学者而言,Java 的时间处理 API 可能显得复杂;而对中级开发者来说,如何高效、安全地操作时间对象是持续优化的方向。本文将以 “Java 实例 – 获取年份、月份等” 为主题,通过对比旧版与新版 API 的差异、提供具体代码示例和常见问题解决方案,帮助读者系统掌握这一核心知识点。


一、Java 时间处理的两大阵营:旧 API 与新 API

Java 的时间处理 API 经历了两次重大迭代:

  1. 旧 API(Date/Calendar):诞生于 JDK 1.0,设计上存在线程不安全、方法命名混乱等问题,例如 Calendar.MONTH 从 0 开始计数(0 表示一月)。
  2. 新 API(java.time 包):随 JDK 8 引入,基于 ISO 8601 标准设计,提供不可变对象和清晰的命名规则,例如 LocalDategetYear() 直接返回年份。

形象比喻:旧 API 像一台老式机械钟表,需要手动调整齿轮才能读取时间;而新 API 则像智能手表,通过触摸屏即可直观获取年、月、日等信息。


二、核心知识点详解:如何获取年份、月份等信息

1. 使用新 API(推荐)

LocalDate 类 是处理日期(不含时间)的首选工具。以下代码演示如何获取当前年份和月份:

import java.time.LocalDate;  
import java.time.Month;  

public class DateExample {  
    public static void main(String[] args) {  
        LocalDate currentDate = LocalDate.now();  
        int year = currentDate.getYear();  // 获取年份  
        Month month = currentDate.getMonth();  // 获取月份枚举值  
        int monthValue = currentDate.getMonthValue();  // 获取月份数值(1-12)  

        System.out.println("当前年份:" + year);  
        System.out.println("当前月份(枚举):" + month);  
        System.out.println("当前月份数值:" + monthValue);  
    }  
}  

输出示例

当前年份:2023  
当前月份(枚举):JULY  
当前月份数值:7  

2. 使用旧 API(兼容场景)

尽管新 API 更推荐,但在兼容旧代码时仍需了解旧 API 的用法:

import java.util.Calendar;  
import java.util.Date;  

public class LegacyDateExample {  
    public static void main(String[] args) {  
        Calendar calendar = Calendar.getInstance();  
        Date currentDate = calendar.getTime();  
        int year = calendar.get(Calendar.YEAR);  
        int month = calendar.get(Calendar.MONTH) + 1;  // 注意:月份从 0 开始,需加 1  
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);  

        System.out.println("当前日期:" + currentDate);  
        System.out.println("年份:" + year);  
        System.out.println("月份:" + month);  
        System.out.println("日:" + dayOfMonth);  
    }  
}  

关键差异对比
| 特性 | 新 API(java.time) | 旧 API(Date/Calendar) |
|---------------------|-----------------------------|-----------------------------|
| 线程安全 | 是(不可变对象) | 否(可变对象) |
| 月份计数 | 1-12(getMonthValue()) | 0-11(需手动加 1) |
| 代码可读性 | 高(方法名直观) | 低(依赖常量如 Calendar.YEAR) |


三、进阶场景:时区与格式化

1. 处理时区差异

当需要获取特定时区的时间时,新 API 提供了 ZoneId 类:

import java.time.ZoneId;  
import java.time.ZonedDateTime;  

public class TimeZoneExample {  
    public static void main(String[] args) {  
        ZoneId zone = ZoneId.of("Asia/Shanghai");  
        ZonedDateTime shanghaiTime = ZonedDateTime.now(zone);  
        System.out.println("上海当前时间:" + shanghaiTime);  
    }  
}  

2. 自定义日期格式

使用 DateTimeFormatter 可以将日期对象格式化为字符串:

import java.time.format.DateTimeFormatter;  

public class FormatExample {  
    public static void main(String[] args) {  
        LocalDate date = LocalDate.of(2023, 7, 15);  
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");  
        String formattedDate = date.format(formatter);  
        System.out.println("格式化后的日期:" + formattedDate);  // 输出:2023年07月15日  
    }  
}  

四、常见问题与解决方案

1. 月份从 0 开始的问题(旧 API)

在旧 API 中,Calendar.MONTH 的值范围是 0(一月)到 11(十二月),因此需通过 +1 转换为实际月份:

int actualMonth = calendar.get(Calendar.MONTH) + 1;  

2. 跨时区计算日期差异

若需计算两个不同时区的日期差异,可使用 ZonedDateTimeChronoUnit

import java.time.temporal.ChronoUnit;  

public class TimeDifferenceExample {  
    public static void main(String[] args) {  
        ZonedDateTime newYork = ZonedDateTime.now(ZoneId.of("America/New_York"));  
        ZonedDateTime tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));  
        long hoursDifference = ChronoUnit.HOURS.between(newYork, tokyo);  
        System.out.println("纽约与东京时差:" + hoursDifference + " 小时");  
    }  
}  

3. 处理日期边界条件(如闰年)

新 API 内置了闰年判断功能:

LocalDate date = LocalDate.of(2024, 2, 29);  
boolean isLeapYear = date.isLeapYear();  // 返回 true  

五、实战案例:计算用户年龄

需求:根据用户出生日期,计算当前年龄。

实现步骤

  1. 使用 LocalDate.now() 获取当前日期;
  2. 通过 Period.between() 计算两个日期之间的年份差。
import java.time.LocalDate;  
import java.time.Period;  

public class AgeCalculator {  
    public static void main(String[] args) {  
        LocalDate birthDate = LocalDate.of(1990, 5, 15);  
        LocalDate currentDate = LocalDate.now();  
        Period age = Period.between(birthDate, currentDate);  
        System.out.println("用户年龄:" + age.getYears() + " 岁");  
    }  
}  

六、总结与建议

通过本文的讲解,读者可以掌握以下核心能力:

  1. 区分新旧 API 的优劣:优先使用 java.time 包,避免旧 API 的线程安全问题;
  2. 灵活获取时间信息:通过 LocalDateLocalTimeLocalDateTime 精准操作日期、时间及组合数据;
  3. 处理复杂场景:时区转换、日期格式化、年龄计算等均可以通过新 API 的简洁方法实现。

推荐阅读

  • 若需深入学习时间 API,可查阅官方文档或《Java 8实战》相关章节;
  • 对旧代码改造时,可使用 java.time包Instant 类与 Date 进行互操作。

通过持续练习和代码实践,开发者可以快速提升对时间处理逻辑的理解,为构建高质量的 Java 应用打下坚实基础。

最新发布