简介

  Java8除了有较大更新的 lambda、 Stream ,还推出了全新的日期时间API。Java之前处理日期、日历和时间的不足之处主要有:

    • 日期类型为可变类型,非线程安全使其应用非常受限
    • 没有引入时区,不支持国际化,因此引入了java.util.Calendar和java.util.TimeZone类
    • 对于时间、时间戳、格式化、解析没有明确定义类,提供类java.text.DateFormat抽象类,但通常情况下,SimpleDateFormat类被用于此类需求
    • 日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义
    • java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,这两个类都有相同的名字

  全新API的众多好处之一就是,明确了日期时间概念,例如: 瞬时(instant)、 长短(duration)、 日期、 时间、 时区和 周期。同时继承了Joda 库按人类语言和计算机各自解析的时间处理方式。不同于老版本,新API基于ISO标准日历系统,java.time包下的所有类都是不可变类型而且线程安全。

关键类

  • Instant:瞬时实例

  • LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等

  • LocalTime:本地时间,不包含日期

  • LocalDateTime:组合了日期和时间,但不包含时差和时区信息

  • ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差

  • ZoneOffSet 和 ZoneId 类,使得解决时区问题更为简便。解析、格式化时间的 DateTimeFormatter 类也全部重新设计

代码实例

1、获取当前的日期

  Java 8 中的 LocalDate 用于表示当天日期。和 java.util.Date不同,它只有日期,不包含时间。当你仅需要表示日期时就用这个类

  1. 1 /**
  2. 2 * 获取今天的日期
  3. 3 */
  4. 4 public void getCurrentDate(){
  5. 5 LocalDate today = LocalDate.now();
  6. 6 System.out.println("Today's local date : " + today);
  7. 7
  8. 8 Date date = new Date();
  9. 9 System.out.println(date);
  10. 10 }

    上面的代码创建了当天的日期,不含时间信息。打印出的日期格式非常友好,不像 Date类 打印出一堆没有格式化的信息

2.、获取年、月、日信息

    LocalDate 提供了获取年、月、日的快捷方法,其实例还包含很多其它的日期属性。通过调用这些方法就可以很方便的得到需要的日期信息,不用像以前一样需要依赖Calendar类了

  1. 1 /**
  2. 2 * 获取年、月、日信息
  3. 3 */
  4. 4 public void getDetailDate(){
  5. 5 LocalDate today = LocalDate.now();
  6. 6 int year = today.getYear();
  7. 7 int month = today.getMonthValue();
  8. 8 int day = today.getDayOfMonth();
  9. 9 System.out.println(String.format("Year:%d, Month:%d, Day:%d", year, month, day));
  10. 10 }

3、处理特定日期

    在第一个例子里,我们通过静态工厂方法now()非常容易地创建了当天日期。我们还可以调用另一个有用的工厂方法 LocalDate.of() 创建任意日期, 该方法需要传入年、月、日做参数,返回对应的LocalDate实例。这个方法的好处是没再犯老API的设计错误,比如年度起始于1900,月份是从 0 开始等等。日期所见即所得,直接明了

  1. /**
  2. * 处理特定日期
  3. */
  4. public void handleSpecialDate(){
  5. LocalDate date = LocalDate.of(2020, 6, 4);
  6. System.out.println("special date is " + date);
  7. }

4、判断两个日期是否相等

    现实生活中有一类时间处理就是判断两个日期是否相等, LocalDate 重载了equal方法,判断起来就很方便。注意,如果比较的日期是字符型的,需要先解析成日期对象再作判断

  1. /**
  2. * 判断日期是否相等
  3. */
  4. public void equalDate(){
  5. LocalDate date = LocalDate.of(2020, 6, 4);
  6. LocalDate now = LocalDate.now();
  7. if (Objects.equals(date, now)) {
  8. System.out.println(date + "===" + now);
  9. }
  10. }

