内容来自《 java8实战 》,本篇文章内容均为非盈利,旨为方便自己查询、总结备份、开源分享。如有侵权请告知,马上删除。
书籍购买地址:java8实战

  • 最开始java 1.0时代,开始使用Date时间类,相当难用,他是以1900年起始,月份是从0开始的,如果你要表示2018年11月25日,那么就要这样

    Date date = new Date(118,10,25);
    System.out.println(date.toLocaleString()); //2018-11-25 0:00:00
  • 之后Date大多数方法已经废弃,却而代之的是Calendar类,但是这个类的月份依旧是从0开始的,但是年份不是从1900开始的,但是解析日期的DateFormat方法只在Date中有,并且他不是线程安全的
  • Date和Calendar都是可变的,这将带来很多麻烦,java8中在java.time中整合了很多Joda-Time的特性,Joda-Time之前是第三方类库

使用LocalDate和LocalTime

  • 从类名就可以看出,LocalDate是表示年月日,而LocalTime是表示时分秒
  • LocalDate使用

    LocalDate date = LocalDate.of(2018,11,25);
    int year = date.getYear();  //2018
    Month month = date.getMonth(); // NOVEMBER
    int dayOfMonth = date.getDayOfMonth(); //25
    DayOfWeek dayOfWeek = date.getDayOfWeek();  //SUNDAY
    int i = date.lengthOfMonth();   //30
    boolean leapYear = date.isLeapYear();  //false
    //获取现在时间
    LocalDate now = LocalDate.now();  //2018-11-25
  • 除了getxxx方法,还可以使用TemporalField参数给get方法获取相同的信息

    LocalDate localDate = LocalDate.of(2018, 11, 25);
    int year = localDate.get(ChronoField.YEAR);
    int month = localDate.get(ChronoField.MONTH_OF_YEAR);
    int dayofweek = localDate.get(ChronoField.DAY_OF_WEEK);
  • 如上的ChronoFieldTemporalField的实现
  • LocalTime的使用

    LocalTime time = LocalTime.of(8,34,00);
    int hour = time.getHour();  //8
    int minute = time.getMinute();  //34
    int second = time.getSecond();  //0
    int nano = time.getNano();  //0
  • LocalDate和LocalTime的解析

    LocalTime time = LocalTime.parse("08:24");
    LocalDate date = LocalDate.parse("2018-11-25");
  • 解析不了会出DateTimeParseException

合并日期和事件

  • 就是LocalDateTime类,结合了上面两个类,可以同时表示年月日和时分秒

    //LocalDateTime基本使用
    LocalDateTime localDateTime = LocalDateTime.of(2018,11,25,8,37);
    //创建LocalDate对象
    LocalDate localDate = LocalDate.now();
    //调用atTime可以传入具体时分秒,构成LocalDateTime
    LocalDateTime time1 = localDate.atTime(8, 37);
    //创建LocalTime对象
    LocalTime localTime = LocalTime.now();
    //调用atDate,传入具体年月日对象,构成LocalDateTime
    LocalDateTime localDateTime1 = localTime.atDate(localDate);
    //从LocalDateTime中可以获取LocalDate和LocalTime
    LocalDate date = localDateTime.toLocalDate();
    LocalTime time = localDateTime.toLocalTime();

Instant

  • 以1970年1月1日0时0分0秒开始计算的

    Instant instant = Instant.ofEpochSecond(20); //1970-01-01T00:00:20Z
    Instant.ofEpochSecond(20, 1000000000);//1970-01-01T00:00:21Z
  • 如上的ofEpochSecond方法,第一个参数是以秒为单位的,然后增强版本,是以纳秒为单位的,其实第二个方法就是在1970-1-1-00:00:00时间上加上了21秒而已
  • 也有now方法获取当前时间戳

