Java8 LocalDateTime

在java8之前我们在处理时间的时候都是用的Date,但它其实有很明显的缺点。

1.我们也会对日期做一些操作,比如加几天、加几分,当月的最后一天等等。有些计算实现比较复杂。
2.也会用SimpleDateFormat来格式化日期。但SimpleDateFormat是线程不安全的。

所以现在一般都推荐使用LocalDateTime 它是线程安全的,并且性能更好,代码更简洁。

一、示例

新时间日期API常用、重要对象主要有下面三个:

LocalDate : 只含年月日的日期对象

LocalTime :只含时分秒的时间对象

LocalDateTime : 同时含有年月日时分秒的日期对象

下面会通过示例来一一理解它们。

1、创建实例

    public static void main(String[] args) {
//1、获取当前日期
LocalDate now = LocalDate.now();
System.out.println("当前时间 = " + now);
//输出: 当前时间 = 2020-07-06 //2、获取指定日期(参数依次 年、月、日)
LocalDate localDate = LocalDate.of(2020, 6, 30);
System.out.println("年月日 = " + localDate);
//输出: 年月日 = 2020-06-30 //3、获取当前时间
LocalTime localTime = LocalTime.now();
System.out.println("localTime = " + localTime);
//输出: localTime = 22:32:45.994 //4、获取指定时间(参数依次 时、分、秒、纳秒
LocalTime localTimeOf = LocalTime.of(12, 24, 12, 4444);
System.out.println("localTimeOf = " + localTimeOf);
//输出: localTimeOf = 12:24:12.000004444 //5、获取当前年月日,时分秒都有的日期
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime = " + localDateTime);
//输出: localDateTime = 2020-07-06T22:32:45.994 //6、获取指定年月日,时分秒都有的日期(参数依次 年、月、日、时、分)
LocalDateTime localDateTimeOf = LocalDateTime.of(2020, 7, 30, 12, 12);
System.out.println("localDateTimeOf = " + localDateTimeOf);
//输出: localDateTimeOf = 2020-07-30T12:12 //7、日期+时间 组成 包含年月日,时分秒都有的日期
LocalDateTime of = LocalDateTime.of(LocalDate.now(), LocalTime.now());
System.out.println("of = " + of);
//输出: of = 2020-07-06T22:32:45.995
}

2、计算日期和时间

日期时间的加减
  • 对于LocalDate,只有精度大于或等于日的加减,如年、月、日;
  • 对于LocalTime,只有精度小于或等于时的加减,如时、分、秒、纳秒;
  • 对于LocalDateTime,则可以进行任意精度的时间相加减;

加法操作

public static void main(String[] args) {

        //获取当前时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前时间 = " + localDateTime); //1、加1年
LocalDateTime plusYears = localDateTime.plusYears(1L);
System.out.println("plusYears = " + plusYears);
//输出: plusYears = 2021-07-06T22:46:49.196 //2、加1个月
LocalDateTime plusMonths = localDateTime.plusMonths(1L);
System.out.println("plusMonths = " + plusMonths);
//输出: plusMonths = 2020-08-06T22:46:49.196 //3、加一天
LocalDateTime plusDays = localDateTime.plusDays(1L);
System.out.println("plusDays = " + plusDays);
//输出: plusDays = 2020-07-07T22:46:49.196 //4、加1个小时
LocalDateTime plusHours = localDateTime.plusHours(1L);
System.out.println("plusHours = " + plusHours);
//输出: plusHours = 2020-07-06T23:46:49.196 //5、加10分
LocalDateTime plusMinutes = localDateTime.plusMinutes(10L);
System.out.println("plusMinutes = " + plusMinutes);
//输出: plusMinutes = 2020-07-06T22:56:49.196 //6、加200毫秒
LocalDateTime plusSeconds = localDateTime.plusSeconds(200L);
System.out.println("plusSeconds = " + plusSeconds);
//输出: plusSeconds = 2020-07-06T22:50:09.196
}

也可以用另外一种方式

     LocalDateTime nextMonth = localDateTime.plus(1, ChronoUnit.MONTHS);
LocalDateTime nextYear = localDateTime.plus(1, ChronoUnit.YEARS);
LocalDateTime nextWeek = localDateTime.plus(1, ChronoUnit.WEEKS);

