原文出处:王爵nice

当你开始使用Java操作日期和时间的时候,会有一些棘手。你也许会通过System.currentTimeMillis() 来返回1970年1月1日到今天的毫秒数。或者使用Date类来操作日期;当遇到加减月份、天数的时候 你又需要用到Calendar类;当需要格式化日期的时候需要使用java.text.DateFormat类。 总而言之在Java中操作日期不是很方便,以至于很多开发者不得不使用第三方库,比如: joda-time


现有API存在的问题

  • 线程安全: DateCalendar不是线程安全的,你需要编写额外的代码处理线程安全问题
  • API设计和易用性: 由于DateCalendar的设计不当你无法完成日常的日期操作
  • ZonedDateTime: 你必须编写额外的逻辑处理时区和那些旧的逻辑

好在JSR 310规范中为Java8添加了新的API, 在java.time包中,新的API纠正了过去的缺陷,

新的日期API

  • ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则
  • Instant: 用来表示时间线上的一个点
  • LocalDate: 表示没有时区的日期, LocalDate是不可变并且线程安全的
  • LocalTime: 表示没有时区的时间, LocalTime是不可变并且线程安全的
  • LocalDateTime: 表示没有时区的日期时间, LocalDateTime是不可变并且线程安全的
  • Clock: 用于访问当前时刻、日期、时间,用到时区
  • Duration: 用秒和纳秒表示时间的数量

最常用的就是LocalDateLocalTimeLocalDateTime了,从它们的名字就可以看出是操作日期 和时间的。这些类是主要用于当时区不需要显式地指定的上下文。在本章节中我们将讨论最常用的api。

LocalDate

LocalDate代表一个IOS格式(yyyy-MM-dd)的日期,可以存储 生日纪念日等日期。 获取当前的日期:


LocalDate localDate = LocalDate.now();

System.out.println("localDate: " + localDate);

localDate: 2017-07-20

LocalDate可以指定特定的日期,调用ofparse方法返回该实例:


LocalDate.of(2017, 07, 20);

LocalDate.parse("2017-07-20");

当然它还有一些其他方法,我们一起来看看:

为今天添加一天,也就是获取明天


LocalDate tomorrow = LocalDate.now().plusDays(1);

从今天减去一个月


LocalDate prevMonth = LocalDate.now().minus(1, ChronoUnit.MONTHS);

下面写两个例子,分别解析日期 2017-07-20,获取每周中的星期和每月中的


DayOfWeek thursday = LocalDate.parse("2017-07-20").getDayOfWeek();

System.out.println("周四: " + thursday);

int twenty = LocalDate.parse("2017-07-20").getDayOfMonth();

System.out.println("twenty: " + twenty);

试试今年是不是闰年:


boolean leapYear = LocalDate.now().isLeapYear();

System.out.println("是否闰年: " + leapYear);

判断是否在日期之前或之后:


boolean notBefore = LocalDate.parse("2017-07-20")

.isBefore(LocalDate.parse("2017-07-22"));

System.out.println("notBefore: " + notBefore);

boolean isAfter = LocalDate.parse("2017-07-20").isAfter(LocalDate.parse("2017-07-22"));

System.out.println("isAfter: " + isAfter);

获取这个月的第一天:


LocalDate firstDayOfMonth = LocalDate.parse("2017-07-20")

.with(TemporalAdjusters.firstDayOfMonth());

System.out.println("这个月的第一天: " + firstDayOfMonth);

firstDayOfMonth = firstDayOfMonth.withDayOfMonth(1);

System.out.println("这个月的第一天: " + firstDayOfMonth);

判断今天是否是我的生日,例如我的生日是 2009-07-20


LocalDate birthday = LocalDate.of(2009, 07, 20);

MonthDay birthdayMd = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());

MonthDay today = MonthDay.from(LocalDate.now());

System.out.println("今天是否是我的生日: " + today.equals(birthdayMd));
LocalTime

LocalTime表示一个时间,而不是日期,下面介绍一下它的使用方法。

获取现在的时间,输出15:01:22.144


LocalTime now = LocalTime.now();

System.out.println("现在的时间: " + now);

将一个字符串时间解析为LocalTime,输出15:02


LocalTime nowTime = LocalTime.parse("15:02");

System.out.println("时间是: " + nowTime);

使用静态方法of创建一个时间