Duration和Period

  • 取两个时间之间的差值

    LocalTime time1 = LocalTime.of(8,00);
    LocalTime time2 = LocalTime.of(9,00);
    Duration between = Duration.between(time1, time2);  //PT1H
  • LocalTime,LocalDateTime,Instant可以用于Duration,Duration适用于以秒和纳秒,所以就不能向其传入LocalDate

    LocalDate date1 = LocalDate.of(2018,7,7);
    LocalDate date2 = LocalDate.of(2018,8,10);
    Period between = Period.between(date1, date2);  //P1M3D
  • 当然他们不仅限于计算差值,还可以创建对象以代表具体的时间值

    Duration duration = Duration.ofMillis(3);
    System.out.println("duration = " + duration);//duration = PT0.003S
    Period period = Period.ofDays(10);
    System.out.println("period = " + period);//period = P10D
  • 对于其他的方法,大家可以查询文档即可:java8 api文档
  • 对于以上的介绍目前为止日期对象都是不可变的,这是考虑函数式编程以及线程安全而做的决定

操纵解析和格式化日期

  • 创建LocalDate的修改版

    LocalDate date = LocalDate.of(2018, 4, 4); //2018-4-4
    LocalDate date1 = date.withYear(2014);//2014-4-4
    LocalDate date2 = date1.withMonth(6);//2014-6-4
    LocalDate date3 = date2.withDayOfMonth(6);//2014-6-6
  • 也可以这样

    LocalDate date = LocalDate.of(2018, 4, 4); //2018-4-4
    LocalDate date1 = date.minusYears(4); //2014-4-4
    LocalDate date2 = date1.plusMonths(8);//2014-12-4
    LocalDate date3 = date2.plusDays(10);//2014-12-14
  • 需要注意的是,即使对一个时间对象调用方法,但是该对象是不会发生改变的,只是返回一个新对象,如下

    LocalDate date = LocalDate.of(2018, 4, 4); //2018-4-4
    LocalDate date1 = date.plusYears(2).with(ChronoField.MONTH_OF_YEAR, 12).plusDays(10);
    date.plusYears(12);
    System.out.println(date);//2018-4-4
    System.out.println(date1);//2020-12-14

使用TemporalAdjuster

  • 当我们遇到复杂情况的时候,比如调整时间到下个周日之类的要求,我们就需要自定义一个TemporalAdjuster对象,更加灵活的处理日期
  • java8已经预定义好一些TemporalAdjuster了,可以通过工厂类访问他们

    LocalDate date = LocalDate.of(2018, 11, 26); //2018-11-26   周1
    LocalDate date1 = date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); //下个周日是2018-12-2
    LocalDate date2 = date1.with(TemporalAdjusters.lastDayOfMonth()); //2018-12-31   十二月的最后一天
  • 其他工厂方法请自己查看java api获取
  • TemporalAdjuster是一个函数式接口,定义如下

    @FunctionalInterface
    public interface TemporalAdjuster {Temporal adjustInto(Temporal temporal);
    }
  • 如上传入一个Temporal,返回一个Temporal,也就是说,实现的逻辑在于怎样把传入的Temporal转换为另一个需要的Temporal

