日期相关类Date 类java.util.DateJava 早期的日期时间类精确到毫秒用来表示一个特定的时刻常用成员方法可用方法1boolean after(Date when)判断当前日期是否在指定日期之后2boolean before(Date when)判断当前日期是否在指定日期之前3int compareTo(Date anotherDate)比较两个 Date返回正负 / 04boolean equals(Object obj)比较两个时间是否相等5static Date from(Instant instant)Instant 转 DateLocalDateTimeLocalDateTime是Java 8引入的日期时间类不可变类没有时区信息只保存日期 时间年、月、日、时、分、秒构造方法是private私有不能直接new创建对象只能通过静态方法获取实例//私有构造 private LocalDateTime(LocalDate date, LocalTime time) { this.date date; this.time time; }创建 LocalDateTime 对象//1. 获取当前系统日期时间 LocalDateTime now LocalDateTime.now(); //2. 指定年月日时分创建时间 LocalDateTime dateTime LocalDateTime.of(2023, 5, 15, 10, 30); //3. 解析字符串默认格式yyyy-MM-ddTHH:mm:ss LocalDateTime parsed LocalDateTime.parse(2023-05-15T10:30:00);//1.1 获取当前日期时间 LocalDateTime now LocalDateTime.now(); System.out.println(当前日期 now(): now); // 1.2 指定年月日时分创建 LocalDateTime dateTimeOfLocalDateTime.of(2026,10,11,13,56,30); System.out.println(of指定时间dateTimeOf); // 1.3 默认格式字符串解析 LocalDateTime parsedDefaultLocalDateTime.parse(2026-10-11T13:56:20); System.out.println(默认parse解析parsedDefault);获取当前日期时间//1.1 获取当前日期时间 LocalDateTime now LocalDateTime.now(); System.out.println(当前日期 now(): now);获取 年、月、日、时、分、秒LocalDateTime dateTimeLocalDateTime.now(); int yeardateTime.getYear(); int monthdateTime.getMonthValue(); int daydateTime.getDayOfMonth(); int hourdateTime.getHour(); int minutedateTime.getMinute(); int seconddateTime.getSecond(); System.out.println(年year); System.out.println(月month); System.out.println(日day); System.out.println(时hour); System.out.println(分minute); System.out.println(秒second);创建指定日期时间 of ()// 1.2 指定年月日时分创建 LocalDateTime dateTimeOfLocalDateTime.of(2026,10,11,13,56,30); System.out.println(of指定时间dateTimeOf);自定义字符串解析parse DateTimeFormatteryyyy4 位年份MM2 位月份dd2 位日期HH24 小时制小时mm分钟ss秒String stringDate2026-10-11 14:20:32; DateTimeFormatter dateTimeFormatter DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); LocalDateTime parseTimeLocalDateTime.parse(stringDate,dateTimeFormatter); System.out.println(自定义格式解析结果parseTime);获取详细时间信息System.out.println(当前日期为dateTime); System.out.println(本周周几1周一7周日dateTime.getDayOfWeek().getValue()); System.out.println(本月第几天dateTime.getDayOfMonth()); System.out.println(当年第几天dateTime.getDayOfYear());日期运算plusXXX /minusXXXLocalDateTime不可变调用 plus/minus 方法会返回新对象原对象不会修改plusDays(1)加 1 天minusDays(1)减 1 天plusWeeks(1)加 1 周minusWeeks(1)减 1 周plusMonths(1)加 1 月minusMonths(1)减 1 月plusYears(1)加 1 年minusYears(1)减 1 年// 增减天数 LocalDateTime plus1DaydateTime.plusDays(1); LocalDateTime minus1DaydateTime.minusDays(1); System.out.println(增加1天后plus1Day); System.out.println(减少1天后minus1Day); //增减周 LocalDateTime plus1WeekdateTime.plusWeeks(1); LocalDateTime minus1WeekdateTime.minusWeeks(1); System.out.println(增加一周后plus1Week); System.out.println(减少一周后minus1Week); //增减月 LocalDateTime plus1MonthdateTime.plusMonths(1); LocalDateTime minus1MonthdateTime.minusMonths(1); System.out.println(增加一月后plus1Month); System.out.println(减少一月后minus1Month); //增减年 LocalDateTime plus1YeardateTime.plusYears(1); LocalDateTime minus1YeardateTime.minusYears(1); System.out.println(增加一年后plus1Year); System.out.println(减少一年后minus1Year);TemporalAdjusters 时间调节器获取指定时间获取本周周一、周日LocalDateTime currentDateLocalDateTime.now(); //previousOrSame 当前或之前最近的周一 LocalDateTime firstDayOfWeekcurrentDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); //nextOrSame当前或之后最近的周日 LocalDateTime lastDayOfWeekcurrentDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); System.out.println(本周周一firstDayOfWeek); System.out.println(本周周日lastDayOfWeek);previousOrSame寻找当前日期或之前最近的指定星期nextOrSame寻找当前日期或之后最近的指定星期获取当月第一天、当月最后一天LocalDateTime currentDate1LocalDateTime.now(); LocalDateTime firstDayOfMonthcurrentDate1.with(TemporalAdjusters.firstDayOfMonth()); LocalDateTime lastDayOfMonthcurrentDate1.with(TemporalAdjusters.lastDayOfMonth()); System.out.println(当月第一天firstDayOfMonth); System.out.println(当月最后一天lastDayOfMonth);总结不可变每次修改时间都会生成新对象原对象不变私有构造不能 new只能now()/of()/parse()创建格式化DateTimeFormatter线程安全替代旧SimpleDateFormat时间调节器 TemporalAdjusters快速获取月初、月末、周起始等特殊时间旧Date、Calendar线程不安全新项目优先使用 Java8 时间 APIBigDecimalBigDecimal在java.math包用于高精度数值运算解决 float/double 浮点丢失精度的问题double 只能保证 16 位有效数字BigDecimal 是不可变类每次加减乘除都会返回新的 BigDecimal 对象原对象不会变构造方法//传入double 1.99 double 存储不精确 BigDecimal doubleNumnew BigDecimal(1.99); System.out.println(doubleNum); // 1.98999999 //传入字符串 2.99 直接精确解析 BigDecimal stringNumnew BigDecimal(2.99); System.out.println(stringNum); // 2.99原理new BigDecimal(1.99)a代码里的1.99是 double 字面量double 底层二进制无法精确表示十进制小数存的是一个近似值bBigDecimal 只是把这个已经不准确的 double 值完整精确还原出来所以输出一长串小数开发规范1不要用 BigDecimal (double) 构造器优先使用字符串构造器new BigDecimal(数字)2如果已经有 double 变量可以用BigDecimal.valueOf(double值)底层会转字符串避免精度丢失比较大小1不要用、不要直接用equals()2equals()会同时比较数值 小数位数new BigDecimal(2.0)和new BigDecimal(2)equals 判断不相等3compareTo()可以用这个比较BigDecimal num1new BigDecimal(10.0); BigDecimal num2new BigDecimal(10); System.out.println(num1.compareTo(num2)); //返回 0 代表相等大于0代表num1num2,小于0代表num1num2常见使用场景金额计算支付、财务、科学计算所有要求不能丢失小数精度的场景面试考点总结1为什么不用 double 做金额二进制浮点无法精确表示部分十进制小数存在精度丢失2BigDecimal 构造器BigDecimal(double)的坑3BigDecimal 是不可变类运算会产生新对象3比较数值用compareTo不要 equals4除法必须指定舍入规则防止除不尽报错BigDecimal 加减乘方法BigDecimal anew BigDecimal(1.35); BigDecimal bnew BigDecimal(3.22); //加法 add() BigDecimal addReta.add(b); System.out.println(addRet); // 4.57 // 减法 subtract() BigDecimal subReta.subtract(b); System.out.println(subRet); //-1.87 // 乘法 multiply() BigDecimal mulReta.multiply(b); System.out.println(mulRet); // 4.3470核心重点1BigDecimal 是不可变类2a.add(b)不是修改对象a的值会返回一个全新 BigDecimal 对象原来的a、b保持不变三个方法说明BigDecimal divide () 除法报错代码错误写法BigDecimal anew BigDecimal(1.35); BigDecimal bnew BigDecimal(3.22); BigDecimal divReta.divide(b); System.out.println(divRet);报错原因a.divide(b) 不带保留位数参数时要求除法结果必须是有限小数方案一指定小数位数 舍入模式最常用BigDecimal anew BigDecimal(1.35); BigDecimal bnew BigDecimal(3.22); //参数1除数 参数2保留小数位数 参数3 : 舍入模式 BigDecimal divReta.divide(b,4, RoundingMode.HALF_DOWN); System.out.println(divRet);14结果保留4 位小数2RoundingMode.HALF_UP四舍五入0.5 向上进 1财务开发最常用3注意除法顺序a.divide(b) 代表 a ÷ b全部舍入模式对照表面试重点银行家舍入 HALF_EVEN很多框架默认用这个不是传统四舍五入方案二MathContext 方式BigDecimal anew BigDecimal(1.35); BigDecimal bnew BigDecimal(3.22); // MathContext第一个参数是 [有效数字位数] 不是小数位数 BigDecimal divReta.divide(b,new MathContext(4,RoundingMode.HALF_UP)); // 0.4193 System.out.println(divRet);区分重点1divide(b, 4, HALF_UP)保留 4 位小数scale42MathContext(4,HALF_UP)总共保留 4 位有效数字precision4例123.45保留 4 位有效数字 →123.5和小数位数不是一回事除法核心总结1写 BigDecimal 除法严禁直接写a.divide(b)无限小数直接抛异常2业务开发金额计算优先用三参数divide(除数,保留小数位数, RoundingMode.HALF_UP)3分清「小数位数 scale」和「有效数字 precision」4BigDecimal 不可变除法返回新对象原对象不变BigDecimal 比较compareTo()面试高频考点不要用不要直接用equals()优先使用compareTo()错误示例1例1 equals() 同时比较【数值 小数位数scale】BigDecimal num1new BigDecimal(2.0); BigDecimal num2new BigDecimal(2); System.out.println(num1.equals(num2)); // false原因anum1的值是2.0scale11 位小数bnum2的值是2scale00 位小数cequals会把数字大小和小数位数一起对比虽然数值相等但小数位数不一样返回 false2例2 比较对象地址判断是不是同一个对象不是比较数值基本永远不适合 BigDecimal 数值对比正确方法compareTo()BigDecimal num1 new BigDecimal(2.0); BigDecimal num2 new BigDecimal(2); BigDecimal num3new BigDecimal(3); int resultnum1.compareTo(num2); // 0 System.out.println(result); System.out.println(num1.compareTo(num3)); // -1 num1 num3 System.out.println(num3.compareTo(num1)); // 1 num3 num1 System.out.println(num1.compareTo(num2)); // 0 num1num2返回值规则aresult 0→两个数字大小相等忽略小数位数bresult 0→num1 num2cresult 0→num1 num2业务常用封装写法BigDecimal anew BigDecimal(10.0); BigDecimal bnew BigDecimal(5); if(a.compareTo(b)0) { System.out.println(a大于b); } else if(a.compareTo(b)0) { System.out.println(a小于b); } else { System.out.println(a等于b); }拓展小知识点BigDecimal.ZERO开发中经常和 0 比较推荐用常量BigDecimal money new BigDecimal(0.00); if(money.compareTo(BigDecimal.ZERO) 0){ System.out.println(金额等于0); }内置常量还有aBigDecimal.ZERO0bBigDecimal.ONE1cBigDecimal.TEN10总结1equals()比较数值 小数位数2compareTo()只比较数值大小业务开发比较 BigDecimal 数值必须用compareTo()