LocalDateTime 表示没有时区的日期时间,一般表示:年月日时分秒,不可变并且线程安全。
LocalDate 表示没有时区的日期时间,一般表示:年月日,不可变并且线程安全。
LocalTime 表示没有时区的日期时间,一般表示:时分秒,不可变并且线程安全。
ZoneId 时区的Id
ZonedDateTime 具有时区的日期时间,存储所有日期和时间字段,精度为纳秒,时区为区域偏移量,用于处理模糊的本地日期时间。
Instant 对时间轴上的单一瞬时点建模,表示时间线上的一个点(瞬时),主要用于Date和我们新的日期api之间相互转换
Duration 表示一段时间,可用于计算两个时间(时分秒等)间隔
Period 表示一段时间,可用于计算两个日期(年月日等)间隔
我们主要围绕LocalDate、LocalTime、LocalDateTime三个基础对象来进行演示
LocalDateTime localDateTime = LocalDateTime.now(); LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); ZonedDateTime zonedDateTime = ZonedDateTime.now(); Instant instant = Instant.now(); Year year = Year.now(); YearMonth yearMonth = YearMonth.now(); MonthDay monthDay = MonthDay.now(); System.out.println("localDateTime:" + localDateTime); System.out.println("localDate:" + localDate); System.out.println("localTime:" + localTime); System.out.println("zonedDateTime:" + zonedDateTime); System.out.println("instant:" + instant); System.out.println("year:" + year); System.out.println("yearMonth:" + yearMonth); System.out.println("monthDay:" + monthDay); ---控制台输出--- localDateTime:2021-09-21T20:49:56.544 localDate:2021-09-21 localTime:20:49:56.544 zonedDateTime:2021-09-21T20:49:56.544+08:00[Asia/Shanghai] instant:2021-09-21T12:49:56.545Z year:2021 yearMonth:2021-09 monthDay:--09-21
LocalDateTime localDateTime = LocalDateTime.of(2021, 9, 21, 6, 30, 10); LocalDate localDate = LocalDate.of(2021, 9, 21); LocalTime localTime = LocalTime.of(6, 30, 10); System.out.println("localDateTime:" + localDateTime); System.out.println("localDate:" + localDate); System.out.println("localTime:" + localTime); //其中LocalDateTime可以传入localDate和localTime来创建 LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime); System.out.println("localDateTime2:" + localDateTime2); ---控制台输出--- localDateTime:2021-09-21T06:30:10 localDate:2021-09-21 localTime:06:30:10 localDateTime2:2021-09-21T06:30:10
Set<String> setZondId = ZoneId.getAvailableZoneIds(); setZondId.stream().forEach(System.out::println);
同时也提供了获取当前系统默认的时区的方式
ZoneId zoneId = ZoneId.systemDefault(); //控制台输出:Asia/Shanghai System.out.println(zoneId);
我们可以通过给LocalDateTime添加时区查看不同时区的时间。比如我们想获取上海和东京的时间
LocalDateTime now = LocalDateTime.now(); // 使用atZone添加时区 ZonedDateTime zonedDateTime = now.atZone(ZoneId.of("Asia/Shanghai")); // ZonedDateTime的withZoneSameInstant()方法可以更改时区 ZonedDateTime zonedDateTime2 = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo")); System.out.println("Asia/Shanghai:" + zonedDateTime); System.out.println("Asia/Tokyo:" + zonedDateTime2); ---控制台输出--- Asia/Shanghai:2021-09-21T21:18:13.499+08:00[Asia/Shanghai] Asia/Tokyo:2021-09-21T22:18:13.499+09:00[Asia/Tokyo]
我们可以看出东京比上海多一个小时
LocalDateTime now = LocalDateTime.now(); System.out.println("now:" + now); LocalDateTime plusYears = now.plusYears(1); LocalDateTime minusYears = now.minusYears(1); System.out.println("plusYears:" + plusYears); System.out.println("minusYears:" + minusYears); LocalDateTime plusDays = now.plusDays(10); LocalDateTime minusDays = now.minusDays(10); System.out.println("plusDays:" + plusDays); System.out.println("minusDays:" + minusDays); ---控制台输出--- now:2021-09-21T21:31:33.295 plusYears:2022-09-21T21:31:33.295 minusYears:2020-09-21T21:31:33.295 plusDays:2021-10-01T21:31:33.295 minusDays:2021-09-11T21:31:33.295
这里我们可以在plus()方法中传入负数,效果即为减少日期,minus()中传入负数即为添加日期。两个方法底层其实调用的是同一个方法。
日期的加减我们也可以使用另外一种方式,即plus(long amountToAdd, TemporalUnit unit)
LocalDateTime now = LocalDateTime.now(); System.out.println("now:" + now); LocalDateTime nextYear = now.plus(1, ChronoUnit.YEARS); LocalDateTime nextMonth = now.plus(1, ChronoUnit.MONTHS); LocalDateTime nextDay = now.plus(1, ChronoUnit.DAYS); System.out.println("nextYear:" + nextYear); System.out.println("nextMonth:" + nextMonth); System.out.println("nextDay:" + nextDay); ---控制台输出--- now:2021-09-21T21:43:19.384 nextYear:2022-09-21T21:43:19.384 nextMonth:2021-10-21T21:43:19.384 nextDay:2021-09-22T21:43:19.384
LocalDateTime now = LocalDateTime.now(); System.out.println("now:" + now); LocalDateTime withYear = now.withYear(2030); System.out.println("withYear:" + withYear); LocalDateTime withMonth = now.withMonth(6); System.out.println("withMonth:" + withMonth); ---控制台输出--- now:2021-09-21T21:48:55.118 withYear:2030-09-21T21:48:55.118 withMonth:2021-06-21T21:48:55.118
LocalDateTime now = LocalDateTime.now(); int year = now.getYear(); int monthValue = now.getMonthValue(); int dayOfMonth = now.getDayOfMonth(); int hour = now.getHour(); int minute = now.getMinute(); int second = now.getSecond(); System.out.println("year:" + year + "__month:" + monthValue + "__day" + dayOfMonth + "__hour:" + hour + "__minute:" + minute + "__second:" + second); ---控制台输出--- year:2021__month:9__day21__hour:21__minute:58__second:6
LocalDateTime date1 = LocalDateTime.of(2021, 9, 21, 10, 30, 30); LocalDateTime date2 = LocalDateTime.of(2030, 10, 28, 10, 30, 30); System.out.println("date1是否比date2日期小:" + date1.isBefore(date2)); System.out.println("date1是否比date2日期大:" + date1.isAfter(date2)); ---控制台输出--- date1是否比date2日期小:true date1是否比date2日期大:false
LocalDateTime date1 = LocalDateTime.of(2021, 9, 21, 10, 30, 30); LocalDateTime date2 = LocalDateTime.of(2025, 11, 25, 11, 30, 30); //注意此处只比较时分秒,不考虑年月日 Duration duration = Duration.between(date1.toLocalTime(), date2.toLocalTime()); System.out.println("date1和date2日期间隔" + duration.toHours() + "小时" + duration.toMinutes() + "分钟" + duration.toMillis() / 1000 + "秒"); //注意此处只比较年月日,不考虑时分秒 Period period = Period.between(date1.toLocalDate(), date2.toLocalDate()); System.out.println("date1和date2日期间隔" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天"); ---控制台输出--- date1和date2日期间隔1小时60分钟3600秒 date1和date2日期间隔4年2月4天
扩展:既然Period和Duration 表示一段时间间隔,那么我们可以在一个日期上直接添加这个日期间隔
LocalDateTime now = LocalDateTime.now(); System.out.println("now:" + now); //此处表示时间间隔为一年一个月一天 Period period = Period.of(1, 1, 1); LocalDateTime plusDate = now.plus(period); System.out.println("plusDate:" + plusDate); ---控制台输出--- now:2021-09-21T22:24:05.166 plusDate:2022-10-22T22:24:05.166
接下来是直接计算连个日期间隔的特定单位(年月日时分秒)
LocalDate date = LocalDate.of(2021, 9, 20); LocalDate date2 = LocalDate.of(2022, 10, 21); System.out.println("间隔年:" + ChronoUnit.YEARS.between(date, date2)); System.out.println("间隔月:" + ChronoUnit.MONTHS.between(date, date2)); System.out.println("间隔天:" + ChronoUnit.DAYS.between(date, date2)); ---控制台输出--- 间隔年:1 间隔月:13 间隔天:396
LocalDateTime date = LocalDateTime.of(2021, 9, 20, 10, 30, 30); //获取该日期的当月第一天 LocalDateTime with = date.with(TemporalAdjusters.firstDayOfMonth()); //获取该日期的当月最后一天 LocalDateTime with2 = date.with(TemporalAdjusters.lastDayOfMonth()); //在该日期基础上获取上一个周六 LocalDateTime with3 = date.with(TemporalAdjusters.previous(DayOfWeek.SATURDAY)); //在该日期基础上获取下一个周六 LocalDateTime with4 = date.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // LocalDateTime转字符串 LocalDateTime date = LocalDateTime.now(); String format = date.format(dateTimeFormatter); System.out.println(format); // 字符串转换LocalDateTime String formatDate = "2021-09-21 22:46:26"; LocalDateTime parse = LocalDateTime.parse(formatDate, dateTimeFormatter); System.out.println(parse);
//java.util.date转换新日期api Date now = new Date(); LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); LocalDate localDate = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalTime localTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalTime(); // localDateTime转换java.util.date Date date1 = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()); // localDate转换java.util.date Date date2 = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()); // 注意localTime转换java.util.date,必须指定年月日 Date date3 = Date.from(LocalTime.now().atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant());
用惯了旧的日期api刚接触可能不太习惯,但是,熟能生巧。加油!为了更好地自己