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. .NETCore微服务探寻(三) - 分布式日志

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  2. SpringCloud教程第2篇:Ribbon(F版本)

    一.ribbon简介 Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign.在这一篇文章首先讲解下基于ribbon+rest. ribbon是一 ...

  3. Vue数据更新页面没有更新问题总结

    Vue数据更新页面没有更新问题总结 1. Vue无法检测实例别创建时不存在于data中的property 原因: 由于Vue会在初始化实例时对property执行getter/setter转化,所以p ...

  4. Java的前生今世

    Java作为一门编程语言,自诞生以来已经流行了20多年,在学习它之前,我们有必要先了解一下它的历史,了解它是如何一步步发展到今天这个样子. 孕育 上世纪90年代,硬件领域出现了单片式计算机系统,比如电 ...

  5. DNS篇(详解DNS)

    *文章来源:https://blog.egsec.cn/archives/601 *本文将主要说明:本文主要叙述什么是DNS.域名的层级.DNS 解析过程.DNS的缓存时间.DNS 的记录类型.DNS ...

  6. 如何在Linux下使用Tomcat部署Web应用(图文)

    学习Java必不可少的视同Tomcat,但是如果不会使用tomcat部署项目,那也是白扯,在这里教大家如果在Linux系统下视同Tomcat部署Web应用.   工具/原料   Apache-tomc ...

  7. Oracle 11g各种服务作用以及哪些需要开启

    Windwos server 2012 R2上成功安装Oracle 11g后共有7个服务,如果全局数据库名为orcl,则Oracle服务分别为 Oracle ORCL VSSWriter Servic ...

  8. java语言基础(二)_IDEA_方法

    IDEA使用 项目结构: 所有代码放置在src文件夹内 新建包:在src文件夹上,右键新建包.包的命名:英文小写.数字.英文句点. 例如:使用公司域名倒写,如cn.itcast.day04.demo0 ...

  9. Html中a标签用法总结:创建email,电话,描点链接等。以及防止链接被搜索引擎收录

    <a>标签可以用来创建一个到其他网页.文件.同一页面内的位置.电子邮件地址或任何其他URL的超链接.  是我们常用的一个标签之一,今天就讲讲如何使用a来创建email,电话,描点链接等.以 ...

  10. nodejs gulp如何获取参数

    比如执行gulp test 如果需要获取test,使用命令process.argv即可 如果执行gulp test --module aaaa,这句话表示的意思执行gulp test,顺带参数modu ...