定制TemporalAdjuster

  • 创建类实现TemporalAdjuster接口

    
    /*** 需求:返回下一个工作日,如果日期在周一到周五之间,就返回下一天就好,如果是周五六日就需要返回下周一的日期*/
    public class NextWorkingDay implements TemporalAdjuster {@Overridepublic Temporal adjustInto(Temporal temporal) {//得到参数中是这周的第几天int day = temporal.get(ChronoField.DAY_OF_WEEK);//根据第几天构造出DayOfWeek枚举类,容易观察,当然也可以不用构造//如果不够再下面的判断相等直接改成上面的day就行了DayOfWeek dayOfWeek = DayOfWeek.of(day);//需要在参数的基础上增加几天int dayNeedAdd = 1;//如果是周五,就需要推后三天才是周一if (dayOfWeek == DayOfWeek.FRIDAY){dayNeedAdd = 3;}//如果是周六,就需要推后两天才是周一if (dayOfWeek == DayOfWeek.SATURDAY){dayNeedAdd = 2;}//如果是周日或者当天就是在周一到周五之间的,直接加一就可以,即返回下一天return temporal.plus(dayNeedAdd, ChronoUnit.DAYS);}
    }
  • 上面说此接口是函数式接口,当然就可以使用Lmabda传入了,使用如下

    LocalDate date = LocalDate.of(2018, 11, 25);//周日
    LocalDate nextWorkDay = date.with(new NextWorkingDay());  //2018-11-26
  • 使用lambda

    LocalDate date = LocalDate.of(2018, 11, 25);//周日
    LocalDate nextWorkDay = date.with(temporal -> {//具体实现是把上面的实现类NextWorkingDay内实现的方法体贴进来就行了
    });
  • 也可以这样

    LocalDate date = LocalDate.of(2018, 11, 25);//周日
    TemporalAdjuster nextWorkDay = TemporalAdjusters.ofDateAdjuster(temporal -> {//具体实现是把上面的实现类NextWorkingDay内实现的方法体贴进来就行了
    });
    LocalDate date1 = date.with(nextWorkDay);
  • 如上是一个静态方法,传入一个UnaryOperator函数式接口的实现即可,就能够返回一个TemporalAdjuster对象,然后传入with方法即可

日期解析

  • java.time.format包就是解析日期格式化日期的,最重要的是DateTimeFormatter类,他有一些预定义常量

    LocalDate date = LocalDate.of(2018, 8, 8);
    String format = date.format(DateTimeFormatter.BASIC_ISO_DATE);//20180808
    String format1 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);//2018-08-08
  • 也可以通过指定解析模式来解析Sring时间字符串

    LocalDate parse = LocalDate.parse("20180808", DateTimeFormatter.BASIC_ISO_DATE); //2018-08-08
    LocalDate parse1 = LocalDate.parse("2018-08-08", DateTimeFormatter.ISO_LOCAL_DATE); //2018-08-08
  • 与之前的DateFormat相比,DateTimeFormatter是线程安全的
  • 按照指定格式创建解析器

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM-dd");
    LocalDate date = LocalDate.of(2018, 12, 6);
    //按照指定格式返回时间字符串
    String format = date.format(formatter);
    System.out.println("format = " + format);  //2018/12-06
    //根据指定的解析格式解析指定时间字符串
    LocalDate parse = LocalDate.parse(format, formatter);
    System.out.println("parse = " + parse);  //2018-12-06
  • 创建一个更加复杂的解析器

    DateTimeFormatter builder = new DateTimeFormatterBuilder().appendText(ChronoField.DAY_OF_MONTH)   //首先解析的是一个月的第几天.appendLiteral("(")   //分隔符.appendText(ChronoField.MONTH_OF_YEAR)  //一年的第几个月.appendLiteral("+")   //分隔符.appendText(ChronoField.YEAR)  //年份.parseCaseInsensitive()  //开始解析,不区分大小写.toFormatter(Locale.CHINA);  //按照哪个国家的方言开始解析
    LocalDate date = LocalDate.of(2018, 2, 25);
    String format = date.format(builder);
    System.out.println("format = " + format); //25(二月+2018
  • 到这里,我们介绍了时间类的使用和解析,以及自定义如何实现自己的日期转换逻辑,至于本书剩下的时区和计算时区的偏差,本文不再记录