LocalTime nowTime = LocalTime.of(15, 02);

System.out.println("时间是: " + nowTime);

使用解析字符串的方式并添加一小时,输出16:02


LocalTime nextHour = LocalTime.parse("15:02").plus(1, ChronoUnit.HOURS);

System.out.println("下一个小时: " + nextHour);

获取时间的小时分钟


int hour = LocalTime.parse("15:02").getHour();

System.out.println("小时: " + hour);

int minute = LocalTime.parse("15:02").getMinute();

System.out.println("分钟: " + minute);

我们也可以通过之前类似的API检查一个时间是否在另一个时间之前、之后


boolean isBefore = LocalTime.parse("15:02").isBefore(LocalTime.parse("16:02"));

boolean isAfter = LocalTime.parse("15:02").isAfter(LocalTime.parse("16:02"));

System.out.println("isBefore: " + isBefore);

System.out.println("isAfter: " + isAfter);

输出 isBefore: true, isAfter: false

LocalTime类中也将每天的开始和结束作为常量供我们使用:


System.out.println(LocalTime.MAX);

System.out.println(LocalTime.MIN);

输出:


23:59:59.999999999

00:00

LocalTime就这些了,下面我们来了解一下LocalDateTime

LocalDateTime

LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。

获取当前的日期和时间:


LocalDateTime now = LocalDateTime.now();

System.out.println("现在: " + now);

输出


现在: 2017-07-20T15:17:19.926

下面使用静态方法和字符串的方式分别创建LocalDateTime对象


LocalDateTime.of(2017, Month.JULY, 20, 15, 18);

LocalDateTime.parse("2017-07-20T15:18:00");

同时LocalDateTime也提供了相关API来对日期和时间进行增减操作:

LocalDateTime tomorrow = now.plusDays(1);

System.out.println("明天的这个时间: " + tomorrow);

LocalDateTime minusTowHour = now.minusHours(2);

System.out.println("两小时前: " + minusTowHour);

这个类也提供一系列的get方法来获取特定单位:


Month month = now.getMonth();

System.out.println("当前月份: " + month);

日期格式化

在日常开发中我们用到最多的也许就是日期、时间的格式化了,那在Java8种该如何操作呢?


LocalDateTime now = LocalDateTime.now();

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

System.out.println("默认格式化: " + now);

System.out.println("自定义格式化: " + now.format(dateTimeFormatter));

LocalDateTime localDateTime = LocalDateTime.parse("2017-07-20 15:27:44", dateTimeFormatter);

System.out.println("字符串转LocalDateTime: " + localDateTime);

也可以使用DateTimeFormatterformat方法将日期、时间格式化为字符串


DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

String dateString = dateTimeFormatter.format(LocalDate.now());

System.out.println("日期转字符串: " + dateString);

日期周期

Period类用于修改给定日期或获得的两个日期之间的区别。

给初始化的日期添加5天:


LocalDate initialDate = LocalDate.parse("2017-07-20");

LocalDate finalDate   = initialDate.plus(Period.ofDays(5));

System.out.println("初始化日期: " + initialDate);

System.out.println("加日期之后: " + finalDate);

周期API中提供给我们可以比较两个日期的差别,像下面这样获取差距天数:


long between = ChronoUnit.DAYS.between(initialDate, finalDate);

System.out.println("差距天数: " + between);

上面的代码会返回5,当然你想获取两个日期相差多少小时也是简单的。

与遗留代码转换

在之前的代码中你可能出现了大量的Date类,如何将它转换为Java8种的时间类呢?

DateInstant互相转换


Date date = Date.from(Instant.now());

Instant instant = date.toInstant();

Date转换为LocalDateTime


LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));

LocalDateTimeDate


Date date =

Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

LocalDateDate


Date date =

Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

