在Java8以前,在Java开发过程当中,若是要操做时间,是使用Date这个类,在Java8中新增了LocalTime、LocalDate和LocalDateTime,日期和时间的处理变得更加方便和容易。用了一段时间,刚开始每次用的时候都要上网查一波才能找到要的答案,后来认真看一下官网的API,发现也不是那么难理解,如今可以经过本身的理解找到本身想要的表达式,在这里作个小小的学习总结。java
既然Date类已经存在了那么多年,为何要花那么大的精力去作这个改动?收益是什么呢?程序员
首先,由于Date类真的很难用,有不少过于Geek的设计,好比月份是从0开始,0是一月,11是十二月。好吧,我已经知道程序员是从0开始计数了,可是每次用的时候都要作各类转换,特别是跟其余输出端有交互的时候,改错一个地方就凌乱了。在新的APIjava.time
里,这些都用常量表示了,不会用错,代码看起来也更加清晰。安全
在业务代码中,每每有不少种需求,获取某一天的0点,获取下一天的中午时间,将当前时间往前或者日后移动几天,等等这类的需求,这些功能使用Date类配合Calendar要写好多代码,代码简洁性也不够好。多线程
另一个,Date里面的不少方法都弃用了,若是新的项目还敢用这些类,那就是给本身埋坑了,仍是趁早改了为好。工具
旧的时间类java.util.Date
和格式化类SimpleDateFormatter
都是可变类,不是线程安全的,在多线程环境下对共享变量Date进行操做时,须要本身保证线程安全。而新的时间APILocalTime
和LocalDate
和格式化类DateTimeFormatter
都是final类(不可变)且是线程安全的。学习
基于上面的这些缘由,就没有理由不使用新的时间API了。spa
从一个用着习惯了不少年的工具切换到新的工具老是很不习惯,过程是痛苦的,可是结果是美好的。线程
在新的时间API里,有LocalTime
、LocalDate
、LocalDateTime
三个类,LocalTime
只处理时间,没法包含日期,LocalDate
只处理日期,没法包含时间,只有LocalDateTime
能同时处理日期和时间。设计
若是理解了三个类的区别,那么在使用上,须要根据具体状况来处理,下面看看比较常遇到的场景。code
只取日期,年月日。
获取今天的日期
LocalDate today = LocalDate.now();// 2020-05-20
使用年月日构造一个日期
LocalDate valentineDay = LocalDate.of(2020, 5, 20); // 月份和日期是从1开始
指定对象,获取年、月、日、星期几
int year = localDate.getYear(); Month month = localDate.getMonth(); int day = localDate.getDayOfMonth(); DayOfWeek dayOfWeek = localDate.getDayOfWeek();
或者
int year = localDate.get(ChronoField.YEAR); int month = localDate.get(ChronoField.MONTH_OF_YEAR); int day = localDate.get(ChronoField.DAY_OF_MONTH); int dayOfWeek = localDate.get(ChronoField.DAY_OF_WEEK);
获取时间,只会取几点几分几秒。
初始化时间对象
LocalTime localTime = LocalTime.now();
使用时分秒构造一个对象
LocalTime localTime = LocalTime.of(12, 0, 0);
指定对象,获取时分秒
LocalTime localTime = LocalTime.now(); int hour = localTime.getHour(); int minute = localTime.getMinute(); int second = localTime.getSecond(); int hour = localTime.get(ChronoField.HOUR_OF_DAY); int minute = localTime.get(ChronoField.MINUTE_OF_HOUR); int second = localTime.get(ChronoField.SECOND_OF_MINUTE);
获取日期+时间,年月日+时分秒,含义等于LocalDate+LocalTime
建立时间对象
LocalDateTime localDateTime = LocalDateTime.now();
使用LocalDate结合LocalTime构造时间对象
LocalDateTime localDateTime = LocalDateTime.of(localData, localTime); LocalDateTime localDateTime = localDate.atTime(localTime); LocalDateTime localDateTime = localTime.atDate(localDate);
经过LocalDateTime获取LocalDate和LocalTime
LocalDate localDate = localDateTime.toLocalDate(); LocalTime localDate = localDateTime.toLocalTime();
这个类是表示时间轴上的某一个时刻的时间点。从1970-01-01 00:00:00这个时间开始计算,主要用于获取时间戳,与System.currentTimeMillis()
(精确到毫秒)相似,可是Instant类能够精确到纳秒。
建立Instant对象
Instant instant = Instant.now();
使用时间戳建立Instant对象
Instant instant = Instant.ofEpochSecond(100, 100000);
获取秒数和毫秒
instant.getEpochSecond(); instant.getEpochMill();
介绍了这几个类的基本API后,再经过实现某些具体的需求来加深印象。
// 获取当前时间对象->设置时->转换成时间戳 public static long getCurrentSeconds() { return Instant.now().atZone(ZoneOffset.of("+8")).toEpochSecond(); }
// 使用日期和时间构造日期时间对象->指定时区转换成时间戳 public static long getTodayStartTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).toEpochSecond(ZoneOffset.of("+8")); } public static long getTodayEndTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toEpochSecond(ZoneOffset.of("+8")); }
// 使用日期和时间构造日期时间对象->修改日期->指定时区转换成时间戳 public static long getYesterdayStartTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1).toEpochSecond(ZoneOffset.of("+8")); }
// 使用时间戳构造日期时间对象->修改日期->指定时区转换成时间戳 public static long getDayStartTime(long ) { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1).toEpochSecond(ZoneOffset.of("+8")); }
public static boolean isFirstDayOfMonth(String ymd) { LocalDate localDate = LocalDate.parse(ymd, DateTimeFormatter.ofPattern("yyyyMMdd")); return localDate.equals(localDate.withDayOfMonth(1)); }
Java新的时间API很强大,这里只能举几个本身遇到比较多的场景给你们介绍,所讲的只是最基础最皮毛的东西,要熟练的掌握全部的细节,仍是须要去看看API或源码的实现,而后在平时具体的需求场景中慢慢积累。
原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。
若是本文对你有帮助,请点个赞吧,谢谢
更多精彩内容,请关注我的公众号。