减法操作

    public static void main(String[] args) {
//获取当前时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前时间 = " + localDateTime);
//输出: 当前时间 = 2020-07-06T22:53:38.264 //1、减1年
LocalDateTime minusYears = localDateTime.minusYears(1L);
System.out.println("minusYears = " + minusYears);
//输出: minusYears = 2019-07-06T22:53:38.264 //2、减1个月
LocalDateTime minusMonths = localDateTime.minusMonths(1L);
System.out.println("minusMonths = " + minusMonths);
//输出: minusMonths = 2020-06-06T22:53:38.264 //3、减一天
LocalDateTime minusDays = localDateTime.minusDays(1L);
System.out.println("minusDays = " + minusDays);
//输出: minusDays = 2020-07-05T22:53:38.264 //4、减1个小时
LocalDateTime minusHours = localDateTime.minusHours(1L);
System.out.println("minusHours = " + minusHours);
//输出: minusHours = 2020-07-06T21:53:38.264 //5、减10分
LocalDateTime minusMinutes = localDateTime.minusMinutes(10L);
System.out.println("minusMinutes = " + minusMinutes);
//输出: minusMinutes = 2020-07-06T22:43:38.264 //6、减200毫秒
LocalDateTime minusSeconds = localDateTime.minusSeconds(200L);
System.out.println("minusSeconds = " + minusSeconds);
//输出: minusSeconds = 2020-07-06T22:50:18.264
}

也可以用另外一种方式

        LocalDateTime lastMonth = localDateTime.minus(1, ChronoUnit.MONTHS);
LocalDateTime lastYear = localDateTime.minus(1, ChronoUnit.YEARS);
LocalDateTime lastWeek = localDateTime.minus(1, ChronoUnit.WEEKS);

注意从代码中可以看到,这些 plus()minus() 方法,是不会改变原date和time的实例的,返回的是新的实例。

3、比较日期和时间

当我们想知道给定的时间或日期是在另一个时间/日期之前还是之后,我们就可以用到isBefore()isAfter()方法,如下所示:

 public static void main(String[] args) {
public static void main(String[] args) {
LocalDate ld1 = LocalDate.of(2020, 7, 6);
LocalDate ld2 = LocalDate.of(2020, 7, 7); boolean after = ld1.isAfter(ld2);
System.out.println("ld1是否在ld2之后 = " + after);
//输出: ld1是否在ld2之后 = false boolean before = ld1.isBefore(ld2);
System.out.println("ld1是否在ld2之前 = " + before);
//输出: ld1是否在ld2之前 = true LocalDateTime ldt1 = LocalDateTime.of(2020, 7, 7, 12, 12);
LocalDateTime ldt2 = LocalDateTime.of(2020, 7, 7, 14, 12); boolean after1 = ldt1.isAfter(ldt2);
System.out.println("ldt1是否在ldt2之后 = " + after1);
//输出: ldt1是否在ldt2之后 = false boolean before1 = ldt1.isBefore(ldt2);
System.out.println("ldt1是否在ldt2之后 = " + before1);
//输出: ldt1是否在ldt2之后 = true //时间相减
Duration duration = Duration.between(ldt1, ldt2);
//两个时间差的天数
long days = duration.toDays();
System.out.println("days = " + days);
//输出: days = 0 //小时数差
long hours = duration.toHours();
System.out.println("hours = " + hours);
//输出: hours = 2 //分钟数差
long minutes = duration.toMinutes();
System.out.println("minutes = " + minutes);
//输出: minutes = 120 //毫秒数差
long millis = duration.toMillis();
System.out.println("millis = " + millis);
//输出: millis = 7200000 //纳秒数差
long nanos = duration.toNanos();
System.out.println("nanos = " + nanos);
//输出: nanos = 7200000000000
}

4、在String和日期之间转换

在以前使用java.util.Date的时候,我们一般使用 SimpleDateFormat 去完成日期/时间和字符串的转换,在新的日期时间API中,我们使用全新的 DateTimeFormatter

如果你遵循ISO标准在日期/时间和字符串之间进行转换,那么这个事情会变得很容易,因为在 DateTimeFormatter 中,已经内置了ISO标准的格式。我们来看看代码

日期转时间

public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.now();
System.out.println("ldt = " + ldt);
//输出: ldt = 2020-07-07T18:32:34.757 String format1 = ldt.format(DateTimeFormatter.ISO_DATE);
System.out.println("format1 = " + format1);
//输出: format1 = 2020-07-07 String format2 = ldt.format(DateTimeFormatter.BASIC_ISO_DATE);
System.out.println("format2 = " + format2);
//输出: format2 = 20200707 String format3 = ldt.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println("format3 = " + format3);
//输出: format3 = 2020-07-07T18:32:34.757 String format4 = ldt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println("format4 = " + format4);
//输出: format4 = 2020-07-07T18:32:34.757 String format = ldt.format(DateTimeFormatter.ofPattern("d-M-y"));
System.out.println("format = " + format);
//输出: format = 7-7-2020 String format5 = ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("format5 = " + format5);
//输出: format5 = 2020-07-07 18:32:34 String format6 = ldt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒"));
System.out.println("format6 = " + format6);
//输出: format6 = 2020年07月07日18时32分34秒
}