跟上Java8 - 日期和时间实用技巧的更多相关文章

  1. 跟上Java8 - 日期和时间实用技巧,转自知乎王爵nice

    作者:王爵nice链接:https://zhuanlan.zhihu.com/p/28133858来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 当你开始使用Java操 ...

  2. Java8 日期和时间实用技巧

    新的日期API ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则 Instant: 用来表示时间线上的一个点 LocalDate: 表示没有时区的日期, Lo ...

  3. Java 8 – 日期和时间实用技巧

    当你开始使用Java操作日期和时间的时候,会有一些棘手.你也许会通过System.currentTimeMillis() 来返回1970年1月1日到今天的毫秒数.或者使用Date类来操作日期:当遇到加 ...

  4. Java8 日期与时间 API

    在 Java 中,想处理日期和时间时,通常都会选用 java.util.Date 这个类进行处理.不过不知道是设计者在当时没想好还是其它原因,在 Java 1.0 中引入的这个类,大部分的 API 在 ...

  5. Java8 日期、时间操作

    一.简介 在Java8之前,日期时间API一直被开发者诟病,包括:java.util.Date是可变类型,SimpleDateFormat非线程安全等问题.故此,Java8引入了一套全新的日期时间处理 ...

  6. Java8 日期和时间API

    LocalDate.LocalTime.Instant.Duration.Period 1.1使用LocalDate和LocalTime 1.1.1LocalDate的创建方式和相关方法使用示例 @T ...

  7. Java8 日期和时间类

    新的日期和时间API 新的日期和时间类解决了Date和Calendar类出现的问题 浅尝 LocalDate 日期类 LocalDate of = LocalDate.of(2018, 7, 13); ...

  8. [转] Java8 日期/时间(Date Time)API指南

    [From] http://www.importnew.com/14140.html Java 8日期/时间( Date/Time)API是开发人员最受追捧的变化之一,Java从一开始就没有对日期时间 ...

  9. Java8新特性--日期和时间API

    如何正确处理时间 现实生活的世界里,时间是不断向前的,如果向前追溯时间的起点,可能是宇宙出生时,又或是是宇宙出现之前, 但肯定是我们目前无法找到的,我们不知道现在距离时间原点的精确距离.所以我们要表示 ...

随机推荐

  1. No.1_NABCD模型分析

        Reminder 之 NABCD模型分析           定位 多平台的闹钟提醒软件. 在安卓市场发布软件,发布后一周的用户量为1000.           N (Need 需求) 这个 ...

  2. ListView高效分页

    使用控件自带的分页功能时,会先将所查询的数据全部加载出来,若数据量较大,则造成浏览器端等待时间过长. 然而在庞大的数据量,用户所需要的不过是那么几条,甚至只要其中的一条数据,所以,为了减少开销,每次只 ...

  3. java 面试 -- 4

    Java面试知识点总结   本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有 ...

  4. Week2-作业1——关于阅读《构建之法》第1、2、16章的疑问与感悟

    关于阅读<构建之法>第1.2.16章的疑问与感悟 术语解释: 第2章,23页 什么是代码覆盖率? ———————————————————— 在测试中的代码覆盖率是指,你运行测试用例后,走过 ...

  5. 07_Java基础语法_第7天(练习)_讲义

    今日内容介绍 1.循环练习 2.数组方法练习 01奇数求和练习 * A: 奇数求和练习 * a: 题目分析 * 为了记录累加和的值,我们需要定义一个存储累加和的变量 * 我们要获取到1-100范围内的 ...

  6. 05_Java基础语法_第5天(方法)_讲义

    今日内容介绍 1.方法基础知识 2.方法高级内容 3.方法案例 01方法的概述 * A: 为什么要有方法 * 提高代码的复用性 * B: 什么是方法 * 完成特定功能的代码块. 02方法的定义格式 * ...

  7. [建树(非二叉树)] 1106. Lowest Price in Supply Chain (25)

    1106. Lowest Price in Supply Chain (25) A supply chain is a network of retailers(零售商), distributors( ...

  8. 如何快速地编写和运行一个属于自己的 MapReduce 例子程序

    大数据的时代, 到处张嘴闭嘴都是Hadoop, MapReduce, 不跟上时代怎么行? 可是对一个hadoop的新手, 写一个属于自己的MapReduce程序还是小有点难度的, 需要建立一个mave ...

  9. Oracle 11G RAC For Windows 2008 R2部署手册(亲测,成功实施多次)

    总体规划 服务器规划 1.建议使用两台硬件配置一模一样的服务器来作为 RAC 环境的两个物理节点 2.服务器至少需要配置两块物理网卡 3.服务器规划表: 节点 主机名 本地磁盘大小 操作系统 内存大小 ...

  10. html实现鼠标悬停变成手型实现方式

    1.采用a标签实现的方式 <a href="javascript:void()">内容</a> 2.采用CSS实现的方式 // 变手形 oElement.s ...