5、检查像生日这种周期性事件

    Java 中另一个日期时间的处理就是检查类似生日、纪念日、法定假日(国庆以及春节)、或者每个月固定时间发送邮件给客户 这些周期性事件。如何检查这些节日或其它周期性事件呢?答案就是 MonthDay类。这个类组合了月份和日,去掉了年,这意味着你可以用它判断每年都会发生事件。和这个类相似的还有一个 YearMonth类。这些类也都是不可变并且线程安全的值类型。下面我们通过 MonthDay来检查周期性事件:

  1. /**
  2. * 判断周期性事件
  3. */
  4. public void cycleDate(){
  5. LocalDate now = LocalDate.now();
  6. LocalDate birth = LocalDate.of(2020, 6, 4);
  7. MonthDay monthDay = MonthDay.of(birth.getMonth(), birth.getDayOfMonth());
  8. MonthDay currentMonthDay = MonthDay.from(now);
  9. if (Objects.equals(currentMonthDay, monthDay)) {
  10. System.out.println("happy birthday to you ");
  11. } else {
  12. System.out.println("today is a good day");
  13. }
  14. }

6、获取当前时间

    与获取日期很像,获取时间使用的是 LocalTime 类,一个只有时间没有日期的类。可以调用静态工厂方法now()来获取当前时间。默认的格式是 hh:mm:ss:nnn

  1. /**
  2. * 获取当前时间
  3. */
  4. public void getCurrentTime(){
  5. LocalTime now = LocalTime.now();
  6. System.out.println("local time now : " + now);
  7. }

7、在现有的时间上增加小时

    Java 8 提供了更好的 plusHours() 方法替换 add() ,并且是兼容的。注意,这些方法返回一个全新的LocalTime实例,由于其不可变性,返回后一定要用变量赋值。

  1. /**
  2. * 增加时间
  3. */
  4. public void plusHours(){
  5. LocalTime now = LocalTime.now();
  6. LocalTime plusHours = now.plusHours(2);
  7. System.out.println("local time now : " + now);
  8. System.out.println("2 hours later time : " + plusHours);
  9. }

8、如何计算一个星期之后的日期

    和上个例子计算两小时以后的时间类似,这个例子会计算一周后的日期。LocalDate日期不包含时间信息,它的plus()方法用来增加天、周、月,ChronoUnit类声明了这些时间单位。由于LocalDate也是不变类型,返回后一定要用变量赋值。可以用同样的方法增加1个月、1年、1小时、1分钟甚至一个世纪,更多选项可以查看Java 8 API中的ChronoUnit类

  1. /**
  2. * 计算一周后的日期和一周前的日期
  3. */
  4. public void calculateCycleDate(){
  5. LocalDate today = LocalDate.now();
  6. LocalDate previousWeek = today.minus(1, ChronoUnit.WEEKS);
  7. LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
  8. System.out.println("local today : " + today);
  9. System.out.println("1 week previous: " + previousWeek);
  10. System.out.println("1 week later : " + nextWeek);
  11. }

9、使用Java 8的Clock时钟类

    Java 8增加了一个 Clock 时钟类用于获取当时的时间戳,或当前时区下的日期时间信息。以前用到System.currentTimeInMillis() 和 TimeZone.getDefault() 的地方都可用Clock替换

  1. /**
  2. * Clock 时钟类
  3. */
  4. public void clock(){
  5. Clock time = Clock.systemUTC();
  6. Clock zone = Clock.systemDefaultZone();
  7. System.out.println(time);
  8. System.out.println(zone);
  9. }

10、判断日期是早于还是晚于另一个日期

    LocalDate 类有两类方法 isBefore() 和 isAfter() 用于比较日期。调用 isBefore() 方法时,如果给定日期小于当前日期则返回 true

  1. /**
  2. * 日期比较大小
  3. */
  4. public void compareDate(){
  5. LocalDate today = LocalDate.now();
  6. LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
  7. if (today.isBefore(tomorrow)) {
  8. System.out.println("hello, good boy");
  9. }
  10. if (tomorrow.isAfter(today)) {
  11. System.out.println("hello, see you later");
  12. }
  13. }

11、处理时区

    Java 8不仅分离了日期和时间,也把时区分离出来了。现在有一系列单独的类如 ZoneId 来处理特定时区,ZoneDateTime 类来表示某时区下的时间

  1. /**
  2. * 处理时区
  3. */
  4. public void getZoneTime(){
  5. ZoneId newYork = ZoneId.of("America/New_York");
  6. LocalDateTime localDateTime = LocalDateTime.now();
  7. ZonedDateTime newYorkTime = ZonedDateTime.of(localDateTime, newYork);
  8. System.out.println("当地时间 : " + localDateTime);
  9. System.out.println("转换为纽约时间 : " + newYorkTime);
  10. }

