Java中月份设置主要基于java.time包(推荐)和遗留的java.util.Calendar,在java.time中,Month类枚举了12个月份(JANUARY至DECEMBER,对应1-12),可通过LocalDate的withMonth()方法设置月份,如LocalDate.now().withMonth(Month.FEBRUARY.getValue()),若使用字符串解析,需结合DateTimeFormatter,用“M”(数字)、“MMM”(英文缩写)等模式匹配月份,注意Calendar类(已过时)月份从0开始,而java.time从1开始,避免混淆,实际开发中优先使用java.time,确保日期操作准确且线程安全。
Java月份设置实用指南:从基础到进阶
在Java开发中,日期时间处理是一项常见且重要的需求,作为日期的核心组成部分,月份的设置与操作涉及多个关键类和方法,无论是业务逻辑中的月份计算、格式化输出,还是日期有效性校验,掌握Java月份设置的方法都能显著提升开发效率,本文将从基础到进阶,全面介绍Java中月份设置的核心知识点,帮助开发者应对各种实际场景需求。
基础篇:Java月份相关的核心类
Java处理日期时间的类主要分为两代:早期java.util.Calendar(已不推荐)和Java 8引入的java.time包(官方推荐),我们先从基础类入手,理解月份的表示与设置方法。
旧版:java.util.Calendar中的月份设置
Calendar是Java早期提供的日期时间类,其月份采用从0开始计数的方式(0代表1月,11代表12月),虽然已被java.time取代,但在部分旧项目中仍可能遇到,需了解其基本用法:
import java.util.Calendar;
public class CalendarMonthExample {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
// 设置月份为5月(注意:实际传入4,因为从0开始)
calendar.set(Calendar.MONTH, 4); // 5月
// 获取设置的月份(返回的是0-11的数字)
int month = calendar.get(Calendar.MONTH);
System.out.println("当前月份(0-11):" + month); // 输出4
// 获取月份的英文名称(需自行处理)
String[] months = {"January", "February", "March", "April", "May",
"June", "July", "August", "September", "October",
"November", "December"};
System.out.println("月份名称:" + months[month]); // 输出May
// 其他常用操作
calendar.add(Calendar.MONTH, 1); // 月份加1
System.out.println("下个月份:" + calendar.get(Calendar.MONTH)); // 输出5(6月)
}
}
注意事项:
Calendar的月份计数方式容易出错(0开始),且线程不安全- 新项目应避免使用,推荐使用Java 8+的
java.time包 Calendar设计存在诸多问题,如月份、星期等字段从0开始计数,与日常认知不符
新版:java.time包中的月份设置
Java 8引入的java.time包是官方推荐的日期时间API,具有线程安全、设计直观、不可变等优点,月份通过Month枚举表示(JANUARY到DECEMBER),避免了Calendar的计数混淆,核心类包括:
LocalDate:表示仅包含日期(年、月、日)的对象,不可变YearMonth:表示仅包含年、月的对象,适合处理"月份"相关的业务(如月度统计)Month:枚举类,定义了12个月份常量(如Month.JANUARY)
(1)LocalDate中的月份设置
LocalDate通过withMonth()方法设置月份,参数为Month枚举或数字(1-12):
import java.time.LocalDate;
import java.time.Month;
public class LocalDateMonthExample {
public static void main(String[] args) {
LocalDate date = LocalDate.now(); // 当前日期,如2023-10-15
// 方式1:使用Month枚举(推荐,避免数字混淆)
LocalDate dateWithMay = date.withMonth(Month.MAY);
System.out.println("设置为5月后的日期:" + dateWithMay); // 输出2023-05-15
// 方式2:使用数字(1-12,1代表1月)
LocalDate dateWithJune = date.withMonth(6);
System.out.println("设置为6月后的日期:" + dateWithJune); // 输出2023-06-15
// 设置非法月份(如13)会抛出DateTimeException
try {
date.withMonth(13);
} catch (Exception e) {
System.out.println("异常:" + e.getMessage());
// 输出"Invalid value for MonthOfYear (valid values 1 - 12): 13"
}
// 其他月份相关操作
LocalDate firstDayOfMonth = date.withDayOfMonth(1); // 当月第一天
System.out.println("当月第一天:" + firstDayOfMonth);
LocalDate lastDayOfMonth = date.withDayOfMonth(
date.lengthOfMonth()); // 当月最后一天
System.out.println("当月最后一天:" + lastDayOfMonth);
}
}
特点:
withMonth()返回新的LocalDate对象,原对象不变(不可变性)- 支持链式调用,如
date.withMonth(5).withDayOfMonth(1) - 自动处理闰年、不同月份天数等复杂情况
(2)YearMonth中的月份设置
YearMonth专门处理"年-月"场景,适合计算月份差、月末日期等操作:
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
public class YearMonthExample {
public static void main(String[] args) {
YearMonth yearMonth = YearMonth.now(); // 当前年月,如2023-10
// 设置月份为12月
YearMonth december = yearMonth.withMonth(12);
System.out.println("设置为12月后的年月:" + december); // 输出2023-12
// 获取该月的总天数(处理闰年2月)
int daysInFebruary2024 = YearMonth.of(2024, 2).lengthOfMonth(); // 2024是闰年
System.out.println("2024年2月的天数:" + daysInFebruary2024); // 输出29
int daysInFebruary2023 = YearMonth.of(2023, 2).lengthOfMonth();
System.out.println("2023年2月的天数:" + daysInFebruary2023); // 输出28
// 月份加减操作
YearMonth nextMonth = yearMonth.plusMonths(1);
System.out.println("下个月份:" + nextMonth);
YearMonth prevMonth = yearMonth.minusMonths(1);
System.out.println("上个月份:" + prevMonth);
// 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月");
System.out.println("格式化输出:" + yearMonth.format(formatter)); // 如"2023年10月"
// 业务场景示例:计算两个月份之间的月数差
YearMonth start = YearMonth.of(2023, 1);
YearMonth end = YearMonth.of(2023, 12);
long monthsBetween = java.time.temporal.ChronoUnit.MONTHS.between(start, end);
System.out.println("2023年1月到12月的月数差:" + monthsBetween); // 输出11
}
}