jdk8的时间日期类
Date
Date默认是以UTC为时区,不过在print打印,和格式化输出的时候会根据默认时区进行输出
java.util.Date 表示某个时刻的时间对像常用的构造方法:
// 无参构造,根据当前的时间戳进行构造Date对象
Date date = new Date();
System.out.println(date); // Wed Jul 27 10:14:22 CST 2022
// 根据具体的长整型数值(表示从1970年1月1日00:00:00 开始经历具体毫秒熟)构造Date对象
long timeStamp = 12354874556L;
Date date1 = new Date(timeStamp);
System.out.println(date1); // Sun May 24 07:54:34 CST 1970
可以看到Date对象的toString()方法显示的时间格式和我们习惯的格式很不一样,这一般需要与 SimpleDateFormat 配合使用
- 常用的方法:
getTime() | 获取当前Date对象对应的时间戳 (毫秒) |
---|---|
setTime(Long timeStamp) | 将Date中的时间戳改变成新的时间戳(毫秒) |
before(Date date) | 判断当前对象是否比date早 |
after(Date date) | 判断当前对象是否比date晚 |
compareTo(Date date) | 当前对象与date进行比较,返回1则比date晚,返回-1比date早 |
Date date = new Date();
System.out.println(date); // Wed Jul 27 10:35:42 CST 2022
System.out.println(date.getTime()); // 1658889383637
date.setTime(547845588894L);
System.out.println(date); // Wed May 13 04:19:48 CDT 1987
System.out.println(date.getTime()); // 547845588894
Date date1 = new Date();
Date date2 = new Date();
date2.setTime(1658889383637L);
System.out.println(date1.before(date2)); // false
System.out.println(date1.after(date2)); // true
System.out.println(date1.compareTo(date2)); // 1 说明date1时间晚于date2
System.out.println(date2.compareTo(date1)); // -1 说明date2时间早于date1
- 判断两个时期谁在前谁在后,只需要用到before、after、compareTo中的一个即可。不需要都记住
SimpleDateFormat
虽然Date对象能够表示一个时刻,但是我们对时间最常用的方式是能够让时间能够用字符串的形式显示出来,但是Date的toString方法显示的格式太丑了,而且有时候我们创建一个时间对象的时候,经常性的会通过字符串转换成Date对象,而Date中没有相应的方法,这时候就需要一个SimpleDateFormat来在Date对象与字符串之间进行转换。即可以将Date对象转换成我们想要格式的字符串,同时也可以通过对应格式的时间字符串转换成Date对象。
// 指定日期时间的格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
// 原始date的时间格式
System.out.println(date); // Wed Jul 27 11:11:51 CST 2022
String format = simpleDateFormat.format(date);
// 经过格式化后的时间字符串
System.out.println(format); // 2022-07-27 11:11:51
try {
// 将对应时间格式的字符串转换成Date对象
Date parse = simpleDateFormat.parse("2022-10-12 12:20:11");
System.out.println(parse);
} catch (ParseException e) {
e.printStackTrace();
}
其实parse、format方法是DateFormat中的方法,DateFormat是一个抽象类,SimpleDateFormat是DateFormat的子类
- 总结: 其实一般的对于日期简单操作,都可以通过Date和SimpleDateFormat这两个类进行,更加复杂的操作比如获得日期中的年月日,时分秒,判断当前日期是当前月的第几天,当前日期是星期几等,这些操作以前是通过Calendar类来操作。
- 但是SimpleDateFormat和Calendar是线程不安全的。后面jdk8以后添加了LocalDate、LocalTime、LocalDateTime、Instant、period、等类,因此不再使用Calendar,改用新的时间类
LocalDateTime、 LocalTime 、LocalDate
在jdk8 加入很多新的日期、时间类,这些类都是不可变,线程安全的类。且在构造的时候会以默认时区(本地时区)构造好之后,不会保留时区信息
- LocalDate : 只含年月日的日期对象
- LocalTime :只含时分秒的时间对象
- LocalDateTime : 同时含有年月日时分秒的日期对象
1. 构造对应的时间日期对象
// 根据当前时间构造时间对象 // toString() 显示
LocalTime localTime = LocalTime.now(); // 11:37:10.535
LocalDate localDate = LocalDate.now(); // 2022-07-27
LocalDateTime localDateTime = LocalDateTime.now(); // 2022-07-27T11:37:10.536
// 根据指定时间日期进行构造
LocalTime localTime = LocalTime.of(11, 50, 30); // 11:50:30
LocalDate localDate = LocalDate.of(2022, 7, 27); // 2022-07-27
LocalDateTime localDateTime = LocalDateTime.of(2022, 7, 27, 13, 48, 15); // 2022-07-27T13:48:15
// 根据Instant进行构造
Instant now = Instant.now();
// Instant 是没有带时区的,
LocalDateTime localDateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault()); // 2022-07-27T17:09:12.739
// 也可以根据时间戳(以世界时间1970-01-01 00:00:00基础)先构造Instant,然后再构造成时间日期对象
Instant instant = Instant.ofEpochSecond(1545121254L); // 根据秒来换算
//Instant instant = Instant.ofEpochMilli(1545121254000L); // 根据毫秒数来换算
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println(localDateTime1); // 2018-12-18T16:20:54
2. 日期的加减
LocalDateTime、LocalTime、LocalDate 对象可以进行链式调用
/**
* 将原有的日期/时间 进行加减
* 对于LocalDate,只有精度大于或等于日的加减,如年、月、日;
* 对于LocalTime,只有精度小于或等于时的加减,如时、分、秒、纳秒;
* 对于LocalDateTime,则可以进行任意精度的时间相加减;
*/
LocalDateTime localDateTime = LocalDateTime.of(2022, 7, 27, 13, 48, 15);
// 时间往后面调整一年,2个月, 3天,4小时,5分钟,6秒钟
LocalDateTime newTime = localDateTime.plusYears(1L)
.plusMonths(2)
.plusDays(3)
.plusHours(4)
.plusMinutes(5)
.plusSeconds(6);
System.out.println(newTime); // 2023-09-30T17:53:21
// 也可以通过另一种方式进行加减
LocalDateTime newTime1 = newTime.plus(-1, ChronoUnit.YEARS)
.plus(-2, ChronoUnit.MONTHS)
.plus(-3, ChronoUnit.DAYS)
.plus(-4, ChronoUnit.HOURS)
.plus(-5, ChronoUnit.MINUTES)
.plus(-6, ChronoUnit.SECONDS);
System.out.println(newTime1); // 2022-07-27T13:48:15
3. 将年月日、时分秒修改后返回新的对象
LocalDateTime localDateTime = LocalDateTime.now();
// 将天日期中的天改为一个月中的第几天,或者一年中的第几天
LocalDateTime localDateTime1 = localDateTime.withDayOfMonth(10);
System.out.println(localDateTime); // 2022-07-27T14:15:08.813
System.out.println(localDateTime1); // 2022-07-10T14:15:08.813
LocalDateTime localDateTime2 = localDateTime.withMinute(20);
System.out.println(localDateTime2); // 2022-07-27T14:20:22.621
修改一般都是通过with开头的方法进行操作
4. 获取日期时间对象的年、月、日、时、分、秒
LocalDateTime localDateTime = LocalDateTime.now();
int year = localDateTime.getYear(); // 2022
Month month = localDateTime.getMonth(); // JULY // getValue() ==> 7
int dayOfMonth = localDateTime.getDayOfMonth(); // 27
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek(); // WEDNESDAY // 周三 getValue() ==> 3
int dayOfYear = localDateTime.getDayOfYear(); // 208 // 一年中第208天
int hour = localDateTime.getHour(); // 14
int minute = localDateTime.getMinute(); // 23
int second = localDateTime.getSecond(); // 16
- 其中月份和一周中的天数是枚举类,不过相对于Calendar的月份数(从0开始到11),星期(1对应星期天,2对应星期一...7对应星期六)要好很多
5. 时间日期的前后判断
LocalDateTime nowTime = LocalDateTime.now(); // 2022-07-28T10:01:32.281
LocalDateTime preTime = LocalDateTime.of(2019, 12, 30, 18, 55, 59);
// 判断哪个时间在前面
boolean after = nowTime.isAfter(preTime); // true
boolean before = nowTime.isBefore(preTime); // false
Instant
事实上Instant就是java8以前的Date,可以使用以下两个类中的方法在这两个类型之间进行转换,
比如Date.from(Instant)就是用来把Instant转换成java.util.date的,而new Date().toInstant()就是将Date转换成Instant的C
Instant是以UTC为标准的。带有时区信息的
// Instant 和 Date类似, 都是通过一个时间戳表示某个时刻
Instant now = Instant.now();
System.out.println(now); // 2022-07-27T06:41:57.174Z
// 将Instant转换成Date
Date from = Date.from(now);
System.out.println(from); // Wed Jul 27 14:44:11 CST 2022
// 将Date对象转换成Instant
Instant instant = from.toInstant();
System.out.println(instant); // 2022-07-27T06:41:57.174Z
1. 获取长整型时间戳
Instant now = Instant.now();
long timeStamp = now.toEpochMilli(); // 1658975123186 毫秒
计算时间、日期间隔(duration、period)
duration: 是计算两个时间之间的间隔长度
period: 是计算两个日期之间间隔的长度
// Duration:用于计算两个“时间”间隔 针对的具体的时刻点的时间 如可以计算LocalDateTime, LocalTime, Instant, 却不可以计算LocalDate
// Period:用于计算两个“日期”间隔 针对的是具体的日期, 可以计算LocalDate 其他的LocalDate, localTime, Instant 不可计算
LocalDate nowTime = LocalDate.now();
LocalDate preTime = LocalDate.of(2010, 5, 23);
Period between = Period.between(preTime, nowTime);
long years = between.get(ChronoUnit.YEARS);
long months = between.get(ChronoUnit.MONTHS);
long days = between.get(ChronoUnit.DAYS);
System.out.println(nowTime); // 2022-07-28
System.out.println(between.toTotalMonths()); // 146
System.out.println(nowTime + "与" + preTime + " 相差" + years + "年, " + months + "月, " + days + "日"); // 2022-07-27与 //2010-05-23 相差12年, 2月, 4日
/**************************************************************************************************************/
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime preLocalDateTime = LocalDateTime.of( 2021, 11, 6, 12, 11, 6);
Duration duration = Duration.between(preLocalDateTime, localDateTime);
long days = duration.toDays();
long hours = duration.toHours();
long minutes = duration.toMinutes();
long millis = duration.toMillis();
long nanos = duration.toNanos();
System.out.println(preLocalDateTime + "与" + localDateTime + "相差"+ days + "天" );
System.out.println(preLocalDateTime + "与" + localDateTime + "相差"+ hours + "小时" );
System.out.println(preLocalDateTime + "与" + localDateTime + "相差"+ minutes + "分钟" );
System.out.println(preLocalDateTime + "与" + localDateTime + "相差"+ millis + "毫秒" );
System.out.println(preLocalDateTime + "与" + localDateTime + "相差"+ nanos + "纳秒" );
输出:
2021-11-06T12:11:06与2022-07-28T11:45:29.033相差263天
2021-11-06T12:11:06与2022-07-28T11:45:29.033相差6335小时
2021-11-06T12:11:06与2022-07-28T11:45:29.033相差380134分钟
2021-11-06T12:11:06与2022-07-28T11:45:29.033相差22808063033毫秒
2021-11-06T12:11:06与2022-07-28T11:45:29.033相差22808063033000000纳秒
格式化输出DateTimeFormatter
和SimpleDateFormat类似,为了让Local*这类的时间日期类与特定格式的日期字符串进行转换,JDK8添加了DateTimeFormatter
LocalDateTime localDateTime = LocalDateTime.now();
// 将LocalDateTime 转换成自定义个格式的时间字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String time = formatter.format(localDateTime);
System.out.println(time); // 2022-07-27 15:36:54
// 将固定格式的字符串转换成LocalDateTime
LocalDateTime localDateTime1 = LocalDateTime.parse("2022-12-11 12:15:11", formatter);
System.out.println(localDateTime);
System.out.println(localDateTime1);
// 也可以在一行中进行格式化
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); // 2022-07-28 14:27:19
System.out.println(LocalDateTime.parse("2022-12-11 12:15:11", formatter)); // 2022-12-11T12:15:11
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程使用 AI 从 0 到 1 写了个小工具
· 快收藏!一个技巧从此不再搞混缓存穿透和缓存击穿
· AI 插件第二弹,更强更好用
· Blazor Hybrid适配到HarmonyOS系统
· 支付宝 IoT 设备入门宝典(下)设备经营篇