12、如何体现出固定日期

    例如:表示信用卡到期这类固定日期。与 MonthDay 检查重复事件的例子相似, YearMonth 是另一个组合类,用于表示信用卡到期日、FD到期日、期货期权到期日等。还可以用这个类得到 当月共有多少天,YearMonth 实例的 lengthOfMonth() 方法可以返回当月的天数,在判断2月有28天还是29天时非常有用

  1. /**
  2. * 固定日期,例如卡片到期日
  3. */
  4. public void cardExpiry(){
  5. YearMonth now = YearMonth.now();
  6. System.out.printf("today in %d Year %d Month, this month have %d day", now.getYear(), now.getMonthValue(), now.lengthOfMonth());
  7. System.out.println();
  8.  
  9. YearMonth expiryDate = YearMonth.of(2030, Month.JUNE);
  10. System.out.printf("card expiry date : %s", expiryDate);
  11. System.out.println();
  12. }

13、检查闰年

    LocalDate类有一个很实用的方法 isLeapYear() 判断该实例是否是一个闰年

  1. /**
  2. * 检查闰年
  3. */
  4. public void checkLeapYear(){
  5. LocalDate localDate = LocalDate.now();
  6. if (localDate.isLeapYear()) {
  7. System.out.println("this year is leap year");
  8. } else {
  9. System.out.println("this year is not leap year");
  10. }
  11. }

14、计算两个日期之间的天数和月数

    有一个常见日期操作是计算两个日期之间的天数、周数或月数。在Java 8中可以用java.time.Period类来做计算

  1. /**
  2. * 计算日期之间的间隔
  3. */
  4. public void calculateDateDays(){
  5. LocalDate localDate = LocalDate.now();
  6. LocalDate nextSpringFestival = LocalDate.of(2021, 2, 12);
  7.  
  8. Period between = Period.between(localDate, nextSpringFestival);
  9. System.out.printf("two days interval %d Month %d Days", between.getMonths(), between.getDays());
  10. System.out.println();
  11. }

15、使用预定义的格式化工具去解析或格式化日期

    Java 8引入了全新的日期时间格式工具,线程安全而且使用方便。它自带了一些常用的内置格式化工具

  1. /**
  2. * 格式化日期
  3. */
  4. public void formateDate(){
  5. String date = "20200615";
  6. LocalDate formate = LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE);
  7. System.out.printf("date : %s, formate : %s", date, formate);
  8. System.out.println();
  9. }

