Date、Calender 和SimpleDateFormat是我们在jdk8之前一直在使用的日期API,相信大家都使用的比较熟练了,也发现了它的使用中存在的一些问题。比如说,直接指定一个年月日通过Date类构造日期,打印后发现是错的日期,尤其是年很离谱,所以
@Deprecated
public Date(int year, int month, int date) {
this(year, month, date, 0, 0, 0);
}
这个方法也被标记为过期了。再则,使用Calender 使用它获得的月份是从0开始的,很不符合国人的习惯;还有SimpleDateFormat是线程不安全的,在多线程场景下,会解析错误或者直接抛异常了。
也是由于这些零碎的各种原因,jdk8推出了新的日期API.新的API单独放在了java.time包下。主要类有LocalDate、LocalTime、LocalDateTime,分别用来表示,日期(yyyy-MM-dd)、时间(HH:mm:ss)、日期时间(yyyy-MM-dd HH:mm:ss).接下里,我们具体看一下这些类的使用。
LocalDate date = LocalDate.of(2023, 5, 6); // 2022-05-06
就是这么简单,一个of搞定
LocalDate date = LocalDate.now(); //2023-09-20
int year = date .getYear(); // 获取到年份
Month month = date.getMonth(); // 获取到月份
int dayOfMonth = date.getDayOfMonth(); // 获取到天
DayOfWeek dayOfWeek = date2.getDayOfWeek(); // 获取到星期几
月份、和星期都是枚举,使用的时候,使用getValue()拿到值
有没有发现,System.out.println(date);打印的结果是直接格式化好的,简直太舒服了
LocalTime time = LocalTime.of(5, 26, 33, 23145); //05:26:33.000023145
LocalTime now = LocalTime.now(); // 15:07:08.959
int hour = now.getHour(); // 获取小时
int minute = now.getMinute(); // 获取分钟
int second = now.getSecond(); // 获取秒
int nano = now.getNano(); // 获取纳秒
LocalDateTime dateTime = LocalDateTime.of(2028, 6, 1, 12, 12, 33, 1111); // 2023-09-20T15:11:23.656
LocalDateTime now = LocalDateTime.now();
int year = now.getYear(); // 获取年份
Month month = now.getMonth(); // 获取月份
int dayOfMonth = now.getDayOfMonth(); // 获取日
DayOfWeek dayOfWeek = now.getDayOfWeek(); // 获取第几周
int hour = now.getHour(); // 获取小时
int minute = now.getMinute(); // 获取分钟
int second = now.getSecond(); // 获取秒
int nano = now.getNano(); // 获取纳秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 修改日期时间 对日期时间的修改,对于已存在的LocalDateTime,创建了它的模版,
// 不会修改原来创建的日期时间,会新创建一个LocalDateTime 对象
LocalDateTime localDateTime = now.withYear(1998); // 直接将当前年份修改为1998年
System.out.println(now);
System.out.println(localDateTime);
// 直接修改到指定的时间
System.out.println(now.withMonth(10)); // 直接将当前年份改为10月份
System.out.println(now.withDayOfMonth(6)); // 直接将当前日改为6日
System.out.println(now.withMinute(15)); // 直接将分钟改为15分钟
// 对当前日期时间的基础上,加上或者减去指定的时间
System.out.println(now.plusDays(2)); // 加两天 ,两天后
System.out.println(now.plusYears(10)); // 加10年 ,十年后
System.out.println(now.plusMonths(6)); // 加6个月 ,6个月后
System.out.println(now.minusYears(10)); // 减去10年 10年前
System.out.println(now.minusMonths(6)); // 减去6个月 半年前
System.out.println(now.minusDays(7)); // 减去7天 一周前
有没有发现,日期时间的加减变的非常的方便,直接有对应的方法进行操作,不用在使用Calender 类进行操作了。
LocalDate now = LocalDate.now();
LocalDate date = LocalDate.of(2020, 1, 1);
// 在Jdk8中实现日期的比较 now.isAfter(date)
System.out.println(now.isAfter(date)); // now 在date之后吗 在返回true,不在返回false
System.out.println(now.isBefore(date)); // now在date之前吗? 在返回true ,不在返回false
System.out.println(now.isEqual(date)); // now和date相等吗
日期的比较也变得相当简单,也有对应的方法,主要是要弄明白方法的含义,例如:a.isAfter(b) 表示a日期是在b日期的后边吗?
LocalDateTime now = LocalDateTime.now();
// 指定格式 使用系统默认的格式
DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
// 将日期时间转换成字符串
String format = now.format(isoLocalDateTime);
System.out.println(format); // 2023-09-19T10:50:44.171
// 通过ofPattern 方法来指定特定的格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format1 = now.format(dateTimeFormatter); // 2023-09-20 15:23:39
System.out.println(format1);
// 将字符串解析为一个日期时间类
LocalDateTime parse = LocalDateTime.parse("2023-09-19 16:22:56", dateTimeFormatter);
System.out.println(parse); // 2023-09-19T16:22:56
在jdk8中新增的一个时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒
Instant now = Instant.now();
System.out.println(now); // 2023-09-20T07:27:20.103Z
// 获取从1970年一月一日 00:00:00 到现在的纳秒
System.out.println(now.getNano()); // 103000000
Thread.sleep(5); // 5毫秒
Instant now1 = Instant.now();
System.out.println(now1.getNano() - now.getNano()); //39000000
Instant now = Instant.now();也可以获取到当前的日期时间,但是它没有获取年、月、日、时分秒的方法。只能获取到纳秒或秒
用来计算日期时间的差
Duration: 用来计算两个时间差(LocalTIme)
Period: 用来计算两个日期差(LocalDate)
LocalTime now = LocalTime.now();
LocalTime time = LocalTime.of(22, 48, 59);
System.out.println(now); //11:15:22.162
Duration duration = Duration.between(now, time);
System.out.println(duration.toDays()); // 获取相差的天数
System.out.println(duration.toHours()); // 获取相差的小时
System.out.println(duration.toMinutes()); // 获取相差的分钟
System.out.println(duration.toMillis()); // 获取相差的毫秒
LocalDate nowDate = LocalDate.now();
System.out.println(nowDate); // 2023-09-19
LocalDate date = LocalDate.of(1997, 12, 5);
Period period = Period.between(date, nowDate);
System.out.println(period.getYears()); // 25
System.out.println(period.getMonths()); // 9 为什么是9呢,因为Period.between(date, nowDate);方法是通过后边的(nowDate)减去前边的(date),这样nowDate时间大,在后边,1997在前边,9月往前数到前一年的12月,刚好是差9个月
System.out.println(period.getDays()); // 14
TemporalAdjuster: 时间矫正器
TemporalAdjusters :通过该类的静态方法提供了大量的常用的TemporalAdjuster实现。
有时候我们可能需要如下调整: 将日期调整到“下个月的第一天”等操作。这时我们通过时间矫正器效果可能会更好。
LocalDateTime now = LocalDateTime.now();
// 将当期的日期调整到下个月的一号
TemporalAdjuster adjuster = (temporal) -> {
LocalDateTime dateTime = (LocalDateTime) temporal;
LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
return nextMonth;
};
LocalDateTime nextMonth = now.with(adjuster);
System.out.println(nextMonth);
LocalDateTime nextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println(nextMonth);
TemporalAdjusters 还有很多静态方法,用到的时候,大家自行选择就好。
1、ava8加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别为:
ZoneDate、ZoneTime、ZoneDateTime
2、其中每个时区都对应着ID,ID的格式为“区域/城市”。例如:Asia/Shanghai等。
3、ZoneId:该类中包含了所有时区信息。
// 时区操作
// 1、获取所有的时区id
ZoneId.getAvailableZoneIds().forEach(System.out::println);
// 获取当前时间 中国使用的 是东八区的时区,比标准时间晚8个小时
LocalDateTime now = LocalDateTime.now();
System.out.println(now);// 2023-09-19T15:52:27.673
// 获取标准时间
ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
System.out.println(bz);//2023-09-19T07:52:27.673Z
// 使用计算机默认的时区,创建日期时间
ZonedDateTime now1 = ZonedDateTime.now();
System.out.println(now1); //2023-09-19T15:52:27.673+08:00[Asia/Shanghai]
// 使用指定的时区创建日期时间
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Marigot"));
System.out.println(now2);
由于在国内,计算机默认时区则是东八区(Asia/Shanghai)所以,我们平时开发,不用关注时区的事情,当在国际化项目开中则需要留意时区的问题。
如果能读到这里,也会有一个直观的感受,新的日期API规律性很强,见文知意,不用特意记忆,读一遍后也能了解个大概,也知道获取个当前的日期时间,该怎么做了,这个便是API的魅力所在。
回顾下常用API:
LocalDate now = LocalDate.now();
LocalTime now = LocalTime.now();
LocalDateTime now = LocalDateTime.now();
在加一个日期时间格式化器,就基本够用了
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
String format = now.format(dateTimeFormatter);