网站首页 > 技术文章 正文
作者 | Java圣斗士 | 原创文章,转载请注明出处
全文4000字,阅读大约需要15分钟,建议收藏
小花:Hey,Morty。最近正在准备面试,你说Java8 的新特性会不会考到呢?
我:Java8 14年3月份就出了,到现在已经有很长的一段发展时间了。但是根据我的面试经验,在笔试题的部分应该不会直接让你写出Java8 的解决方案,倒是会在面试的过程中由技术官提问一些比较重要的Java 8 特性。
小花:哦,那Java 8 有什么在开发中经常会用到的特性呢?
我:有很多啊,其中一个就是为了解决广遭诟病的Java日期操作而推出的“时间日期API”。
小花:哦?Java8 原来还有这么个好东西?以前处理日期和时间的时候,总是感觉很别扭。
我:是的呢。在Java8 以前,我们处理时间或者格式化都是通过 java.util.Date 和java.text.DateFormat。这在操作的时候有诸多的不便,在实际生产开发中很容易受到限制。
首先,Date类本身是可变类型,而SimpleDateFormat也不是线程安全的。这一点在并发编程的时候就不得不认真考虑。而在Java8中,不仅改善了日期类型的线程安全性,将java.time包下所有的 API 如LocalDateTime、DateTimeFormatter都设置为了final的,而且也添加了更加丰富的日期处理功能,比如比较两个时间大小;计算一天后、一天前,或者一周后、一周前的日期等等。甚至判断闰年也都是现成的接口。
小花:天哪,用了这么久java8,居然都不知道还有这么神奇的玩意。前阵子和其他公司对接接口,日期这部分着实费了不少力气,早知道Java8的日期API这么强大,我就不用掉这么多头发了,呜呜呜~~~
我:恩,是的呢。
小花:那我们在日期与字符串相互转化的时候,应该怎样用Java8 来描述呢?
我:恩,日期和字符串的相互转化的确是常见的场景。不过先不着急,来看看在Java8中如何获取当前时间吧:
LocalDateTime now = LocalDateTime.now(); //output : 2019-06-06T14:16:05.323
小花:咦?感觉代码可读性更强了一些,不过输出的时候为什么中间会带一个大T呢?而且也不用 format 直接就显示成了爱情的模样!
我:哈哈,你还真皮。大T是因为LocalDateTime 的toString方法遵循ISO-8601的国际标准,你可以上网百度一下这个标准,简单的说就是在日期和时间组合显示的时候,中间要加个'T',具体原因我也没有联系过相关负责人,不过根据我的经验,很可能是因为空格的话在信息传输的过程中,由于不可见字符造成一些编码的错误,这在Base64编码中有过相关的描述。
另外,不仅LocalDateTime重写了toString,其他的比如DateTime都完成了最常用的文本描述形式。因为在大多数情况,人们只需要yyyy-MM-dd HH:mm:ss的形式而不需要像:Tue Jun 04 07:20:19 CST 2019,这样。
小花:就是嘛,new Date()之后每次都要format,真的没必要。
我:Java8 中也提供了日期的字符串格式化,而且都是静态方法,相比java.util,这套API可真是做到了完全的工具化处理。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String nowStr = now.format(formatter); // output : 2019-06-06 14:37:32
你可以像上面这样直接来格式化日期类型的对象,但是要注意,LocalDate只包含日期,LocalTime只包含时间,如果你的 pattern 串中无法与之匹配,就会报:UnsupportedTemporalTypeException异常。举个栗子:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); LocalTime now = LocalTime.now(); // 只获取时间的封装 System.out.println(formatter.format(now)); //异常
小花:还真是把双刃剑!
我:嗯嗯,java8日期API将日期、时间、日期加时间进行了细分,操作更灵活,但同时也需要小心处理。其实如果你用惯了java.util.Date,你只需要直接使用LocalDateTime就可以了,形式上它和Date本身都是日期加时间的组合版,而且,如果你看到LocalDateTime的源码的话,一定很吃惊,因为它完全就是调用的LocalDate和LocalTime的接口,换句话说,它只是把这两个类型有机组合之后的封装API。
接下来,我们我们来聊聊比较有意思的场景吧。
小花:嗯,我想表示具体某一天的日期,应该如何获取到日期对象呢?
我:如果你心里有一个具体的日期,或者时间,可以直接这样写:
LocalDateTime nationalDay = LocalDateTime.of(2019, Month.OCTOBER, 1, 0, 0); // output : 2019-10-01T00:00
如果只需要日期就可以把LocalDateTime 换成LocalDate,并去掉参数中的时和分。如果只是一个日期字符串,可以利用DateTimeFormatter:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime someDay = LocalDateTime.parse("2019-10-01 14:30:30", formatter); // output : 2019-10-01T14:30:30
小花:我这里有两个日期,但是如何优雅地比较大小呢?
我:没有比直接调用API更优雅的事情了:
//nationalDay == 2019-10-01T00:00 boolean nowIsBefore = LocalDateTime.now().isBefore(nationalDay);
小花:如果我不仅要比较大小,还要知道两个日期之间相差多长时间呢?
我:不论是相差的年、月、日、时、分、秒,都是可以的:
long diffYears = ChronoUnit.YEARS.between(LocalDateTime.now(), nationalDay); // output : 0 long diffMonths = ChronoUnit.MONTHS.between(LocalDateTime.now(), nationalDay); // output : 3 long diffDays = ChronoUnit.DAYS.between(LocalDateTime.now(), nationalDay); // output : 118 long diffHours = ChronoUnit.HOURS.between(LocalDateTime.now(), nationalDay); // output : 2847 long diffMins = ChronoUnit.MINUTES.between(LocalDateTime.now(), nationalDay); // output :170878 long diffSecs = ChronoUnit.SECONDS.between(LocalDateTime.now(), nationalDay); // output : 10252739
小花:那我想获取当前分钟数呢?
我:这可要分两种情况了,一种是一天之中的分钟数,一种是一小时之中的分钟数。如果你这么写:
int mins = LocalDateTime.now().getMinute();
那么默认获取小时之内的分钟数,不过还有一种更万金油的方式,不论你是一天之内还是一小时之内:
long minsOfHour = LocalDateTime.now().getLong(ChronoField.MINUTE_OF_HOUR); long minsOfDay = LocalDateTime.now().getLong(ChronoField.MINUTE_OF_DAY);
小花:啊,真是厉害,我能想到的场景就这些了。你还有什么补充吗?
我:来介绍两个有意思的枚举:Month、DayOfWeek,如果你已经有了一个LocalDateTime类型的对象,比如sunDay。你想知道它是星期几,那么你可以这么写:
DayOfWeek dayOfWeek = sunDay.getDayOfWeek(); // output : SUNDAY int dayOfWeek = sunDay.getDayOfWeek().getValue(); // output : 7
想知道月份的话,就可以这么写:
Month month = LocalDateTime.now().getMonth(); // output : JUNE int month2 = LocalDateTime.now().getMonth().getValue(); // output : 6
小花:哦,对了,前面你说的可以直接判断闰年,怎么写呢?
我:哈哈,你还记着啊,我差点都忘了。判断闰年还是平年,你可以直接调用日期对象的isLeapYear方法:
LocalDate today = LocalDate.now(); boolean leapYear = today.isLeapYear(); // output : false
小花:哇,Java8的这套日期API真是太好用了。
我:是的,Java8的日期API真的是功能强大,我们刚才聊过的这些都是日常开发中非常常用的场景。另外还有一些时区的处理方法,不过这些问题都要进国际大公司,平时需要处理跨时区的问题时才能遇得上了。这里就不做过多的讨论了。
综上,就是小编总结的Java 8 时间日期API的常见用法,希望各位看官喜欢。
---欢迎关注【Java圣斗士】,我是你们的小可爱(?ω?) Morty---
---专注IT职场经验、IT技术分享的灵魂写手---
---每天带你领略IT的魅力---
---期待与您陪伴!---
猜你喜欢
- 2024-10-22 DATE #4、Java操作日期时间-②老版本使用的日期和时间类
- 2024-10-22 JDK1.7和JDK1.8中日期时间使用和处理的不同「Java工程师必读」
- 2024-10-22 浅谈Java8日期时间处理(抗美援朝战争时间的起止日期)
- 2024-10-22 玩转MySQL的时间类型:Date、DateTime、TimeStamp、Time
- 2024-10-22 Java8日期时间类使用详解,干货满满,不容错过哦
- 2024-10-22 java 8 新特性 日期和时间 API(我的世界java版特性)
- 2024-10-22 JAVA时间工具包 - java.time(java中时间)
- 2024-10-22 Java 打印日期/时间格式(java 打印当前时间)
- 2024-10-22 Java时间类Date与Calendar的区别与使用
- 2024-10-22 用python 计算两个日期相差多少个月
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)