16、完整代码

  1. /**
  2. * @author LiuHuan
  3. * @date 2019-11-02 21:23
  4. * @desc
  5. */
  6. public class Java8DateTest {
  7.  
  8. public static void main(String[] args) {
  9. Java8DateTest test = new Java8DateTest();
  10. test.getCurrentDate();
  11. test.getDetailDate();
  12. test.handleSpecialDate();
  13. test.equalDate();
  14. test.cycleDate();
  15. test.getCurrentTime();
  16. test.plusHours();
  17. test.calculateCycleDate();
  18. test.clock();
  19. test.compareDate();
  20. test.getZoneTime();
  21. test.cardExpiry();
  22. test.checkLeapYear();
  23. test.calculateDateDays();
  24. test.formateDate();
  25. }
  26.  
  27. /**
  28. * 获取当前时间
  29. */
  30. public void getCurrentDate(){
  31. LocalDate today = LocalDate.now();
  32. System.out.println("Today's local date : " + today);
  33.  
  34. Date date = new Date();
  35. System.out.println(date);
  36. }
  37.  
  38. /**
  39. * 获取年、月、日信息
  40. */
  41. public void getDetailDate(){
  42. LocalDate today = LocalDate.now();
  43. int year = today.getYear();
  44. int month = today.getMonthValue();
  45. int day = today.getDayOfMonth();
  46. System.out.println(String.format("Year:%d, Month:%d, Day:%d", year, month, day));
  47. }
  48.  
  49. /**
  50. * 处理特定日期
  51. */
  52. public void handleSpecialDate(){
  53. LocalDate date = LocalDate.of(2020, 6, 4);
  54. System.out.println("special date is " + date);
  55. }
  56.  
  57. /**
  58. * 判断日期是否相等
  59. */
  60. public void equalDate(){
  61. LocalDate date = LocalDate.of(2020, 6, 4);
  62. LocalDate now = LocalDate.now();
  63. if (Objects.equals(date, now)) {
  64. System.out.println(date + "===" + now);
  65. }
  66. }
  67.  
  68. /**
  69. * 判断周期性事件
  70. */
  71. public void cycleDate(){
  72. LocalDate now = LocalDate.now();
  73. LocalDate birth = LocalDate.of(2020, 6, 4);
  74. MonthDay monthDay = MonthDay.of(birth.getMonth(), birth.getDayOfMonth());
  75. MonthDay currentMonthDay = MonthDay.from(now);
  76. if (Objects.equals(currentMonthDay, monthDay)) {
  77. System.out.println("happy birthday to you ");
  78. } else {
  79. System.out.println("today is a good day");
  80. }
  81. }
  82.  
  83. /**
  84. * 获取当前时间
  85. */
  86. public void getCurrentTime(){
  87. LocalTime now = LocalTime.now();
  88. System.out.println("local time now : " + now);
  89. }
  90.  
  91. /**
  92. * 增加时间
  93. */
  94. public void plusHours(){
  95. LocalTime now = LocalTime.now();
  96. LocalTime plusHours = now.plusHours(2);
  97. System.out.println("local time now : " + now);
  98. System.out.println("2 hours later time : " + plusHours);
  99. }
  100.  
  101. /**
  102. * 计算一周后的日期和一周前的日期
  103. */
  104. public void calculateCycleDate(){
  105. LocalDate today = LocalDate.now();
  106. LocalDate previousWeek = today.minus(1, ChronoUnit.WEEKS);
  107. LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
  108. System.out.println("local today : " + today);
  109. System.out.println("1 week previous: " + previousWeek);
  110. System.out.println("1 week later : " + nextWeek);
  111. }
  112.  
  113. /**
  114. * Clock 时钟类
  115. */
  116. public void clock(){
  117. Clock time = Clock.systemUTC();
  118. Clock zone = Clock.systemDefaultZone();
  119. System.out.println(time);
  120. System.out.println(zone);
  121. }
  122.  
  123. /**
  124. * 日期比较大小
  125. */
  126. public void compareDate(){
  127. LocalDate today = LocalDate.now();
  128. LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
  129. if (today.isBefore(tomorrow)) {
  130. System.out.println("hello, good boy");
  131. }
  132. if (tomorrow.isAfter(today)) {
  133. System.out.println("hello, see you later");
  134. }
  135. }
  136.  
  137. /**
  138. * 处理时区
  139. */
  140. public void getZoneTime(){
  141. ZoneId newYork = ZoneId.of("America/New_York");
  142. LocalDateTime localDateTime = LocalDateTime.now();
  143. ZonedDateTime newYorkTime = ZonedDateTime.of(localDateTime, newYork);
  144. System.out.println("当地时间 : " + localDateTime);
  145. System.out.println("转换为纽约时间 : " + newYorkTime);
  146. }
  147.  
  148. /**
  149. * 固定日期,例如卡片到期日
  150. */
  151. public void cardExpiry(){
  152. YearMonth now = YearMonth.now();
  153. System.out.printf("today in %d Year %d Month, this month have %d day", now.getYear(), now.getMonthValue(), now.lengthOfMonth());
  154. System.out.println();
  155.  
  156. YearMonth expiryDate = YearMonth.of(2030, Month.JUNE);
  157. System.out.printf("card expiry date : %s", expiryDate);
  158. System.out.println();
  159. }
  160.  
  161. /**
  162. * 检查闰年
  163. */
  164. public void checkLeapYear(){
  165. LocalDate localDate = LocalDate.now();
  166. if (localDate.isLeapYear()) {
  167. System.out.println("this year is leap year");
  168. } else {
  169. System.out.println("this year is not leap year");
  170. }
  171. }
  172.  
  173. /**
  174. * 计算日期之间的间隔
  175. */
  176. public void calculateDateDays(){
  177. LocalDate localDate = LocalDate.now();
  178. LocalDate nextSpringFestival = LocalDate.of(2021, 2, 12);
  179.  
  180. Period between = Period.between(localDate, nextSpringFestival);
  181. System.out.printf("two days interval %d Month %d Days", between.getMonths(), between.getDays());
  182. System.out.println();
  183. }
  184.  
  185. /**
  186. * 格式化日期
  187. */
  188. public void formateDate(){
  189. String date = "20200615";
  190. LocalDate formate = LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE);
  191. System.out.printf("date : %s, formate : %s", date, formate);
  192. System.out.println();
  193. }
  194.  
  195. }

