Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理。同样的,如果你现在依旧在项目中使用传统Date、Calendar和SimpleDateFormat等API来处理日期相关操作,这篇文章你一定不要错过。来刷新你的知识库吧!
背景
Java对日期、日历及时间的处理一直以来都饱受诟病,比如java.util.Date和java.util.Calendar类易用性差,不支持时区,非线程安全;还有用于格式化日期的类DateFormat也是非线程安全的等问题。
Java8引入的新的一系列API,对时间日期的处理提供了更好的支持,清楚的定义了时间日期的一些概念,比如说,瞬时时间(Instant),持续时间(duration),日期(date),时间(time),时区(time-zone)以及时间段(Period)。
同时,借鉴了Joda库的一些优点,比如将人和机器对时间日期的理解区分开的。
简介
新的时间日期API核心位于java.time内,另外也在java.time.chrono,java.time.format,java.time.temporal和java.time.zone有相关的API,但使用频次较少。
Java8常用的日期和时间类包含LocalDate、LocalTime、Instant、Duration、Period、LocalDateTime以及ZonedDateTime等。
另外,还有新的日期解析格式化类DateTimeFormatter。
学习最佳的途径就是去实践它,现在我们示例的形式来讲每个知识点进行讲解。
LocalDate-如何获得日期
LocalDate类内只包含日期,不包含具体时间。只需要表示日期而不包含时间,就可以使用它。
// 只获取日期 LocalDate today = LocalDate.now(); System.out.println(today); int year = today.getYear(); int month = today.getMonthValue(); int day = today.getDayOfMonth(); System.out.printf("Year : %d Month : %d day : %d \t %n", year, month, day);
同时,还可以通过LocalDate获取日期是月份的第几天、周的第几天,月份的天数,是否为闰年等。看下面的代码是不是非常方便。
LocalDate today = LocalDate.now(); // 月份中的第几天 int dayOfMonth = today.getDayOfMonth(); // 一周的第几天 DayOfWeek dayOfWeek = today.getDayOfWeek(); // 月份的天数 int length = today.lengthOfMonth(); // 是否为闰年 boolean leapYear = today.isLeapYear();
上面通过now获取LocalDate对象,也可以通过静态方法of()或parse创建任意一个日期。再也不用像之前一样年只能从1900年开始,月必须从0开始等。
LocalDate oneDay = LocalDate.of(2019,10,1); System.out.println(oneDay); LocalDate parseDay = LocalDate.parse("2019-10-01"); System.out.println(parseDay);
打印结果:2019-10-01。
LocalDate重写了equals方法,让日期的比较也变得简单了。
// 定义任意日期 LocalDate oneDay = LocalDate.of(2019, 10, 1); System.out.println(oneDay); // 定义任意比较 LocalDate anyDay = LocalDate.of(2019, 10, 1); System.out.println(oneDay.equals(anyDay));
同时,针对日期还可延伸出MonthDay或YearMonth类,顾名思义,只包含月天或年月。同样适用于equals方法来比较。
另外使用before和after可以比较两个日期前后时间。
boolean notBefore = LocalDate.parse("2019-10-01").isBefore(LocalDate.parse("2019-10-02")); boolean isAfter = LocalDate.parse("2019-10-01").isAfter(LocalDate.parse("2019-10-02"));
对日期进行前一天后一天或前一个月的加减也变得十分方便。
LocalDate tomorrowDay = LocalDate.now().plusDays(1); LocalDate nextMonth = LocalDate.now().plusMonths(1);
还有,我们在实战的时候往往要获取某一天的开始时间和当天所在月的第一天等。
LocalDate.now().atStartOfDay(); LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
LocalTime-如何获取时间
LocalTime和LocalDate类似,区别在于LocalDate不包含具体时间,而LocalTime包含具体时间。同样可以使用now或of方法来获得对象。
LocalTime localTime = LocalTime.now(); LocalTime oneTime = LocalTime.of(10,10,10);
LocalDate类似它也拥有parse、isBefore、获取时间单元等方法,就不再赘述。
需要注意的是,LocalTime获得的时间格式为:11:41:58.904。也就是,HH:mm:ss.nnn,这里nnn是纳秒。
还有一个在实战中查询日期区间时我们经常定义的“23:59:59.99”常量再也不用自己定义了。
// 23:59:59.999999999 LocalTime maxTime = LocalTime.MAX; // 00:00 LocalTime minTime = LocalTime.MIN;
LocalDateTime-日期和时间的组合
LocalDateTime表示日期和时间组合。可以通过of()方法直接创建,也可以调用LocalDate的atTime()方法或LocalTime的atDate()方法将LocalDate或LocalTime合并成一个LocalDateTime。
创建时间示例:
LocalDateTime now = LocalDateTime.now(); LocalDateTime oneTime = LocalDateTime.of(2019,10,14,10,12,12); // 拼接日期 LocalTime.now().atDate(LocalDate.now());
LocalDateTime与LocalDate和LocalTime之间可以相互转化。其他日期增减等操作与上面的类似。
Instant-获取时间戳
Instant用于一个时间戳,与System.currentTimeMillis()类似,但Instant可以精确到纳秒(Nano-Second)。
Instant除了可以使用now()方法创建,还可以通过ofEpochSecond方法创建。
Instant now = Instant.now(); Instant.ofEpochSecond(365 * 24 * 60, 100);
其中ofEpochSecond第一个参数表示秒,第二个参数表示纳秒。整体表示:从1970-01-01 00:00:00开始后的365天100纳秒的时间点。
Duration-获取时间段
Duration的内部实现与Instant类似,但Duration表示时间段,通过between方法创建。
LocalDateTime from = LocalDateTime.now(); LocalDateTime to = LocalDateTime.now().plusDays(1); Duration duration = Duration.between(from, to); // 区间统计换算 // 总天数 long days = duration.toDays(); // 小时数 long hours = duration.toHours(); // 分钟数 long minutes = duration.toMinutes(); // 秒数 long seconds = duration.getSeconds(); // 毫秒数 long milliSeconds = duration.toMillis(); // 纳秒数 long nanoSeconds = duration.toNanos();
Duration对象还可以通过of()方法创建,该方法参数为时间段长度和时间单位。
// 7天 Duration duration1 = Duration.of(7, ChronoUnit.DAYS); // 60秒 Duration duration2 = Duration.of(60, ChronoUnit.SECONDS);
Period-获取日期段
Period与Duration类似,获取一个时间段,只不过单位为年月日,也可以通过of方法和between方法创建,between方法接收的参数为LocalDate。
Period period = Period.of(1, 10, 25); Period period1 = Period.between(LocalDate.now(), LocalDate.now().plusYears(1));
ZonedDateTime-创建时区时间
ZonedDateTime类,用于处理带时区的日期和时间。ZoneId表示不同的时区。大约有40不同的时区。
获取所有时区集合:
Set allZoneIds = ZoneId.getAvailableZoneIds();
创建时区:
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
把LocalDateTime转换成特定的时区:
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), zoneId);
另外和时区一起使用的类是OffsetDateTime类,OffsetDateTime是不变的,表示date-time偏移,存储所有日期和时间字段,精确至纳秒,从UTC/Greenwich计算偏移。
时间日期格式化
Java8对日期的格式化操作非常简单,首先看到上面的类大多都提供了parse方法,可以直接通过解析字符串得到对应的对象。
而日期和时间的格式化可通过LocalDateTime的format方法进行格式化。
LocalDateTime dateTime = LocalDateTime.now(); String str = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); System.out.println(str); str = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); System.out.println(str);
可以使用DateTimeFormatter预置的格式,也可以通过DateTimeFormatter.ofPattern方法来指定格式。
关键点回顾
Java8中关于时间日期的API有以下关键点:
好了,关于Java8新特性的时间日期功能就将到这里,用起来是不是简单明快多了,赶紧在项目中练练手吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Java8新特性Stream流实例详解,包括了Java8新特性Stream流实例详解的使用技巧和注意事项,需要的朋友参考一下 什么是Stream流? Stream流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。 Stream的优点:声明性,可复合,可并行。这三个特性使得stream操作更简洁,更灵活,更高效。 Stream的操作有两个特点:可以多个操作链接起来运行,内部
也许有人能给我举个例子?我在问自己,新的日期和时间API的改进来自哪里。
主要内容:1. Java 9 REPL(JShell),2. 用于不可变列表,集合,映射和Map.Entry的工厂方法,3. 接口的私有方法,4. Java 9模块系统,5. Process API改进,6. Try-With-Resources改进,7. CompletableFuture API改进,8. 反应流,9. 菱形运算符匿名内部类,10 Optional类改进,11. Stream API改进,12. 增强了@Deprecated注释,13. HTTP2客户端,14. 多分辨率图像
本文向大家介绍详解Java8新特性Stream之list转map及问题解决,包括了详解Java8新特性Stream之list转map及问题解决的使用技巧和注意事项,需要的朋友参考一下 List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap 具体用法实例如下: 输出结果为: 注意:用Collectors的toMap方法转换List,一般会遇
本文向大家介绍java8新特性之方法引用示例代码,包括了java8新特性之方法引用示例代码的使用技巧和注意事项,需要的朋友参考一下 简介 方法引用是java8的新特性之一, 可以直接引用已有Java类或对象的方法或构造器。方法引用与lambda表达式结合使用,可以进一步简化代码。 方法引用的使用场景 我们用Lambda表达式来实现匿名方法。但有些情况下,我们用Lambda表达式仅仅是调用一些已经存
何时何地哪个更可取? 我不知道他们之间到底有什么区别。 来自LocalDateTime的文档 ...时间表示为纳秒精度。例如,值“2007 年 10 月 2 日 13:45.30.123456789”可以存储在 LocalDateTime 中。 我假设LocalDateTime也可以接受纳秒。所以我想,我可以用LocalDateTime替换我的代码,它们被声明为TimeStamp。如果我错了,请纠