在项目开发中,需要对 Date 类型进行格式,否则可读性很差,格式化 Date 类型常用类却是 SimpleDateFormat,而在多线程环境下 SimpleDateFormat 可能会出现总是想不到的问题,因为 SimpleDateFormat 是线程不安全的,在多线程下建议使用 DateTimeFormatter 格式化日期
Java8 日期和时间API中提供了3个时间类,分别是:LocalDate、LocalTime、LocalDateTime,绝大多数操作都是围绕这几个对象来进行的。
LocalDateTime与Date区别:Date有的LocalDateTime都有,Date没有的LocalDateTime也有。
下面列举的都是常用,想要了解更多请参考API文档。
LocalDate 是日期处理类,只含年月日的日期对象,LocalDate是不可变并且线程安全的。常用操作如下:
- // 获取当前日期
- LocalDate localDate = LocalDate.now();
- System.out.println(localDate);
-
- // 根据指定日期/时间创建对象
- localDate = LocalDate.of(2022, 8, 3);
- System.out.println(localDate);
-
- // 获取年
- System.out.println(localDate.getYear());
- System.out.println(localDate.get(ChronoField.YEAR));
-
- // 获取月
- System.out.println(localDate.getMonth());
- System.out.println(localDate.get(ChronoField.MONTH_OF_YEAR));
-
- // 获取日
- System.out.println(localDate.getDayOfMonth());
- System.out.println(localDate.get(ChronoField.DAY_OF_MONTH));
-
- // 获取星期
- System.out.println(localDate.getDayOfWeek());
- System.out.println(localDate.getDayOfWeek().getValue());
- System.out.println(localDate.get(ChronoField.DAY_OF_WEEK));
-
- // 在当前时间基础上指定本年中的第几天,取值范围1-366
- System.out.println(localDate.withDayOfYear(10));
- // 在当前时间基础上指定本月中的第几天,取值范围1-31
- System.out.println(localDate.withDayOfMonth(20));
LocalTime 是时间处理类,只含时分秒的时间对象,LocalTime是不可变并且线程安全的。常用操作如下:
- // 获取当前时间
- LocalTime localTime = LocalTime.now();
- System.out.println(localTime);
-
- // 设置时间
- localTime = LocalTime.of(13, 51, 10);
- System.out.println(localTime);
-
- //获取小时
- System.out.println(localTime.getHour());
- System.out.println(localTime.get(ChronoField.HOUR_OF_DAY));
-
- //获取分
- System.out.println(localTime.getMinute());
- System.out.println(localTime.get(ChronoField.MINUTE_OF_HOUR));
-
- //获取秒
- System.out.println(localTime.getSecond());
- System.out.println(localTime.get(ChronoField.SECOND_OF_MINUTE));
LocalDateTime 可以设置年月日时分秒,同时含有年月日时分秒的日期对象,相当于LocalDate + LocalTime;LocalDateTime是不可变并且线程安全的。常用操作如下:
- // 获取当前日期时间
- LocalDateTime localDateTime = LocalDateTime.now();
- System.out.println(localDateTime);
-
- // 获取LocalDate
- LocalDate localDate = localDateTime.toLocalDate();
- System.out.println(localDate);
-
- // 获取LocalTime
- LocalTime localTime = localDateTime.toLocalTime();
- System.out.println(localTime);
-
- // 设置日期
- localDateTime = LocalDateTime.of(2022, 8, 10, 14, 46, 56);
- System.out.println(localDateTime);
-
- localDateTime = LocalDateTime.of(localDate, localTime);
- System.out.println(localDateTime);
-
- // 日期时间的加减
- System.out.println(localDateTime.plusYears(2L));
- System.out.println(localDateTime.plus(2, ChronoUnit.MONTHS));
-
- // 获取日期的年月日周
- System.out.println(localDateTime.getDayOfYear());
- System.out.println(localDateTime.getDayOfMonth());
- System.out.println(localDateTime.getDayOfWeek().getValue());
-
- //增加一年
- System.out.println(localDateTime.plusYears(1));
- System.out.println(localDateTime.plus(1, ChronoUnit.YEARS));
- //减少一个月
- System.out.println(localDateTime.minusMonths(1));
- System.out.println(localDateTime.minus(1, ChronoUnit.MONTHS));
-
-
- // 修改年
- System.out.println(localDateTime.withYear(2021));
- System.out.println(localDateTime.with(ChronoField.YEAR, 2022));
-
- // 日期计算
- // 通过 TemporalAdjusters 类提供的方法获取年月周的开始和结束时间,
- LocalDate localDate1 = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
- System.out.println(localDate1);
-
- // 格式化时间
- localDate = LocalDate.of(2019, 9, 10);
- System.out.println(localDate.format(DateTimeFormatter.BASIC_ISO_DATE));
- System.out.println(localDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
-
- //自定义格式化
- DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- System.out.println(localDate.format(dateTimeFormatter));
-
- // 解析时间
- System.out.println(LocalDate.parse("20220803", DateTimeFormatter.BASIC_ISO_DATE));
- System.out.println(LocalDate.parse("2021-08-03", DateTimeFormatter.ISO_LOCAL_DATE));
Duration 用于计算两个日期的“时间”间隔。常用操作如下:
- // 计算两个时间的间隔
- LocalDateTime localDateTime1 = LocalDateTime.now();
- LocalDateTime localDateTime2 = LocalDateTime.of(2022, 5, 13, 22, 30, 10);
-
- Duration duration = Duration.between(localDateTime1, localDateTime2);
-
- System.out.println(" 天 :" + duration.toDays());
- System.out.println(" 时 :" + duration.toHours());
- System.out.println(" 分 :" + duration.toMinutes());
- System.out.println(" 毫秒 :" + duration.toMillis());
注意:并没有获得秒差的,可以通过分或毫秒转换得到。
Period 用于计算两个“日期”间隔。常用操作如下:
- // 计算两个日期的间隔
- LocalDate localDate1 = LocalDate.of(2022, 5, 20);
- LocalDate localDate2 = LocalDate.of(2022, 8, 3);
-
- // 内部是用date2-date1,所以得到的结果是负数
- Period period = Period.between(localDate1, localDate2);
-
- System.out.println("相差年数 : " + period.getYears());
- System.out.println("相差月数 : " + period.getMonths());
- System.out.println("相差日数 : " + period.getDays());
- // 或
- System.out.println("相差年数 : " + period.get(ChronoUnit.YEARS));
- System.out.println("相差月数 : " + period.get(ChronoUnit.MONTHS));
- System.out.println("相差日数 : " + period.get(ChronoUnit.DAYS));
注意:当获取两个日期的间隔时,并不是年月日对应的数字相加减,而是会先算出具体差多少天,在折算成相差几年几月几日。
- // datetime转字符串
- String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- System.out.println(format);
-
- // 字符串转datetime
- LocalDateTime localDateTime = LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- System.out.println(localDateTime);
-
- // LocalDateTime转date
- Date date1 = Date.from(localDateTime.toInstant(ZoneOffset.ofHours(8)));
- System.out.println(date1);
-
- Date date2 = Date.from(Instant.from(localDateTime.atZone(ZoneId.systemDefault())));
- System.out.println(date2);
-
- Date date3 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
- System.out.println(date3);
- System.out.println();
-
- // date转LocalDateTime
- LocalDateTime localDateTime1 = date1.toInstant().atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
- System.out.println(localDateTime1);
-
- LocalDateTime localDateTime2 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
- System.out.println(localDateTime2);
-
- // LocalDateTime转毫秒时间戳
- Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
- long timestamp = instant.toEpochMilli();
- System.out.println(timestamp);
-
- // 时间戳转LocalDateTime
- System.out.println(LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()));