String转日期

public static void main(String[] args) {
LocalDate ld = LocalDate.parse("2020-07-07");
System.out.println("ld = " + ld);
//输出: ld = 2020-07-07 String str = "2020-07-07 22:24:33";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(str,dateTimeFormatter);
System.out.println("ldt = " + ldt);
//输出: ldt = 2020-07-07T22:24:33
}

5、其它

有的时候,你需要进行一些更加复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可以使用重载版本的with方法,向其传递一个提供了更多定制化选择的TemporalAdjuster对象,更 加 灵 活 地 处 理 日 期。

日期处理

  public static void main(String[] args) {
LocalDate date = LocalDate.parse("2020-07-07");
//获取这个月的第一个周末的时间
System.out.println(date.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.SUNDAY)));
//输出: 2020-07-05 //获取上个月的最后一周末的时间
System.out.println(date.with(TemporalAdjusters.dayOfWeekInMonth(0, DayOfWeek.SUNDAY)));
//输出: 2020-06-28 //获取这个月的倒数第一个周末的时间
System.out.println(date.with(TemporalAdjusters.dayOfWeekInMonth(-1, DayOfWeek.SUNDAY)));
//输出: 2020-07-26 //获取这个月的第一个周末的时间,上面的dayOfWeekInMonth更灵活,可以定义第几周
System.out.println(date.with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY)));
//输出: 2020-07-05 //明年的第一天
System.out.println(date.with(TemporalAdjusters.firstDayOfNextYear()));
//输出: 2021-01-01 //获取下个周5的时间
System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));
//输出: 2020-07-10 //获取本月最后一天
System.out.println(date.with(TemporalAdjusters.lastDayOfMonth()));
//输出: 2020-07-31 //获取本月第一天
System.out.println(date.with(TemporalAdjusters.firstDayOfMonth()));
//输出: 2020-07-01
}

其它还有许多,具体查看api

时间处理

public static void main(String[] args) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//一天开始时间
LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
String format = todayStart.format(dateTimeFormatter);
System.out.println("format = " + format);
//输出: format = 2020-07-07 00:00:00 //一天结束时间
LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
String format1 = todayEnd.format(dateTimeFormatter);
System.out.println("format1 = " + format1);
//输出: format1 = 2020-07-07 23:59:59 //一天中午时间
LocalDateTime todayMid = LocalDateTime.of(LocalDate.now(), LocalTime.NOON);
String format2 = todayMid.format(dateTimeFormatter);
System.out.println("format2 = " + format2);
//输出: format2 = 2020-07-07 12:00:00
}

举了这么多例子,在实际开发中应该足够用了。

参考

1、JDK8新特性之:Optional

2、Optional类包含的方法介绍及其示例

别人骂我胖,我会生气,因为我心里承认了我胖。别人说我矮,我就会觉得好笑,因为我心里知道我不可能矮。这就是我们为什么会对别人的攻击生气。
攻我盾者,乃我内心之矛(23)