java8学习:新的日期使用相关推荐

  1. java8 time工具_java8 Date/Time API 新的日期处理工具

    接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Date/Time api 进行说明,新的日期时间工具全部都在 java.time 及其子包中. 新 ...

  2. Java8新特性【函数式编程API、新时间日期处理API、Optional容器类】总结

    文章目录 1.Lambda表达式 1.1什么是Lambda表达式 1.2从匿名类到 Lambda 的转换 1.3Lambda表达式语法 2.函数式接口 2.1什么是函数式接口 2.2自定义函数式接口 ...

  3. 学习笔记之-java8的新特性-函数式接口,lambda表达式,方法引用,Stream API,Optional类

    1.Lambda表达式 用匿名内部类的方法去创建多线程1.new Thread2.参数传递new Runnable3.重写run方法4.在run方法中去设置线程任务5.调用start问题:我们最终目标 ...

  4. Java8之新日期时间篇

    文章目录 1.为什么需要引入新的日期和时间? 2.新的日期和时间API设计原则 3.Java8中的日期和时间API包含的包 4.常用类以及方法 4.1LocalDate 4.1.1常用API 4.1. ...

  5. 深圳Java培训学习:Java8.0新特性之Lambda表达式--【千锋】

    深圳Java培训学习:Java8.0新特性之Lambda表达式–[千锋] 前言 Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.本篇文章,主要给大家介绍的是lambda表 ...

  6. 《Java8实战》笔记(12):新的日期和时间API

    新的日期和时间API 相信大多数有经验的程序员都会赞同Java 8之前的库对日期和时间的支持就非常不理想.值得高兴的是 Java 8中引入全新的日期和时间API就是要解决这一问题. Java 8之前的 ...

  7. 详解Java8特性之新的日期时间 API

    #吐槽 Java 8 提供了一套新的日期时间 API,为什么要这么干呢.因在旧版的 Java 中,日期时间 API 存在很多问题,比如说线程安全问题了, java.util.Date 是非线程安全的, ...

  8. java8学习_java8学习

    Java8 Lambda表达式和Stream学习 lambda表达式和Stream是Java8的新特性,这次分享一下我在学习lambda表达式和Stream的收获. 这是这次测试用的Entity: p ...

  9. Java8学习笔记(1) -- 从函数式接口说起

    转载自   Java8学习笔记(1) -- 从函数式接口说起 希望本文能够成为Java8 Lambda表达式的快速入门指南. 函数式接口 理解Functional Interface(函数式接口,以下 ...

  10. java8的新特性_Java8的

    java8的新特性 Java8没有安排释放,直到2014年3月,但早期发行版本已经可用了一段时间. 一些最有趣的新功能是: 流 功能接口 默认方法 Lambdas Java时间 流 新的java.ut ...

最新文章

  1. python中字符abc_python3 正则匹配[^abc]和(?!abc)的区别(把多个字符作为一个整体匹配排除)...
  2. 层展开/关闭 - 运动缓冲效果
  3. slf4j 日志接口 统一
  4. GPTEE中定义的RSA的Algorithm Identifier详解
  5. [USACO1.1]坏掉的项链Broken Necklace
  6. keras实现简单lstm_四十二.长短期记忆网络(LSTM)过程和keras实现股票预测
  7. CentOS 搭建 LAMP服务器
  8. c++远征之多态篇——运行时类型识别(RTTI)
  9. 系统架构师学习笔记-面向对象方法
  10. cmd命令 - vue项目:单独安装vue-router
  11. 洗礼灵魂,修炼python(8)--高效的字典
  12. C语言是作为一个程序员必须了解的,那么你知道怎样学习C语言吗?
  13. 名片管理系统python详解_Python综合应用名片管理系统案例详解
  14. FPGA IIC总线协议简介
  15. 青岛Uber优步司机奖励政策(9月14日~9月20日)
  16. Python——装饰器(二)
  17. SSIS [大容量插入任务] 找不到文件错误
  18. java中容器里的增删改查_Java工程师的第八天——简单的增删改查的应用
  19. vc编程的ime输入法菜单开发
  20. .max文件导入Unity出现异常

热门文章

  1. 前端模块化--这是我看过讲得比较好的东东
  2. android 开发 获取各种intent (图片、apk文件、excel、pdf等文件)
  3. 总结自己的Git常用命令
  4. python下载指定的版本包
  5. python 笔记 之 sqlalchemy操作数据库-创建表
  6. iOS 多线程 自动释放池常见面试题代码
  7. MySQL事物系列:1:事物简介
  8. struts1生成验证码
  9. 超棒的jQuery矢量地图生成插件 - JQVAMP
  10. 如何应用Java的BigDecimal类