天天看点

Jdk8 时间和日期API介绍

在项目开发中,需要对 Date 类型进行格式,否则可读性很差,格式化 Date 类型常用类却是 SimpleDateFormat,而在多线程环境下 SimpleDateFormat 可能会出现总是想不到的问题,因为 SimpleDateFormat 是线程不安全的,在多线程下建议使用 DateTimeFormatter 格式化日期

Java8 日期和时间API中提供了3个时间类,分别是:LocalDate、LocalTime、LocalDateTime,绝大多数操作都是围绕这几个对象来进行的。

LocalDateTime与Date区别:Date有的LocalDateTime都有,Date没有的LocalDateTime也有。

下面列举的都是常用,想要了解更多请参考API文档。

LocalDate

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 = 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

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

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));      

Date与LocalDateTime转换

// 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()));      

继续阅读