news 2026/3/3 5:33:22

java学习--Calendar

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java学习--Calendar

一、Calendar 类核心定位与核心特性

✅ 1. 核心作用

java.util.Calendar是 Java 提供的日期时间「操作与计算」工具类,是 JDK 1.1 推出的Date类的替代增强方案—— 解决了Date类直接操作年 / 月 / 日 / 时 / 分 / 秒繁琐、方法大量过时的问题,专门负责日期字段的获取、设置、增减计算

✅ 2. 核心特性(必知)

  1. 抽象类,不能直接 new:Calendar 是抽象父类,需通过静态方法Calendar.getInstance()获取子类(GregorianCalendar,公历)对象;
  2. 默认表示当前系统时间:调用getInstance()得到的对象,默认封装了「当前电脑的日期 + 时间」;
  3. 字段索引化:通过预定义的静态常量(如YEARMONTH)操作年、月、日等字段,而非直接调用方法;
  4. 存在设计缺陷:月份从0开始、星期从1开始,是最易踩坑的点;
  5. 线程不安全:与DateSimpleDateFormat一致,多线程环境下共享实例会有并发风险;
  6. 过渡型 API:JDK 1.8 推出的java.time新日期 API(LocalDate/LocalDateTime)完全替代它,新项目优先用新 API,老项目兼容时用 Calendar

二、Calendar 核心使用步骤(通用)

Calendar 的所有操作都遵循「获取对象 → 操作字段 → 结果处理」三步,是固定套路,务必牢记:

import java.util.Calendar; public class CalendarBase { public static void main(String[] args) { // 1. 核心:获取Calendar实例(唯一方式,不能new Calendar()) Calendar cal = Calendar.getInstance(); // 2. 核心操作:获取/设置/增减 年、月、日、时、分、秒等字段 int year = cal.get(Calendar.YEAR); // 获取年份 cal.set(Calendar.MONTH, 11); // 设置月份为12月 cal.add(Calendar.DAY_OF_MONTH, 7); // 日期加7天 // 3. 结果转换:转Date对象 / 格式化输出 java.util.Date date = cal.getTime(); System.out.println("转换后的Date对象:" + date); } }

三、Calendar 三大核心操作(全示例 + 详解)

✅ 操作 1:获取日期字段(get 方法)—— 最常用

通过int get(int field)方法,传入 Calendar 预定义的字段常量,获取指定的日期 / 时间数值,这是 Calendar 最基础的用法。

✔️ 常用字段常量(必须熟记)
常量名含义取值范围 / 注意事项
Calendar.YEAR年份4 位完整年份(如 2025,无偏移,直接用)
Calendar.MONTH月份✅【核心坑点】0~11(0=1 月、1=2 月...11=12 月)
Calendar.DAY_OF_MONTH当月日期1~31(对应日历中的「几号」,最常用)
Calendar.HOUR_OF_DAY24 小时制小时0~23(推荐,业务开发通用)
Calendar.HOUR12 小时制小时0~11
Calendar.MINUTE分钟0~59
Calendar.SECOND0~59
Calendar.MILLISECOND毫秒0~999
Calendar.DAY_OF_WEEK星期✅【坑点】1~7(1 = 周日、2 = 周一...7 = 周六)
✔️ 完整获取示例代码
import java.util.Calendar; public class CalendarGet { public static void main(String[] args) { // 获取Calendar实例(当前时间) Calendar cal = Calendar.getInstance(); // 获取核心字段 int year = cal.get(Calendar.YEAR); // 月份修正:+1 才是实际月份(因为Calendar月份从0开始) int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DAY_OF_MONTH); int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); // 星期修正:1=周日,需转换为业务常用的「周一~周日」 int week = cal.get(Calendar.DAY_OF_WEEK); String weekStr = switch (week) { case 1 -> "周日"; case 2 -> "周一"; case 3 -> "周二"; case 4 -> "周三"; case 5 -> "周四"; case 6 -> "周五"; case 7 -> "周六"; default -> ""; }; // 格式化输出 System.out.printf("当前时间:%d年%d月%d日 %02d:%02d:%02d %s%n", year, month, day, hour, minute, second, weekStr); } }

✅ 关键提醒:月份和星期必须做修正,否则会出现「1 月显示 0、12 月显示 11、周日显示 1」的错误,这是 Calendar 最高频的坑!

✅ 操作 2:设置日期字段(set 方法)—— 两种方式

通过set方法可以精准修改指定字段的值,支持「单字段设置」和「多字段批量设置」,满足任意自定义日期的需求,修改后 Calendar 对象的时间会同步更新。

✔️ 方式 1:单字段设置void set(int field, int value)
Calendar cal = Calendar.getInstance(); // 设置年份为2026 cal.set(Calendar.YEAR, 2026); // 设置月份为3月(注意:传入2,因为0=1月) cal.set(Calendar.MONTH, 2); // 设置日期为15号 cal.set(Calendar.DAY_OF_MONTH, 15); // 设置小时为18点(24小时制) cal.set(Calendar.HOUR_OF_DAY, 18); System.out.println("设置后时间:" + cal.getTime());
✔️ 方式 2:批量设置void set(int year, int month, int day[, int hour, int minute, int second])

一次性设置年、月、日(可选时分秒),最简洁高效,推荐使用:

Calendar cal = Calendar.getInstance(); // 批量设置:2025年12月25日 20:00:00(月份传11,对应12月) cal.set(2025, 11, 25, 20, 0, 0); System.out.println("批量设置后:" + cal.getTime());

✅ 操作 3:增减日期计算(add 方法)—— 核心亮点

void add(int field, int amount)是 Calendar 最核心的优势方法,专门用于日期的偏移计算(加 / 减年、月、日、时等),自动处理「跨月、跨年、闰年」等边界情况,无需手动计算。

  • amount > 0:字段增加对应数值
  • amount < 0:字段减少对应数值
✔️ 完整计算示例代码(开发高频场景)
import java.util.Calendar; import java.util.Date; public class CalendarAdd { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); System.out.println("原始时间:" + now); // 1. 加1年 cal.add(Calendar.YEAR, 1); System.out.println("加1年:" + cal.getTime()); cal.add(Calendar.YEAR, -1); // 还原 // 2. 减2个月 cal.add(Calendar.MONTH, -2); System.out.println("减2个月:" + cal.getTime()); cal.add(Calendar.MONTH, 2); // 还原 // 3. 加7天(计算1周后,开发高频) cal.add(Calendar.DAY_OF_MONTH, 7); System.out.println("加7天:" + cal.getTime()); cal.add(Calendar.DAY_OF_MONTH, -7); // 还原 // 4. 减3小时 cal.add(Calendar.HOUR_OF_DAY, -3); System.out.println("减3小时:" + cal.getTime()); // ✅ 自动处理边界:2025-01-01 减1天 → 2024-12-31 cal.set(2025, 0, 1); cal.add(Calendar.DAY_OF_MONTH, -1); System.out.println("边界处理示例:" + cal.getTime()); } }

✅ 核心优势:add方法是 Calendar 相比 Date 的最大亮点,彻底解决了手动计算日期的繁琐和错误风险

四、Calendar 与 Date 互转(开发必备)

实际开发中,Calendar 负责「日期计算」,Date 负责「表示时间瞬间」,二者经常需要互相转换,转换逻辑是开发高频考点,必须熟练掌握。

✅ 1. Calendar → Date

调用 Calendar 的Date getTime()方法,直接返回对应的 Date 对象,无参数、无异常,极简:

Calendar cal = Calendar.getInstance(); // Calendar 转 Date Date date = cal.getTime();

✅ 2. Date → Calendar

调用 Calendar 的void setTime(Date date)方法,将 Date 对象的时间赋值给 Calendar,无返回值、无异常

Date date = new Date(); Calendar cal = Calendar.getInstance(); // Date 转 Calendar cal.setTime(date);

✅ 完整互转示例

import java.util.Calendar; import java.util.Date; public class CalendarDateConvert { public static void main(String[] args) { // ========== Calendar → Date ========== Calendar cal1 = Calendar.getInstance(); cal1.set(2025, 11, 29); // 2025-12-29 Date date1 = cal1.getTime(); System.out.println("Calendar转Date:" + date1); // ========== Date → Calendar ========== Date date2 = new Date(); // 当前时间 Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); System.out.printf("Date转Calendar:%d年%d月%d日%n", cal2.get(Calendar.YEAR), cal2.get(Calendar.MONTH)+1, cal2.get(Calendar.DAY_OF_MONTH)); } }

五、Calendar 格式化(转指定格式字符串)

Calendar 本身不具备格式化能力,和 Date 一样,需要配合格式化工具类完成「Calendar → 自定义格式字符串」的转换,主流两种方案:

✅ 方案 1:Calendar + SimpleDateFormat(传统方案,兼容所有 JDK)

核心逻辑:Calendar → Date → 格式化字符串

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class CalendarFormat { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); // 先转Date // 定义格式:yyyy-MM-dd HH:mm:ss SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化 String dateStr = sdf.format(date); System.out.println("格式化结果:" + dateStr); // 示例:2025-12-29 16:30:50 } }

✅ 方案 2:Calendar → JDK8 新 API → DateTimeFormatter(推荐,线程安全)

JDK8 推出的DateTimeFormatter线程安全、无并发风险,是当前开发首选,转换逻辑:Calendar → Date → Instant → LocalDateTime → 格式化

import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; public class CalendarNewFormat { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); // 1. Date → LocalDateTime LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); // 2. 定义格式化器(线程安全) DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 3. 格式化 String dateStr = dtf.format(ldt); System.out.println("JDK8格式化结果:" + dateStr); } }

六、Calendar 高频坑点 & 注意事项(避坑宝典)

这部分是重中之重,Calendar 的设计缺陷导致坑点极多,也是面试高频考点,务必全部掌握,杜绝开发 BUG!

❌ 坑点 1:月份从 0 开始(最高频)

✅ 现象:Calendar.JANUARY = 0Calendar.DECEMBER = 11,直接获取 / 设置会少 1 个月;✅ 解决方案:获取时 + 1,设置时 - 1;✅ 示例:设置 3 月 → 传入 2,获取到 2 → 表示 3 月。

❌ 坑点 2:星期从 1 开始,且 1 代表周日(次高频)

✅ 现象:Calendar.SUNDAY =1Calendar.SATURDAY=7,与业务中「周一 = 1、周日 = 7」不符;✅ 解决方案:获取后通过switch/if转换为业务常用格式。

❌ 坑点 3:Calendar 是线程不安全的

✅ 现象:多线程环境下共享同一个 Calendar 实例,调用set/add方法会导致日期错乱;✅ 解决方案:① 每个线程独立创建Calendar 实例;② 新项目直接用 JDK8 新日期 API(线程安全)。

❌ 坑点 4:add 与 roll 方法混淆(易误用)

Calendar 有两个偏移方法:addroll99% 的场景用 add,二者核心区别:

  • add(int field, int amount)联动其他字段(推荐),例如 2025-12-31 加 1 天 → 2026-01-01;
  • roll(int field, int amount)不联动其他字段,仅修改当前字段,例如 2025-12-31 加 1 天 → 2025-12-01(开发极少用)。

❌ 坑点 5:getTime () 与 getTimeInMillis () 混淆

  • getTime():返回Date 对象,用于格式转换、Date 互转;
  • getTimeInMillis():返回时间戳(long 型,毫秒),用于时间比较、跨语言传输。

七、Calendar vs Date vs JDK8 新 API(选型指南)

很多同学会疑惑三者的区别和选型,这里给出清晰的对比和开发建议,直接套用即可:

✅ 三者核心区别

类 / API定位优点缺点
Date表示「时间瞬间」简单、轻量,仅表示时间点方法大量过时,无计算 / 格式化能力
Calendar日期「操作 / 计算」工具支持字段获取、设置、增减,自动处理边界设计缺陷多(月 0 周 1)、线程不安全、API 繁琐
java.time(JDK8)新一代日期时间 API✅线程安全 ✅无设计缺陷 ✅API 优雅 ✅支持时区 / 闰年JDK8 及以上版本可用(目前项目均满足)

✅ 开发选型建议(强制遵循)

  1. 新项目 / 技术升级项目直接使用 JDK8 新日期 API(LocalDate/LocalDateTime/Instant),彻底抛弃 Date + Calendar,开发效率翻倍,无坑点;
  2. 老项目维护:需兼容 Date/Calendar 时,用 Calendar 做日期计算,用 Date 表示时间点,用 SimpleDateFormat 做格式化,严格规避上述坑点;
  3. 核心原则能不用 Calendar 就不用,它只是 Date 的过渡方案,并非最优解。

八、核心知识点总结

  1. Calendar抽象类,唯一获取实例的方式是Calendar.getInstance()
  2. Calendar 核心能力:字段获取(get)、字段设置(set)、日期计算(add),是 Date 的增强工具;
  3. 两大致命坑点:月份 0 开始、星期 1 = 周日,必须做修正;
  4. Calendar 与 Date 互转:getTime()(Cal→Date)、setTime(Date)(Date→Cal);
  5. Calendar 无格式化能力,需配合 SimpleDateFormat/DateTimeFormatter;
  6. 终极建议:JDK8+ 项目优先使用java.time新 API,Calendar 仅用于老项目兼容。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/2 10:43:29

PyTorch-CUDA-v2.7镜像中监测死链并及时修复保持用户体验

PyTorch-CUDA-v2.7 镜像中监测死链并及时修复保持用户体验 在 AI 开发日益依赖容器化环境的今天&#xff0c;一个看似不起眼的问题——“打不开 Jupyter”——却常常成为压垮用户体验的最后一根稻草。你有没有遇到过这样的场景&#xff1a;刚申请好 GPU 实例&#xff0c;满怀期…

作者头像 李华
网站建设 2026/3/2 23:48:54

清华镜像站同步上线PyTorch-CUDA-v2.7支持高速下载

清华镜像站上线 PyTorch-CUDA-v2.7&#xff1a;让深度学习环境部署不再“卡脖子” 在实验室熬夜调试代码时&#xff0c;你是否曾因为 torch.cuda.is_available() 返回 False 而抓狂&#xff1f;是不是花了一整天时间不是在训练模型&#xff0c;而是在查日志、对版本、重装驱动&…

作者头像 李华
网站建设 2026/3/1 10:48:06

PyTorch-CUDA-v2.7镜像中提及‘diskinfo下载官网’增强可信度

PyTorch-CUDA-v2.7 镜像&#xff1a;构建安全高效的深度学习开发环境 在人工智能研发日益工程化的今天&#xff0c;一个稳定、高效且可信的开发环境&#xff0c;往往比模型结构本身更能决定项目的成败。尤其是在多团队协作、远程部署或持续集成&#xff08;CI/CD&#xff09;场…

作者头像 李华
网站建设 2026/2/28 14:39:36

PyTorch-CUDA-v2.7镜像中设置阶梯定价鼓励大额采购

PyTorch-CUDA-v2.7 镜像与阶梯定价&#xff1a;技术集成与商业激励的双重实践 在当前 AI 模型规模不断膨胀、训练成本持续攀升的背景下&#xff0c;如何让开发者既能快速上手深度学习环境&#xff0c;又能以更经济的方式获取大规模算力&#xff0c;已成为云平台和基础设施服务商…

作者头像 李华
网站建设 2026/3/1 9:30:37

PyTorch-CUDA-v2.7镜像中针对关键词‘pytorch安装教程gpu’优化标题

PyTorch-CUDA-v2.7镜像实战解析&#xff1a;如何一键部署GPU加速深度学习环境 在深度学习项目启动的前48小时里&#xff0c;有多少开发者真正把时间花在了写代码上&#xff1f;更现实的情况是&#xff1a;他们正卡在安装PyTorch GPU版本的路上——驱动不兼容、CUDA版本错配、cu…

作者头像 李华
网站建设 2026/3/3 4:38:39

DiskInfo下载官网数据后如何配置PyTorch-CUDA-v2.7环境

DiskInfo下载官网数据后如何配置PyTorch-CUDA-v2.7环境 在现代AI开发中&#xff0c;一个常见的场景是&#xff1a;你刚刚用 DiskInfo 工具从某设备官网抓取了一批结构化系统数据&#xff0c;准备做异常检测或性能预测建模。此时最不想面对的&#xff0c;就是花半天时间折腾GPU…

作者头像 李华