Java8新特性 之时间工具类

简述新的日期时间API

Java 的日期与时间 API 问题由来已久,Java 8 之前的版本中关于时间、日期及其他时间日期格式化类由于线程安全、重量级、序列化成本高等问题而饱受批评。Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。新的 java.time 中包含了所有关于时钟(Clock),本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。
历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简化了了日期时间和本地化的管理。

目前Java8新增了java.time包定义的类表示日期-时间概念的规则,很方便使用;最重要的一点是值不可变,且线程安全。

  • LocalDate:本地日期类,只有年月日
  • LocalTime:本地时间类,只有时分秒
  • LocalDateTime:本地日期时间类,包含年月日时分秒
  • MonthDay:月日
  • YearMonth:年月
  • ZoneId:时区

下图是java.time包下的一些主要的类的日期时间 值的格式,方便理解使用:
在这里插入图片描述

Note: 不过尽管有了新的API,但仍有一个严重的问题——大量的旧代码和库仍然在使用老的API。现在,Java 8解决了这个问题,它给Date类增加了一个新的方法toInstant(),可以将Date转化成新的实例。这样就可以切换到新的API。

获取时区

ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId.toString());
zoneId = ZoneId.of("Asia/Shanghai");
System.out.println(zoneId.toString());
zoneId = TimeZone.getTimeZone("CTT").toZoneId();
System.out.println(zoneId.toString());

结果:
Asia/Shanghai
Asia/Shanghai
Asia/Shanghai

获取日期时间

// 日期
LocalDate date = LocalDate.parse("20191011", DateTimeFormatter.ofPattern("yyyyMMdd"));
LocalDate date = LocalDate.of(2019, 10, 11); // 年 月 日
LocalDate nowDate = LocalDate.now();
// 时间
LocalTime time = LocalTime.parse("151210", DateTimeFormatter.ofPattern("HHmmss"));
LocalTime time = LocalTime.of(22, 12, 18); // 时 分 秒
LocalTime nowTime = LocalTime.now();
System.out.println(date);
System.out.println(time);
// 日期时间
LocalDateTime dateTime = LocalDateTime.of(2014, 3, 16, 13, 20, 22); // 年 月 日 时 分 秒
LocalDateTime dateTime1 = LocalDateTime.of(date, time);
LocalDateTime dateTime2 = LocalDateTime.parse("20191011150012", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("---黄金分割线---");
System.out.println(dateTime1);
System.out.println(dateTime2);

在这里插入图片描述

获取具体的日期时间字段值

LocalDateTime dateTime = LocalDateTime.of(2019, 3, 10, 15, 30, 59);
System.out.println(dateTime);
System.out.println(dateTime.getYear()); // 年
System.out.println(dateTime.getMonthValue()); // 月
System.out.println(dateTime.getDayOfMonth()); // 日
System.out.println(dateTime.getHour()); // 时
System.out.println(dateTime.getMinute()); // 分
System.out.println(dateTime.getSecond()); // 秒
System.out.println(dateTime.getDayOfWeek()); // 星期几

在这里插入图片描述

日期时间格式化输出

DateTimeFormatter是不可变的,所以它是线程安全的。

LocalDate today = LocalDate.now();
System.out.println(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));