Java8之日期处理的更多相关文章

  1. 在JDBC中使用Java8的日期LocalDate、LocalDateTime

    在实体Entity里面,可以使用java.sql.Date.java.sql.Timestamp.java.util.Date来映射到数据库的date.timestamp.datetime等字段 但是 ...

  2. Java8 时间日期类操作

    Java8 时间日期类操作 Java8的时间类有两个重要的特性 线程安全 不可变类,返回的都是新的对象 显然,该特性解决了原来java.util.Date类与SimpleDateFormat线程不安全 ...

  3. 详解Java8的日期和时间API

    详解Java8的日期和时间API 在JDK1.0的时候,Java引入了java.util.Date来处理日期和时间:在JDK1.1的时候又引入了功能更强大的java.util.Calendar,但是C ...

  4. java8 关于日期的处理

    Java8 为我们提供了一种新的日期格式:LocalDate和LocalDateTime 获取当前的时间及前一天时间的方法: import java.time.LocalDateTime; impor ...

  5. 基于Java8的日期时间工具类DateTimeFormatter

    原文:https://blog.csdn.net/qq_36596145/article/details/85331002 import java.time.Instant; import java. ...

  6. JAVA8之日期操作详解

    package org.date; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.Month; im ...

  7. Java8的日期和时间的库20经常使用的演示样本

    除了lambda表达,stream以及从一些小的改进,Java 8还推出了新的日期和时间API,在本教程中,我们将展示通过几个简单的任务来学习如何使用示例Java 8这组API.Java至今.日历和时 ...

  8. (后端)mybatis中使用Java8的日期LocalDate、LocalDateTime

    原文地址:https://blog.csdn.net/weixin_38553453/article/details/75050632 MyBatis的型处理器是属性“createdtime参数映射为 ...

  9. java8中日期字符串的月日时分秒自动补零

    需求:如字符串2019-7-1 9:6:5转成2019-07-01 09:06:05 java8实现如下: public static String getStartDate(String start ...

随机推荐

  1. maatwebsite lost precision when export long integer data

    Maatwebsite would lost precision when export long integer data, no matter string or int storaged in ...

  2. 虚拟化技术之kvm WEB管理工具kimchi

    在前面的博客中,我们介绍了kvm的各种工具,有基于图形管理的virt-manager.有基于命令行管理的virt-install .qemu-kvm.virsh等等:今天我们来介绍一款基于web界面的 ...

  3. CentOS 7环境下大量创建账号的方法

    1 一些账号相关的检查工具 1.1 pwck命令 pwck 这个指令在检查 /etc/passwd 这个账号配置文件内的信息,与实际的家目录是否存在等信息,还可以比对 /etc/passwd /etc ...

  4. Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 实践

    Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 目录 Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 引子 FeignClient的 ...

  5. idea使用技巧一常用快捷键

    快捷键 功能 ctrl+x 删除行 ctrl+d 复制行 ctrl+n 查找类 ctrl+f 查找文本 ctrl+j 自动代码 ctrl+h 显示类结构图 ctrl+q 显示注释文档 ctrl+p 方 ...

  6. vue 在模板template中变量和字符串拼接

    例子:  :post-action="'/api/v1/reportPage/'+this.selectedPagerId+'/saveimg/'"

  7. .net 安装部署诀窍

    1.解决方案资源管理器中有多个类库项目和一个启动主项目时:各类库项目的生成路径设为bin\debug: 启动主项目的生成路径设成指定的主输出路径: 2.打包时在应用程序文件夹中添加主输出即可,主输出的 ...

  8. 1090 Highest Price in Supply Chain (25 分)(模拟建树,找树的深度)牛客网过,pat没过

    A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...

  9. 6 年前,只会 JSP 和 Servlet 就可以找到工作

    这篇文章在去年就已经构思了,不过一直都没有整理出来,今天终于完成了这篇文章,所以发上来给大家看一看,都是一些个人的小感慨,我的观点可能不是非常的完善,大家也可以一起讨论. 找工作之难,难于上青天 五六 ...

  10. 09 promise then

    then() 方法返回一个 Promise 链式调用:then里面回调函数(成功回调和失败回调),凡事这两个回调函数里面抛出错误或者返回一个已经是拒绝状态的 Promise. 那么 then 返回的  ...