• plusNanos(int offset):增加指定纳秒

减少相关的方法

  • minusYears(int offset):减少指定年

  • minusMonths(int offset):减少指定月

  • minusWeeks(int offset):减少指定周

  • minusDates(int offset):减少指定日

  • minusHours(int offset):减少指定时

  • minusMinuets(int offset):减少指定分

  • minusSeconds(int offset):减少指定秒

  • minusNanos(int offset):减少指定纳秒


@Testpublic void test07() {//增加时间量的方法 plusXXX系类的方法 返回的是一个新的日期对象LocalDateTime now = LocalDateTime.now();System.out.println(now);//可以给当前的日期增加时间量LocalDateTime newDate = now.plusYears(1);int year = newDate.getYear();System.out.println(year);System.out.println("================================");//减去时间量的方法minusXXX 系列的方法 返回的是一个新的日期对象LocalDate now1 = LocalDate.now();System.out.println(now1);LocalDate newDate2 = now1.minusDays(10);int dayOfMonth = newDate2.getDayOfMonth();System.out.println(dayOfMonth);} 

输出结果


2020-12-12T16:12:43.2282021================================2020-12-122 

[](

)指定年月日时分秒的方法

  • with(TemporalAdjuster adjuster):指定特殊时间

  • withYear(int year):指定年

  • withDayOfYear(int dayOfYear):指定日

  • withMonth(int month):指定月

  • withDayOfMonth(int dayOfMonth):指定日


@Testpublic void test08() {//指定某个日期的方法 with()方法LocalDate now2 = LocalDate.now();System.out.println(now2);LocalDate localDate = now2.withYear(2014);System.out.println(localDate);// TemporalAdjusters工具类,提供了一些获取特殊日期的方法LocalDate with = now2.with(TemporalAdjusters.firstDayOfMonth());System.out.println(with);LocalDate with1 = now2.with(TemporalAdjusters.firstDayOfNextMonth());System.out.println(with1);//获取这个月的第几个星期几是几号,比如 TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY)// 代表的意思是这个月的第二个星期五是几号LocalDate with2 = now2.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY));System.out.println(with2);} 

输出结果


2020-12-122014-12-122020-12-012021-01-012020-12-11 

[](

)将日期格式化为字符串的方法

  • format():格式化字符串

@Testpublic void test03() {//获取当前日期时分秒LocalDateTime now = LocalDateTime.now();//默认格式  年-月-日T时:分:秒System.out.println(now);//指定格式DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");//传入格式String dateStr = now.format(ofPattern);System.out.println(dateStr);} 

输出结果


2020-12-12T16:06:12.7052020年12月12日 16时06分12秒 

[](

)解析字符串为日期时间的方法

  • paser(String str):将一个日期字符串解析成日期对象,注意字符串日期的写法的格式要正确,否则解析失败

  • paser(String str, DateTimeFormatter formatter):将字符串按照参数传入的格式进行解析


@Testpublic void test06() {//给出一个符合默认格式要求的日期字符串String dateStr = "2020-01-01";//把日期字符串解析成日期对象 如果日期字符串时年月日 解析时用  LocalDateLocalDate parse = LocalDate.parse(dateStr);System.out.println(parse);System.out.println("===========================================");//给出一个符合默认格式要求的 时分秒 字符串String dateTimeStr = "14:20:30";//把 时分秒 字符串解析成时分秒对象LocalTime parse1 = LocalTime.parse(dateTimeStr);System.out.println(parse1);System.out.println("=========================================");//给出一个符合默认格式要求的 日期时分秒 字符串String str = "2018-12-12T14:20:30";//把 日期时分秒 字符串解析成时分秒对象LocalDateTime parse2 = LocalDateTime.parse(str);System.out.println(parse2);System.out.println("========================================");//给出一个自定义日期时分秒格式字符串String dateStr2 = "2020年12月12日 12:13:14";//给出一个自定义解析格式DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");//按照指定的格式去解析LocalDateTime parse3 = LocalDateTime.parse(dateStr2, formatter);System.out.println(parse3);} 

输出结果


2020-01-01===========================================14:20:30=========================================2018-12-12T14:20:30========================================2020-12-12T12:13:14 

TemporalAdjuster接口 - 时间调节器


前面看到的所有日期操作都是相对比较直接的。有的时候,你需要进行一些更加灵活复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,就需要时间调节器 TemporalAdjuster,可以更加灵活地处理日期。TemporalAdjusters 工具提供了一些通用的功能,并且你还可以新增你自己的功能。


@Testpublic void testTemporalAdjuster() {LocalDate now = LocalDate.now();//指定日期//对于一些特殊的日期,可以通过一个工具类TemporalAdjusters 来指定//见名知意,本月第一天TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfMonth();LocalDate with = now.with(temporalAdjuster);System.out.println(with);//下周周末TemporalAdjuster next = TemporalAdjusters.next(DayOfWeek.SUNDAY);LocalDate with1 = now.with(next);System.out.println(with1);System.out.println("===================================");LocalDate now1 = LocalDate.now();//自定义日期 - 下一个工作日LocalDate with2 = now1.with(new TemporalAdjuster() {@Override//参数 nowDate 当前的日期对象public Temporal adjustInto(Temporal nowDate) {//向下转型LocalDate date = (LocalDate) nowDate;if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {LocalDate localDate = date.plusDays(3);return localDate;} else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {LocalDate localDate = date.plusDays(2);return localDate;} else {LocalDate localDate = date.plusDays(1);return localDate;}}});System.out.println("下一个工作日是:" + with2);} 

输出结果


2020-12-012020-12-13===================================下一个工作日是:2020-12-14 

Duration类 - 用于计算两个“时间”间隔的类


Duration 表示一个时间段,Duration 包含两部分:seconds 表示秒,nanos 表示纳秒,它们的组合表达了时间长度。

因为 Duration 表示时间段,所以 Duration 类中不包含 now() 静态方法。注意,Duration 不包含毫秒这个属性。

Duration只能处理两个LocalTime, LocalDateTime, ZonedDateTime; 如果传入的是LocalDate,将会抛出异常

常用API

  • 静态方法 between():计算两个时间的间隔,默认是

  • toDays():将时间转换为以天为单位的

  • toHours():将时间转换为以时为单位的

  • toMinutes():将时间转换为以分钟为单位的

  • toMillis():将时间转换为以毫秒为单位的

  • toNanos():将时间转换为以纳秒为单位的


@Testpublic void test10() {//计算时间的间隔Instant start = Instant.now();for (int i = 0; i < 100000; i++) {// System.out.println(i);}Instant end = Instant.now();Duration duration = Duration.between(start, end);long l = duration.toNanos();//间隔的时间System.out.println("循环耗时:" + l + "纳秒");} 

输出结果


循环耗时:1000000纳秒 

Period类 - 用于计算两个“日期”间隔的类


Period 在概念上和 Duration 类似,区别在于 Period 是以年月日来衡量一个时间段。Duration 用于计算两个时间间隔,Period 用于计算两个日期间隔,所以 between() 方法只能接收 LocalDate 类型的参数。

  • 静态方法 between():计算两个日期之间的间隔

  • getYears():获取年份

  • getMonths():获取月份

  • getDays():获取天数


@Testpublic void test11() {//计算两个日期的间隔LocalDate birthday = LocalDate.of(2012, 12, 12);LocalDate now = LocalDate.now();//我从出生到现在,有多少岁,零几个月,几天//计算两个日期的间隔Period between = Period.between(birthday, now);int years = between.getYears();int months = between.getMonths();int days = between.getDays();System.out.println("玛雅人的地球都消灭了" + years + "年" + months + "月" + days + "天了...");} 

输出结果


玛雅人的地球都消灭了8年0月0天了... 

Instant 时间戳类


java.time.Instant 时间线上的一个瞬时点,承载纳秒级精度的 Unix 时间戳,其 String toString() 方法基于 ISO-8601 进行格式化。Instant 不承载时区信息。

获取对象的方法:now():注意默认获取出来的是默认时区,和我们相差八个小时(因为我们在东八时区

设置偏移量的方法:atOffset()

获取系统默认时区时间的方法:atZone():方法的参数是要一个时区的编号(可以通过时区编号类获取ZonedDateTime类的对象)

get系列的方法

  • getEpochSecond():获取从1970-01-01 00:00:00当前时间秒值

  • toEpochMilli():获取从1970-01-01 00:00:00当前时间毫秒值

  • getNano():把获取到的当前时间的秒数 换算成纳秒

ofEpoch系列方法

  • ofEpochSecond():给计算机元年增加秒数

  • ofEpochMilli():给计算机元年增加毫秒数


@Testpublic void test09() {//  Instant 时间戳类从1970 -01 - 01 00:00:00 截止到当前时间的毫秒值Instant now = Instant.now();System.out.println(now); //获取的是默认时区,获取的不是中国 的时区//获取当前时区的,我们可以添加偏移量,返回偏移过后的日期OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));System.out.println(offsetDateTime);System.out.println("===========================");//从1970 - 01 - 01 00:00:00 截止到当前时间的毫秒值long l = System.currentTimeMillis();System.out.println(l);long time = new Date().getTime();System.out.println(time);//JDK1.8 Instant 时间戳类从1970 -01 - 01 00:00:00 截止到当前时间的毫秒值Instant now1 = Instant.now();//toEpochMilli():从1970 -01 - 01 00:00:00 截止到当前时间间隔的毫秒值long l1 = now1.toEpochMilli();System.out.println(l1);//获取从1970 -01 - 01 00:00:00 截止到当前时间间隔的秒值long epochSecond = now1.getEpochSecond();System.out.println(epochSecond);System.out.println("==========================");//给计算机元年增加相应的时间量Date date = new Date(1000 * 60 * 60 * 24);System.out.println(date);//现在 给计算机元年增加相应的时间量//5. ofEpochSecond() 方法 给计算机元年增加秒数//ofEpochMilli() 给计算机元年增加毫秒数Instant instant = Instant.ofEpochMilli(1000 * 60 * 60 * 24);System.out.println(instant);//ofEpochSecond() 方法 给计算机元年增加秒数Instant instant1 = Instant.ofEpochSecond(60 * 60 * 24);System.out.println(instant1);} 

输出结果


2020-12-12T08:48:46.480Z2020-12-12T16:48:46.480+08:00===========================1607762926539160776292654016077629265401607762926==========================Fri Jan 02 08:00:00 CST 19701970-01-02T00:00:00Z1970-01-02T00:00:00Z 

Clock - 时钟系统


Clock 是时钟系统,用于查找当前时刻。你可以用它来获取某个时区下当前的日期或者时间。可以用 Clock 来替代旧的 System.currentTimeInMillis() 与 TimeZone.getDefault() 方法。


@Testpublic void testClock() {//系统默认时间Clock clock = Clock.systemDefaultZone();System.out.println(clock.instant().toString());//世界协调时UTCClock clock1 = Clock.systemUTC();//通过Clock获取当前时刻System.out.println("当前时刻为:" + clock1.instant());//获取clock对应的毫秒数,与System.currentTimeMillis()输出相同System.out.println(clock1.millis());System.out.println(System.currentTimeMillis());System.out.println(new Date(System.currentTimeMillis()).toString());//在clock基础上增加6000秒,返回新的ClockClock clock2 = Clock.offset(clock1, Duration.ofSeconds(6000));//纽约时间Clock clock3 = Clock.system(ZoneId.of("America/New_York"));System.out.println("Current DateTime with NewYork clock: " + LocalDateTime.now(clock3));System.out.println(clock3.millis());} 

输出结果


2020-12-12T09:05:07.025Z当前时刻为:2020-12-12T09:05:07.036Z16077639070361607763907036Sat Dec 12 17:05:07 CST 2020Current DateTime with NewYork clock: 2020-12-12T04:05:07.0401607763907041 

ZonedDate、ZonedTime、ZonedDateTime - 带时区的日期时间


这个三个类方法及用法和 LocalDate、 LocalTime、 LocalDateTime 基本一样,只不过ZonedDate、ZonedTime、ZonedDateTime 这三个带有特定时区

[](

)ZoneId - 世界时区类

Java 使用 ZoneId 来标识不同的时区。时区从基准 UTC 开始的一个固定偏移。ZoneId 的子类 ZoneOffset,代表了这种从伦敦格林威治零度子午线开始的时间偏移,也就是时差。

常用API

  • getAvailableZoneIds():获取世界各个地方的时区的集合

  • systemDefault():获取系统默认时区的ID

  • of(String zoneName):根据各个地区的时区ID名创建对象


@Testpublic void test13() {//ZoneID 世界时区类//获取世界各地的时区编号。Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();for (String availableZoneId : availableZoneIds) {System.out.println(availableZoneId);}System.out.println("=====================");//获取系统的默认时区编号ZoneId zoneId = ZoneId.systemDefault();System.out.println(zoneId);//获取其他国家的日期LocalDateTime now = LocalDateTime.now();//获取指定时区的日期时间ZoneId zoneId1 = ZoneId.of("Europe/Monaco");ZonedDateTime zonedDateTime = now.atZone(zoneId1);  //获得指定时区的当前时间System.out.println(zonedDateTime);System.out.println("=====================");//根据时区,获取该地区的日期LocalDateTime now1 = LocalDateTime.now(ZoneId.of("America/Phoenix"));  //获得指定时区的当前时间(不带时区信息)System.out.println(now1);} 

输出结果


America/TorontoAsia/SingaporeAustralia/LindemanAmerica/Los_AngelesSystemV/EST5EDTPacific/MajuroAmerica/Argentina/Buenos_AiresEurope/NicosiaPacific/GuadalcanalEurope/AthensUS/PacificEurope/Monaco=====================Asia/Shanghai2020-12-12T20:56:27.214+01:00[Europe/Monaco]=====================2020-12-12T05:56:27.225 

DateTimeFormatter类 - 用于解析日期字符串和格式化日期输出


DateTimeFormatter用于解析日期字符串和格式化日期输出,创建格式化器最简单的方法是通过 DateTimeFormatter 的静态工厂方法以及常量。

在java8之前,我们进行时间格式化主要是使用SimpleDateFormat,而在java8中,主要是使用DateTimeFormatter,java8中,预定义了一些标准的时间格式,我们可以直接将时间转换为标准的时间格式

常用API

  • ofPattern(“yyyy-MM-dd”):静态方法,通过给定格式获取对象

  • format():把一个日期对象的默认格式 格式化成指定的格式字符串


@Testpublic void test12() {// 之前格式化日期的类  new SimpleDateFormat()//JDK1.8 DateTimeFormatter//指定格式 静态方法 ofPattern()DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// DateTimeFormatter 自带的格式方法LocalDateTime now = LocalDateTime.now();//把日期对象,格式化成字符串String format = formatter.format(now);//刚才的方式是使用的日期自带的格式化方法String format1 = now.format(formatter);System.out.println(format);System.out.println(format1);} 

输出结果


2020-12-12 17:28:502020-12-12 17:28:50 

[](

)格式化输出 & 字符串解析

java.time.format.DateTimeFormatter 能够进行 TemporalAccessor 类型(包括:LocalDateLocalTimeLocalDateTimeZonedDateTime)的格式化输出。同时,LocalDateLocalTimeLocalDateTimeZonedDateTime 提供了静态的 parse 方法,能够进行字符串解析。

LocalDateLocalTimeLocalDateTimeZonedDateTime 允许基于类型的默认格式进行格式化输出和字符串解析。

| 类型 | 默认格式示例 |

| — | — |

| Instant | 2017-11-23T10:15:30.00Z |

| LocalDate | 2017-11-23 |

| LocalTime | 10:15:30 |

| LocalDateTime | 2017-11-23T10:15:30 |

| ZonedDateTime | 2017-11-23T10:15:30+01:00[Asia/Shanghai] |

使用SimpleDateFormat的正确姿势


方法一:在需要执行格式化的地方都新建SimpleDateFormat实例,使用局部变量来存放SimpleDateFormat实例


public static String formatDate(Date date) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(date);} 

这种方法可能会导致短期内创建大量的SimpleDateFormat实例,如解析一个excel表格里的字符串日期。

方法二:为了避免创建大量的SimpleDateFormat实例,往往会考虑把SimpleDateFormat实例设为静态成员变量,共享SimpleDateFormat对象。这种情况下就得对SimpleDateFormat添加同步。


private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static String formatDate(Date date) {synchronized (sdf) {return sdf.format(date);}} 

这种方法的缺点也很明显,就是在高并发的环境下会导致解析被阻塞。

方法三(推荐):要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。


private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {@Overrideprotected DateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");}};public static String formatDate(Date date) {return threadLocal.get().format(date);} 

Java8 日期时间类与Date类的相互转化


在转换中,我们需要注意,因为java8之前Date是包含日期和时间的,而LocalDate只包含日期,LocalTime只包含时间,所以与Date在互转中,势必会丢失日期或者时间,或者会使用起始时间。如果转LocalDateTime,那么就不存在信息误差。

[](

)Date和Instant互相转换


@Testpublic void test18() {//Date与Instant互相转换Instant instant  = Instant.now();Date date = Date.from(instant);System.out.println(date);Instant instant2 = date.toInstant();System.out.println(instant2);} 

输出结果


Sat Dec 12 21:18:13 CST 20202020-12-12T13:18:13.129Z 

[](

)Date与LocalDateTime互相转换


@Testpublic void test19() {//Date - LocalDateTimeDate date = new Date();System.out.println("current date: " + date);LocalDateTime localDateTime1 = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();System.out.println("localDateTime1: " + localDateTime1);LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());System.out.println("localDateTime2: " + localDateTime2);//LocalDateTime - DateLocalDateTime localDateTime = LocalDateTime.now();System.out.println("localDateTime: " + localDateTime);Date date1 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());System.out.println("date1: " + date1);} 

输出结果


current date: Sat Dec 12 21:27:47 CST 2020localDateTime1: 2020-12-12T21:27:47.592localDateTime2: 2020-12-12T21:27:47.592localDateTime: 2020-12-12T21:27:47.652date1: Sat Dec 12 21:27:47 CST 2020 

[](

)Date与LocalDate互相转换


@Testpublic void test20() {

Java8日期时间API,Java高级多线程面试相关推荐

  1. Java8————日期时间 API

    引言 Java 1.0 中引入了 Date 类,Java 1.1 中引入了 Calendar ,Java 8 中引入了java.time API ,这是 Java 非常吸引人的一次对时间日期的升级.它 ...

  2. 这么详细的Java8日期时间API,还不赶紧收藏起来(四):ZoneId和ZonedDateTime

    ZoneId java.time.ZoneId类表示时区ID 声明: public abstract class ZoneId implements Serializable ZoneId可以用于在I ...

  3. Java个人技术知识点总结(业务场景篇,java高级多线程面试

    Kafka宕机引发的高可用问题 问题要从一次Kafka的宕机开始说起. 笔者所在的是一家金融科技公司,但公司内部并没有采用在金融支付领域更为流行的RabbitMQ,而是采用了设计之初就为日志处理而生的 ...

  4. Java8 日期/时间(Date Time)API指南

    Java 8日期/时间( Date/Time)API是开发人员最受追捧的变化之一,Java从一开始就没有对日期时间处理的一致性方法,因此日期/时间API也是除Java核心API以外另一项倍受欢迎的内容 ...

  5. 6 日期字符串转日期_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...

    因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...

  6. java 包结构 枚举类_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...

    因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...

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

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

  8. 高级JAVA开发必备技能:java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量)(JAVA 小虚竹)

    技术活,该赏 点赞再看,养成习惯 大家好,我是小虚竹.之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来.答案是肯定的,谁让我宠粉呢.由于内容偏多(超十万字了) ...

  9. java8 日期api_我们多么想要新的Java日期/时间API?

    java8 日期api 当前的Java.net 民意测验问题是:" 对于用Java 8实现的JSR-310(新的日期和时间API)有多重要? "在我撰写本文时,将近150位受访者投 ...

最新文章

  1. Python中类方法、类实例方法、静态方法,私有属性和私有方法有何区别?
  2. 【kafka】kafka docker jmx 远程连接 跨容器
  3. VS2017 控件添加关联变量
  4. linux本地时间与utc不一致_辽宁无新增 | 北京新增本地确诊病例31例,中高考时间目前不做调整...
  5. SELinux 初探
  6. mysql on azure 链接_如何通过Python从Azure函数连接到azuremysql
  7. swift 将图片资源打包成Bundle
  8. Python数据结构与算法(3.3)——队列
  9. couchbase使用
  10. java程序员生日祝福语_给程序员的一句话祝福语
  11. 解决Jenkins集成SonarQube Scanner出现“Tasks support was removed in SonarQube 7.6.”的问题
  12. nvidia所有版本显卡驱动下载地址
  13. 最容易理解的Raft算法讲解
  14. Java---登录页面及其接口的实现
  15. 浅谈游戏《Cuphead茶杯头》
  16. 播放器ocx插件——自动获取MP3时长
  17. 安卓交流社区!阿里P8架构师的Android大厂面试题总结,详细的Android学习指南
  18. 用HEXO在Github建立个人博客
  19. Bitmap的图片压缩汇总
  20. android广播不同app,用广播(Broadcast)实现不同app之间的通信

热门文章

  1. 电子商务网站专题页策划的6个必杀技
  2. Openwrt firewall hotplug
  3. 友盟的9.4.0版本以上的集成测试
  4. 微信视频号可以换绑管理员了
  5. 爬虫大数据软件开发中程序员的伦理问题
  6. mysql 多实例 2019_mysql 多实例
  7. 从八大经典排序模版具体实现(包含自定义仿函数)到STL的sort函数灵活运用
  8. Java的运行机制与基本组成
  9. Python-猜词小游戏(优化)
  10. linux程序设计师什么,成为物联网工程师要学些什么?