Java入门( 日期类与 BigDecimal 工具类 )
目录一、日期时间处理类从 Date 到 LocalDateTime 的升级1.1 老牌 Date 类了解即可慎用为主实战示例Date 类基础使用1.2 LocalDateTime 类Java8 日期处理首选1.2.1 创建 LocalDateTime 对象1.2.2 获取日期时间字段1.2.3 日期时间运算增减时间1.2.4 日期时间调整获取特殊时间二、BigDecimal 类高精度数值运算的救星2.1 核心注意点创建 BigDecimal 对象的正确方式2.2 基础运算加、减、乘2.3 除法运算解决无限循环小数问题2.3.1 舍入模式8 种核心规则2.3.2 除法实战指定精度 舍入模式三、核心总结在 Java 日常开发中处理日期时间和高精度数值运算是高频需求早期的Date类存在方法过时、设计不友好等问题而浮点型double/float的精度丢失问题更是让财务、金融等场景的运算避之不及。本文将详细讲解 Java 中日期时间处理Date类、LocalDateTime类和高精度数值运算BigDecimal类的核心用法结合实战示例拆解关键知识点帮你彻底掌握这两个开发必备工具类。一、日期时间处理类从 Date 到 LocalDateTime 的升级日期时间处理是开发中不可或缺的部分Java 从最初的Date类到 Java 8 引入的java.time包下的LocalDateTime类实现了从 “简陋” 到 “优雅” 的跨越。LocalDateTime解决了Date类线程不安全、方法过时、时区处理繁琐等问题成为目前主流的日期时间处理方案。1.1 老牌 Date 类了解即可慎用为主Date类位于java.util包用于表示精确到毫秒的日期时间但其大部分构造方法和成员方法已被标记为过时仅作兼容旧代码使用核心特点和注意事项如下无参构造方法new Date()获取当前系统时间带年 / 月 / 日参数的构造方法存在偏移问题年份从 1900 开始计算月份 0 代表 1 月、1 代表 2 月以此类推多数获取时间字段的方法如getHours()、getMonth()已被Calendar类替代仅保留after()、before()、compareTo()等少数比较方法。实战示例Date 类基础使用import java.util.Date; public class DateDemo { public static void main(String[] args) { // 1. 获取当前系统时间精确到毫秒 Date nowDate new Date(); System.out.println(当前系统时间 nowDate); // 2. 构造指定时间注意偏移1242024-190012月1010日 Date specifyDate new Date(124, 1, 10, 15, 30, 20); System.out.println(指定时间2024-02-10 15:30:20 specifyDate); // 3. 日期比较after/before/compareTo boolean isAfter nowDate.after(specifyDate); boolean isBefore nowDate.before(specifyDate); int compare nowDate.compareTo(specifyDate); System.out.println(当前时间是否在指定时间之后 isAfter); System.out.println(当前时间是否在指定时间之前 isBefore); System.out.println(日期比较结果0相等1大于-1小于 compare); } }输出结果随系统时间变化当前系统时间Sat Mar 21 16:00:00 CST 2026 指定时间2024-02-10 15:30:20Sat Feb 10 15:30:20 CST 2024 当前时间是否在指定时间之后true 当前时间是否在指定时间之前false 日期比较结果0相等1大于-1小于11.2 LocalDateTime 类Java8 日期处理首选LocalDateTime位于java.time包是不可变、线程安全的日期时间类整合了LocalDate日期和LocalTime时间支持日期时间的创建、解析、字段获取、运算、调整等所有常用操作是目前 Java 开发中日期时间处理的核心类。1.2.1 创建 LocalDateTime 对象LocalDateTime的构造方法为私有无法直接new需通过静态方法创建核心方式有 3 种获取当前时间、指定日期时间、从字符串解析其中字符串解析需配合DateTimeFormatter指定格式注意大小写yyyy 年MM 月dd 日HH24 小时制hh12 小时制。实战示例创建 LocalDateTime 对象import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class LocalDateTimeCreate { public static void main(String[] args) { // 方式1获取当前系统日期时间最常用 LocalDateTime now LocalDateTime.now(); System.out.println(当前日期时间 now); // 方式2指定年/月/日/时/分/秒创建 LocalDateTime specifyTime LocalDateTime.of(2026, 3, 21, 16, 0, 0); System.out.println(指定日期时间 specifyTime); // 方式3从自定义格式的字符串解析需指定DateTimeFormatter String timeStr 2026-03-21 16:05:30; DateTimeFormatter formatter DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); LocalDateTime parseTime LocalDateTime.parse(timeStr, formatter); System.out.println(字符串解析的日期时间 parseTime); } }输出结果当前日期时间2026-03-21T16:00:00.123456789 指定日期时间2026-03-21T16:00 字符串解析的日期时间2026-03-21T16:05:301.2.2 获取日期时间字段通过getXxx()系列方法可直接获取年、月、日、时、分、秒、星期、年内天数等字段无偏移问题比Date类更直观。实战示例获取日期时间字段import java.time.LocalDateTime; public class LocalDateTimeGet { public static void main(String[] args) { LocalDateTime now LocalDateTime.now(); // 基础字段年、月、日、时、分、秒 int year now.getYear(); int month now.getMonthValue(); // 获取数字月份1-12 int day now.getDayOfMonth(); int hour now.getHour(); int minute now.getMinute(); int second now.getSecond(); // 扩展字段星期、本月天数、年内天数 int week now.getDayOfWeek().getValue(); // 星期1周一7周日 int dayOfYear now.getDayOfYear(); // 打印结果 System.out.println(年 year 月 month 日 day); System.out.println(时 hour 分 minute 秒 second); System.out.println(本周星期 week 当年第 dayOfYear 天); } }输出结果年2026 月3 日21 时16 分10 秒25 本周星期6 当年第80天1.2.3 日期时间运算增减时间LocalDateTime提供plusXxx()增加时间和minusXxx()减少时间方法支持天、周、月、年、时、分、秒等维度的运算方法返回新对象原对象不可变使用时需接收返回值。实战示例日期时间增减运算import java.time.LocalDateTime; public class LocalDateTimeCalculate { public static void main(String[] args) { LocalDateTime now LocalDateTime.now(); System.out.println(原始时间 now); // 增加时间1天、2周、3个月、1年、2小时 LocalDateTime plusTime now.plusDays(1).plusWeeks(2).plusMonths(3).plusYears(1).plusHours(2); System.out.println(增加后时间 plusTime); // 减少时间3天、1周、2个月、10小时 LocalDateTime minusTime now.minusDays(3).minusWeeks(1).minusMonths(2).minusHours(10); System.out.println(减少后时间 minusTime); } }输出结果原始时间2026-03-21T16:15:30.123 增加后时间2027-06-05T18:15:30.123 减少后时间2026-01-15T06:15:30.1231.2.4 日期时间调整获取特殊时间通过TemporalAdjusters工具类配合with()方法可快速获取本周周一 / 周日、本月第一天 / 最后一天、本年第一天 / 最后一天等特殊时间无需手动计算简化开发。实战示例获取特殊日期时间import java.time.LocalDateTime; import java.time.DayOfWeek; import java.time.temporal.TemporalAdjusters; public class LocalDateTimeAdjust { public static void main(String[] args) { LocalDateTime now LocalDateTime.now(); System.out.println(当前时间 now); // 1. 本周周一和周日previousOrSame/nextOrSame当前或最近的指定星期 LocalDateTime monday now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); LocalDateTime sunday now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); // 2. 本月第一天和最后一天 LocalDateTime firstDayOfMonth now.with(TemporalAdjusters.firstDayOfMonth()); LocalDateTime lastDayOfMonth now.with(TemporalAdjusters.lastDayOfMonth()); // 3. 本年第一天和最后一天 LocalDateTime firstDayOfYear now.with(TemporalAdjusters.firstDayOfYear()); LocalDateTime lastDayOfYear now.with(TemporalAdjusters.lastDayOfYear()); // 打印结果 System.out.println(本周周一 monday); System.out.println(本周周日 sunday); System.out.println(本月第一天 firstDayOfMonth); System.out.println(本月最后一天 lastDayOfMonth); System.out.println(本年第一天 firstDayOfYear); System.out.println(本年最后一天 lastDayOfYear); } }输出结果当前时间2026-03-21T16:20:00.123 本周周一2026-03-17T16:20:00.123 本周周日2026-03-23T16:20:00.123 本月第一天2026-03-01T16:20:00.123 本月最后一天2026-03-31T16:20:00.123 本年第一天2026-01-01T16:20:00.123 本年最后一天2026-12-31T16:20:00.123二、BigDecimal 类高精度数值运算的救星在处理金额、税率、汇率等高精度数值运算时double和float会因二进制存储的精度丢失问题导致计算结果错误例如0.10.20.30000000000000004。BigDecimal类位于java.math包是不可变、线程安全的高精度数值类支持任意精度的小数运算完美解决浮点型精度问题。2.1 核心注意点创建 BigDecimal 对象的正确方式BigDecimal提供了多种构造方法其中 **double构造方法存在精度丢失风险 **字符串构造方法是推荐方式可精确表示数值。如果必须使用double创建可通过BigDecimal.valueOf(double val)静态方法内部将double转为字符串避免精度丢失。实战示例不同构造方法的对比import java.math.BigDecimal; public class BigDecimalCreate { public static void main(String[] args) { // 错误方式double构造方法精度丢失 BigDecimal bigDecimalDouble new BigDecimal(0.1); // 正确方式1字符串构造方法精确表示 BigDecimal bigDecimalStr new BigDecimal(0.1); // 正确方式2valueOf静态方法处理double类型 BigDecimal bigDecimalValueOf BigDecimal.valueOf(0.1); // 打印结果对比 System.out.println(double构造方法 bigDecimalDouble); System.out.println(字符串构造方法 bigDecimalStr); System.out.println(valueOf静态方法 bigDecimalValueOf); } }输出结果double构造方法0.1000000000000000055511151231257827021181583404541015625 字符串构造方法0.1 valueOf静态方法0.12.2 基础运算加、减、乘BigDecimal的加减乘运算通过add()、subtract()、multiply()方法实现所有方法均返回新的 BigDecimal 对象原对象不可变运算时需保证操作数均为BigDecimal类型且通过字符串构造创建。实战示例BigDecimal 加减乘运算import java.math.BigDecimal; public class BigDecimalAddSubMul { public static void main(String[] args) { // 初始化两个高精度数值金额100.50 元和 25.30 元 BigDecimal num1 new BigDecimal(100.50); BigDecimal num2 new BigDecimal(25.30); // 加法100.50 25.30 BigDecimal addResult num1.add(num2); // 减法100.50 - 25.30 BigDecimal subResult num1.subtract(num2); // 乘法100.50 * 25.30 BigDecimal mulResult num1.multiply(num2); // 打印结果 System.out.println(加法结果 addResult 元); System.out.println(减法结果 subResult 元); System.out.println(乘法结果 mulResult 元); } }输出结果加法结果125.80 元 减法结果75.20 元 乘法结果2542.6500 元2.3 除法运算解决无限循环小数问题BigDecimal的除法运算通过divide()方法实现如果运算结果为无限循环小数直接调用无参 divide () 会抛出 ArithmeticException 异常因此实际开发中必须指定精度和舍入模式或通过MathContext指定运算规则。2.3.1 舍入模式8 种核心规则Java 提供RoundingMode枚举类定义了 8 种舍入模式开发中最常用的是 **HALF_UP四舍五入**其他模式可根据业务场景选择如财务结算的HALF_EVEN银行家舍入法核心模式说明如下舍入模式核心规则示例UP远离零舍入1.234→1.24-1.234→-1.24DOWN接近零舍入1.236→1.23-1.236→-1.23HALF_UP四舍五入1.235→1.24-1.235→-1.24HALF_EVEN银行家舍入奇数进偶数舍1.235→1.241.245→1.24UNNECESSARY断言精确结果否则抛异常10/25正常1/3抛异常2.3.2 除法实战指定精度 舍入模式推荐方式divide(BigDecimal divisor, int scale, RoundingMode roundingMode)其中scale为保留的小数位数roundingMode为舍入模式。实战示例BigDecimal 除法运算import java.math.BigDecimal; import java.math.RoundingMode; public class BigDecimalDivide { public static void main(String[] args) { // 初始化数值10.0 除以 3.0无限循环小数 BigDecimal num1 new BigDecimal(10.0); BigDecimal num2 new BigDecimal(3.0); // 方式1指定精度保留2位小数 四舍五入模式最常用 BigDecimal divide1 num1.divide(num2, 2, RoundingMode.HALF_UP); // 方式2指定精度保留3位小数 银行家舍入法 BigDecimal divide2 num1.divide(num2, 3, RoundingMode.HALF_EVEN); // 方式3通过MathContext指定精度和模式总精度4位四舍五入 BigDecimal divide3 num1.divide(num2, new java.math.MathContext(4, RoundingMode.HALF_UP)); // 打印结果 System.out.println(10.0/3.0保留2位四舍五入 divide1); System.out.println(10.0/3.0保留3位银行家舍入 divide2); System.out.println(10.0/3.0总精度4位四舍五入 divide3); } }输出结果10.0/3.0保留2位四舍五入3.33 10.0/3.0保留3位银行家舍入3.333 10.0/3.0总精度4位四舍五入3.333三、核心总结日期时间处理优先使用 Java8 的LocalDateTime摒弃过时的Date类LocalDateTime支持创建、解析、字段获取、运算、调整等所有操作线程安全且无偏移问题配合DateTimeFormatter处理字符串解析TemporalAdjusters处理特殊时间。高精度数值运算使用BigDecimal替代double/float避免精度丢失必须通过字符串构造方法或valueOf()创建对象运算后接收新返回对象除法运算需指定精度和舍入模式常用HALF_UP四舍五入。共性特点LocalDateTime和BigDecimal均为不可变类所有修改 / 运算方法均返回新对象原对象保持不变天生线程安全适合高并发场景。这两个工具类是 Java 开发的基础且核心的工具掌握其正确用法能有效避免开发中的常见坑如日期偏移、精度丢失提升代码的健壮性和可维护性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2434330.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!