LocalTime time = LocalTime.now();
System.out.println("---黄金分割线---");
//24小时制
System.out.println(time.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
//12小时制
System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss")));

LocalDateTime now = LocalDateTime.of(today,time);
System.out.println("---黄金分割线---");
//yyyyMMdd
System.out.println(now.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println(now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));

在这里插入图片描述

字符串转日期时间

LocalDate date = LocalDate.parse("20191011", DateTimeFormatter.ofPattern("yyyyMMdd"));
LocalTime time = LocalTime.parse("151210", DateTimeFormatter.ofPattern("HHmmss"));
LocalDateTime dateTime = LocalDateTime.parse("20191011150012", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

LocalDateTime与Date的转换

Instant 时间点对象可以很容易的转换为老式的 java.util.Date

LocalDateTime dateTime = LocalDateTime.of(2019, 3, 10, 15, 30, 59);
Instant instant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
//LocalDateTime 转 Date
Date date = Date.from(instant);
System.out.println(date);

//Date 转 LocalDateTime
instant = date.toInstant();
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(localDateTime);

LocalDateTime与时间戳的转换

LocalDateTime localDateTime = LocalDateTime.now();
// LocalDateTime 转秒级时间戳
long timeStamp = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
System.out.println(timeStamp);
timeStamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
System.out.println(timeStamp);
// 秒级时间戳转 LocalDateTime
LocalDateTime dateTime = Instant.ofEpochSecond(timeStamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(dateTime);

// LocalDateTime 转毫秒级时间戳
timeStamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
System.out.println("---黄金分割线---");
System.out.println(timeStamp);
// 毫秒级时间戳转 LocalDateTime
dateTime = Instant.ofEpochMilli(timeStamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(dateTime);

在这里插入图片描述

时间调整到特定某天

LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//同月的第一天
LocalDateTime firstDayInSameMonthOfNow = now.withDayOfMonth(1);
System.out.println(firstDayInSameMonthOfNow);
//同年的第一天
LocalDateTime firstDayInSameYearOfNow = now.withDayOfYear(1);
System.out.println(firstDayInSameYearOfNow);
//同年的第2月第10天
LocalDateTime time = now.withMonth(2).withDayOfMonth(10);
System.out.println(time);
//当天的6点10分15秒整
time = now.withHour(6).withMinute(10).withSecond(15).withNano(0);
System.out.println(time);

在这里插入图片描述

Duration一个时间段

// Duration.between()方法创建 Duration 对象
LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 1, 00, 0, 0);    // 2017-01-01 00:00:00
LocalDateTime to = LocalDateTime.of(2019, Month.SEPTEMBER, 12, 14, 28, 0);     // 2019-09-15 14:28:00
Duration duration = Duration.between(from, to);     // 表示从 from 到 to 这段时间
long days = duration.toDays();              // 这段时间的总天数
long hours = duration.toHours();            // 这段时间的小时数
long minutes = duration.toMinutes();        // 这段时间的分钟数
long seconds = duration.getSeconds();       // 这段时间的秒数
long milliSeconds = duration.toMillis();    // 这段时间的毫秒数
long nanoSeconds = duration.toNanos();      // 这段时间的纳秒数

LocalDateTime from = LocalDateTime.of(2019, 3, 10, 15, 30, 59);
LocalDateTime to = LocalDateTime.of(2019, 3, 15, 15, 30, 59);
Duration duration = Duration.between(from, to);
System.out.println(duration.compareTo(Duration.ofDays(2)));
System.out.println(duration.compareTo(Duration.ofDays(10)));
System.out.println("Duration in days: " + duration.toDays());
System.out.println("Duration in hours: " + duration.toHours());

在这里插入图片描述

增加、减少年数、月数、天数、小时、分钟、秒

plus开头的方法都是增加日期时间的。
minus开头的方法都是增加日期时间的。
with开头的方法都是直接修改到指定值。

LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 12, 14, 32, 0);
// 增加一年
localDateTime = localDateTime.plusYears(1);
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
// 减少一个月
localDateTime = localDateTime.minusMonths(1);
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);  
// 通过with修改某些值
// 修改年为2020
localDateTime = localDateTime.withYear(2020);
localDateTime = localDateTime.with(ChronoField.YEAR, 2020);

判断今天是否是生日

LocalDate now = LocalDate.now();
LocalDate birthday = LocalDate.of(1991, 10, 12);
MonthDay birthdayMonthDay = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());
MonthDay nowMonthDay = MonthDay.from(now);
System.out.println(birthdayMonthDay.equals(nowMonthDay));

判断某个日期在另一个日期的前面还是后面

  • isBefore():如果调用方法的那个日期比给定的日期要早的话,方法会返回true。
  • isAfter():如果调用方法的那个日期比给定的日期晚的话,方法会返回true。
  • isEqual():如果调用方法的那个日期比给定的日期相等的话,方法会返回true。

检查闰年

LocalDate类由一个isLeapYear()方法来返回当前LocalDate对应的那年是否是闰年。

获取今年的天数

// 获取今年的天数
int daysOfThisYear = LocalDate.now().lengthOfYear();
// 获取指定某年的天数
LocalDate.of(2011, 1, 1).lengthOfYear();

获取日期的开始和结束时间

获取当前月的第一天和最后一天

使用TemporalAdjusters方法实现。

LocalDate date = LocalDate.now();
LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth()); 	// 获取当前月的第一天
LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth()); 		// 获取当前月的最后一天
System.out.println(date);		// 2021-11-11
System.out.println(firstDay);	// 2021-11-01
System.out.println(lastDay);	// 2021-11-30
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值