java代码之美(17) ---Java8 LocalDateTime的更多相关文章

  1. java代码之美(16) ---Java8 Optional

    Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中 ...

  2. java代码之美(14)---Java8 函数式接口

    Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加 ...

  3. java代码之美(15)---Java8 Function、Consumer、Supplier

    Java8 Function.Consumer.Supplier 有关JDK8新特性之前写了三篇博客: 1.java代码之美(1)---Java8 Lambda 2.java代码之美(2)---Jav ...

  4. java代码(15) ---java8 Function 、Consumer 、Supplier

    Java8 Function.Consumer.Supplier 有关JDK8新特性之前还有三篇博客: 1,java代码(1)---Java8 Lambda 2,java代码(2)---Java8 S ...

  5. java代码(14) --Java8函数式接口

    Java8函数式接口 之前有关JDK8的Lambda表达式 Java代码(1)--Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁 一.概 ...

  6. java代码之美(11)---java代码的优化

    java代码的优化 随着自己做开发时间的增长,越来越理解雷布斯说的: 敲代码要像写诗一样美.也能理解有一次面试官问我你对代码有洁癖吗? 一段好的代码会让人看就像诗一样,也像一个干净房间会让人看去很舒服 ...

  7. java代码之美(3)---guava 复写Object常用方法

    guava 复写Object常用方法 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方 ...

  8. java代码之美(10)---Java8 Map中的computeIfAbsent方法

    Map中的computeIfAbsent方法 Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以在特定需求下,让你的代码更加简洁. ...

  9. java代码之美(2)---Java8 Stream

    Stream 第一次看到Stream表达式就深深把我吸引,用它可以使你的代码更加整洁而且对集合的操作效率也会大大提高,如果你还没有用到java8的Stream特性,那就说明你确实out啦. 一.概述 ...

随机推荐

  1. java scoket Blocking 阻塞IO socket通信四

    记住NIO在jdk1.7版本之前是同步非阻塞的,以前的inputsream是同步阻塞的,上面学习完成了Buffer现在我们来学习channel channel书双向的,以前阻塞的io的inputstr ...

  2. Python3-设计模式-迭代器模式

    Python3中的迭代器 迭代器模式主要是访问集合元素的一中方式,迭代器不会把整个集合对象加载到内存,而是按照顺序将集合中的元素一个一个的进行迭代,这样每次迭代的时候只取少量的元素,比较省内存 注: ...

  3. C#数据结构与算法系列(十五):排序算法(SortAlgorithm)

    1.介绍 排序是将一组数据,以指定的顺序进行排序的过程 2.分类 内部排序法:指将需要处理的所有数据都加载到内部存储器中进行排序 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序

  4. IDEA记坑之移动项目文件之后,import 找不到文件以及出现Cannot access的问题

    今天本想挪动下文件,使项目更加可观,易整理,但是挪动后出现各种问题,import xxx;全部飘红.部分切面还出现Cannot access:试过了重启idea,rebuild....各种方法都行不通 ...

  5. 入门大数据---Spark简介

    一.简介 Spark 于 2009 年诞生于加州大学伯克利分校 AMPLab,2013 年被捐赠给 Apache 软件基金会,2014 年 2 月成为 Apache 的顶级项目.相对于 MapRedu ...

  6. Elastic认证考试,请先看这一篇

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wojiushiwo987/article ...

  7. 服务消费者(Feign-下)

    上一篇文章中已经讲述 Feign的基本用法,本章主要概述 FeignClient GET/POST/PUT/DELETE restful写法以及 Feign 拦截器,与配置优化方案,关闭HttpCli ...

  8. Linux 操作系统!开篇!!!

    此篇文章主要会带你介绍 Linux 操作系统,包括 Linux 本身.Linux 如何使用.以及系统调用和 Linux 是如何工作的. Linux 简介 UNIX 是一个交互式系统,用于同时处理多进程 ...

  9. 使用telnet测试指定端口的连通性

    大家好,我是良许. 大家知道,telnet 是一个阉割版的 ssh ,它数据不加密,数据容易被盗窃,也容易受中间人攻击,所以默认情况下 telnet 端口是必须要被关闭的. telnet为用户提供了在 ...

  10. 听说你还不知道CompletableFuture?

    java8已经在日常开发编码中非常普遍了,掌握运用好它可以在开发中运用几行精简代码就可以完成所需功能.今天将介绍CompletableFuture的在生产环境如何使用实践.CompletableFut ...