文章目录

  • 1.为什么需要引入新的日期和时间?
  • 2.新的日期和时间API设计原则
  • 3.Java8中的日期和时间API包含的包
  • 4.常用类以及方法
    • 4.1LocalDate
      • 4.1.1常用API
      • 4.1.2案例展示
      • 4.1.3拓展使用
    • 4.2LocalTime
    • 4.3LocalDateTime
      • 4.3.1常用API
      • 4.3.2案例展示
      • 4.3.3拓展使用
    • 4.4Instant
      • 4.4.1常用API
      • 4.4.2概念关系
    • 4.5Period
      • 4.5.1常用API
      • 4.5.2案例使用
    • 4.6Duration
      • 4.6.1常用API
      • 4.6.2案例展示
    • 4.7DateTimeFormatter
      • 4.7.1常用API
      • 4.7.2案例展示
    • 4.8ZoneId和ZonedDateTime

1.为什么需要引入新的日期和时间?

  • Date如果不格式化,打印出的日期可读性差

    Date date = new Date();
    Wed May 13 16:06:28 CST 2020
    LocalDate localDate = LocalDate.now();
    2020-05-13
    
  • Java8之前所有的日期类都是可变的, 这就导致了线程不安全

  • Java的日期和时间类的定义不一致,在java.util和java.sql中都包含日期类

  • java.util.Date同时包含日期和时间,但是java.sql中只包含日期,将其纳入java.sql中是不合适的,而且最糟糕的是:着两个类中的日期类的名字都是一样的

  • 对于时间、时间戳、格式化及解析,没有一些明确定义的类, 而且对于格式化和解析的需求,Java中有java.text.DateFormat抽象类,但是通常我们用的是SimpleDateFormat

  • 日期不支持国际化,没有时区支持,即使Java引入java.util.Calendar和java.uril.TimeZone类,但是问题依然存在

  • 使用SimpleDateFormat对时间进行格式化, 但SimpleDateFormat是线程不安全的:

    • format方法中的calendar是共享变量,并且这个共享变量没有做线程安全控制,当多个线程同时使用相同的SimpleDateFormat对象进行格式化的时候,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值,另外一个线程马上把设置的time值修改了导致返回的格式化时间可能是错误的
    • SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendat).getTime()方法来解析,alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了:
      • 填充日期对象cal的属性值
      • 使用calb中属性设置cal
      • 返回设置好的cal对象,但是这三步不是原子操作
  • `Date和Calendar都是可变的.能把2014年3月18日修改成4月18日意味着什么呢?这种设计会被拖入维护的噩梦

2.新的日期和时间API设计原则

  • 不变性:新的日期/时间API中,所有的类都是不可变的,实现了线程安全;
  • 关注点分离:新的API中将人可读的日期时间和机器时间(unix timestamp)明确分离,它为日期(Date)、时间(Time)、日期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类
  • 清晰明了:新的API中,方法都被明确定义用以完成相同的行为,例如,想要拿到当前实例,可以用new()方法,在所有的类方法中都实现了formate()和parse()方法,不再是之前用单独一个类去解决,而且新的API中所有的类都使用了工厂模式和策略模式;
  • 实用性:所有新的日期和时间API类都实现了一系列方法用以完成通用的需求,例如:加、减、格式化、解析、从日期或时间中提取单独部分等等;
  • 可扩展性:新的日期/时间API是基于[国际标准ISO 8601](https://baike.baidu.com/item/ISO 8601),其实我们也是可以将其用于非IOS的日历上

3.Java8中的日期和时间API包含的包

  • java.time包:这是新的Java日期/时间API的基础包,所有的主要基础类都是该包的一部分,例如:LocalDate、LocalTime、LocalDateTime、Instant、Period、Duration等类。这些类都是线程安全的
  • java.time.chrono包:这个包为非ISO的日历标准定义了一些泛化的API,我们可以拓展AbstractChronology来创建自己的日历标准
  • java.time.formate包:这个包包含能够格式化和解析日期时间对象的类,在绝大数情况下,我们不应该直接使用它,因为java.time包中相应的类已经提供了格式化和解析的方法
  • java.time.temporal包:这个包含一些时态对象,可以用其找出关于某个日期/时间对象的某个特定日期或时间,比如说找到某个月的第一天或最后一天,可以根据withXXX的格式进行区分
  • java.time.zone包:这个包支持不同的时区以及相关规则的类

4.常用类以及方法

我们使用比较频繁地可能是以下几个类:

  • Instant: 代表的是时间戳,时刻
  • LocalDate:不包含具体时间(时分秒)的日期
  • LocalTime: 不包含日期的时间
  • LocalDateTime: 包含了日期以及时间
  • Period: 计算日期差,用于LocalDate之前的比较
  • Duration: 计算日期时间差,用于LocalDateTime之间的比较,也可用于Instant之间的比较
  • ChronoUnit(java.time.temporal): 用于比较所有的单位时间的工具类
  • 时区: ZoneId, ZoneOffset
  • 带时区的日期和时间: ZonedDateTime
  • DateTimeFormatter(java.time.format): 日期格式化器

4.1LocalDate

LocalDate是不变的日期时间对象代表一个日期,往往被视为年月日。

4.1.1常用API

方法 描述
static LocalDate now() 从默认时区的系统时钟获取当前日期
static LocalDate of(int year, int month, int dayofMonth) 从一年,一个月和一天获得一个LocalDate的实例
int get(TemporalField field) 从这个日期时间作为一个int获取指定字段的值,一般使用实现类ChronoField
int getYear() 获取年份字段
int getMonthValue() 获取月份
int getDayofMonth() 获取当月的第几天,一般用这个方法获取日
String format(DateTimeFormatter formatter) 格式化日期,日期转String
static LocalDate parse(CharSequence text, DateTimeFormatter formatter) 字符串转日期
static LocalDateTime parse(CharSequence text) 获得LocalDate实例从一个字符串
int compareTo(chronoLocalDate other) 将此日期与另一个日期比较
boolean isAfter(ChronoLocalDate other) 检查此日期是否在指定日期之后
boolean isBefore(ChronoLocalDate other) 检查此日期是否在指定日期之前
boolean isEqual(ChronoLocalDate other) 检查此日期是否等于指定日期
LocalDate plus(long amountToAdd, TemporalUnit unit) 返回此日期的一个副本, 添加指定的TemporalUnit。
LocalDate minusDays(long daysToSubtract) 返回此LocalDate的副本,并减去指定的天数(年份和月份类似)
LocalDate plusDays(long daysToAdd) 返回此LocalDate的副本,并增加指定的天数(年份和月份类似
long until(Temporal endExclusive, TemporalUnit unit) 计算时间的量,直到指定单元的另一个日期为止
ZonedDateTime atStartofDay(ZoneId zone) 根据时区中的规则,在最找的有效时间内从此日期返回划分的日期时间
LocalDate with(TemporalAdjuster adjuster) 返回此日期的调整副本
LocalDate with(TemporalField field, long newValue) 给字段的字段设置新值
LocalDate withYear(int year) 返回此日期的副本与年更改。
LocalDate withMonth(int month) 返回此日期的副本与更改的月份
LocalDate withDayOfMonth(int dayOfMoth) 返回此日期的副本与月更改日期。
String toString() 输出该日期时间为字符串

4.1.2案例展示

        LocalDate date = LocalDate.of(2022, 1, 1);LocalDate date2 = LocalDate.of(2022, 2, 1);//获取日期内容信息System.out.println(date);System.out.println(date.getYear()); = localDate.get(ChronoField.YEAR) System.out.println(date.getMonthValue()); = localDate.get(ChronoField.MONTH_OF_YEAR)System.out.println(date.getDayOfMonth()); = localDate.get(ChronoField.DAY_OF_MONTH)System.out.println(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));LocalDate parse = LocalDate.parse("2023-01-19", DateTimeFormatter.ofPattern("yyyy-MM-dd"));System.out.println(parse);//日期比较System.out.println(date.compareTo(date2));System.out.println(date.isAfter(date2));System.out.println(date.isBefore(date2));System.out.println(date.equals(date2));//日期加运算System.out.println(date.plusYears(1)) = date.plus(1, ChronoUnit.YEARS)System.out.println(date.plusMonths(1)) = date.plus(1, ChronoUnit.MONTHS)System.out.println(date.plusDays(1)) = date.plus(1, ChronoUnit.DAYS)//日期减运算System.out.println(date.minusYears(1));System.out.println(date.minusMonths(1));System.out.println(date.minusDays(1));//日期间隔运算,ChronoUnit枚举是TemporalUnit的实现类, 还可以计算时分秒等System.out.println(date.until(date2, ChronoUnit.YEARS));System.out.println(date.until(date2, ChronoUnit.MONTHS));System.out.println(date.until(date2, ChronoUnit.DAYS));//调整年份,月,日LocalDate date = LocalDate.of(2015, 1, 1);LocalDate newDate = localDate.with(ChronoField.YEAR, 2018) =>2018-01-01 和date.withYear是等价的System.out.println(date.withYear(2018)); => 2018-01-01 System.out.println(date.withMonth(5)); => 2015-05-01System.out.println(date.withDayOfMonth(2)); => 2015-01-02System.out.println(date.withDayOfYear(35)); => 2015-02-04

4.1.3拓展使用

  • 和Date之间的相互转换

        public Date localDate2Date(LocalDate localDate){ZonedDateTime zdt = localDate.atStartOfDay(ZoneId.systemDefault());return Date.from(zdt.toInstant());}public LocalDate date2LocalDate(Date date) {ZonedDateTime zdt = date.toInstant().atZone(ZoneId.systemDefault());return zdt.toLocalDate();}
    
  • 调整日期 LocalDate with(TemporalAdjuster adjuster), 使用TemporalAdjusters类:

          //获取这个月的第一天, 以及localDate获取第一天并转Date(其他类似)System.out.println(localDate.with(TemporalAdjusters.firstDayOfMonth()));Date startDate = Date.from(localDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay(ZoneId.systemDefault()).toInstant());//获取这个月最后一天System.out.println(localDate.with(TemporalAdjusters.lastDayOfMonth()));//获取上个月第一天获取上个月最后一天LocalDate lastMonathLocalDate = localDate.minusMonths(1);......//获取今年第一天System.out.println(localDate.with(TemporalAdjusters.firstDayOfYear()));//获取今年最后一天System.out.println(localDate.with(TemporalAdjusters.lastDayOfYear()));
    

4.2LocalTime

LocalTime是不变的日期时间对象代表一个时间,往往被视为小时分钟秒,方法使用借鉴LocalDate即可

4.3LocalDateTime

LocalDate是不变的日期时间对象代表一个日期时间,往往被视为年、月、日、时、分、秒。

4.3.1常用API

其实方法跟LocalDate差不多, 只是多了一些时分秒的操作,这里就列举一些LocalDateTime的API

方法 描述
static LocalDateTime now() 从默认时区的系统时钟获取当前日期时间
of(int year, int month, int dayOfMonth, int hour, int minute, int second) 获得LocalDateTime从年,月,日,小时,分钟和秒的实例,设置纳秒为零
atZone(ZoneId zone) 结合时间与时区来创建一个ZonedDateTime
int get(TemporalField field) 从这个日期时间作为一个int获取指定字段的值, 一般使用实现类ChronoField
int getYear() 获取年度字段。
int getMonthValue() 从1到12得到一个月的时间字段。
int getDayOfMonth() 获取月字段的一天。
int getHour() 获取小时字段
int getMinute() 获取分钟字段
int getSecond() 获取秒
boolean isAfter(ChronoLocalDateTime<?> other) 检查此日期是否在指定日期之后
boolean isBefore(ChronoLocalDateTime<?> other) 检查此日期是否在指定日期之前
boolean isEqual(ChronoLocalDateTime<?> other) 检查此日期是否等于指定日期
LocalDateTime minus(long amountToSubtract, TemporalUnit unit) 返回日期时间副本, 减少指定的单位数量
LocalDateTime minusHours(long Hours) 返回此LocalDateTime的副本,以减少的小时数(年月日类似)
LocalDateTime minusMinutes(long minutes) 返回此LocalDateTime的副本,以减少的分钟数
LocalDateTime minusSeconds(long seconds) 返回此LocalDateTime的副本,以减少的秒数
LocalDateTime plus(long amountToAdd, TemporalUnit unit) 返回日期时间副本, 增加指定的单位数量
LocalDateTime plusHours(long Hours) 返回此LocalDateTime的副本,以增加的小时(年月日等类似)
LocalDateTime until(Temporal endExclusive, TemporalUnit unit) 计算时间的量,直到指定单元的另一个日期时间
LocalDateTime with(TemporalField field, long newValue) 将此日期时间的副本与指定的字段设置为一个新值,一般使用实现类ChronoField
LocalDateTime with(TemporaAdjuster adjuster) 返回此日期时间的调整副本
LocalDate toLocalDate() 获取这个日期时间LocalDate的一部分
LocalTime toLocalTIme() 获取这个日期时间LocalTime的一部分

4.3.2案例展示

         //测试LocalDateTime date = LocalDateTime.of(2010, 5, 5, 5, 5, 5);LocalDateTime date2 = LocalDateTime.of(2010, 5, 5, 5, 5, 5);System.out.println(date.getYear()); = date.get(ChronoField.YEAR)System.out.println(date.getMonthValue());System.out.println(date.getDayOfMonth());System.out.println(date.getHour());System.out.println(date.getMinute());System.out.println(date.getSecond());System.out.println(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));LocalDate parse = LocalDate.parse("2023-01-19", DateTimeFormatter.ofPattern("yyyy-MM-dd"));System.out.println(parse);//日期比较System.out.println(date.compareTo(date2));System.out.println(date.isAfter(date2));System.out.println(date.isBefore(date2));System.out.println(date.equals(date2));//加运算System.out.println(date.plusYears(1));System.out.println(date.plusMonths(1));System.out.println(date.plusDays(1));System.out.println(date.plusHours(1));System.out.println(date.plusMinutes(1));System.out.println(date.plusSeconds(date.getSecond()));//减运算System.out.println(date.minusYears(1));System.out.println(date.minusMonths(1));System.out.println(date.minusDays(1));System.out.println(date.minusHours(1));System.out.println(date.minusMinutes(1));System.out.println(date.minusSeconds(1));   //转换LocalDate,LocalTimeSystem.out.println(date.toLocalDate());System.out.println(date.toLocalTime());//日期间隔运算,ChronoUnit枚举是TemporalUnit的实现类System.out.println(date.until(date2, ChronoUnit.YEARS));System.out.println(date.until(date2, ChronoUnit.MONTHS));System.out.println(date.until(date2, ChronoUnit.DAYS));System.out.println(date.until(date2, ChronoUnit.HOURS));System.out.println(date.until(date2, ChronoUnit.MINUTES));System.out.println(date.until(date2, ChronoUnit.SECONDS));//日期调整date.with(ChronoField.YEAR, 2020).....

4.3.3拓展使用

  • 和Date之间相互转换

         public Date localDateTime2Date(LocalDateTime localDateTime){ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());return Date.from(zdt.toInstant());}public LocalDateTime date2LocalDateTime(Date date) {ZonedDateTime zdt = date.toInstant().atZone(ZoneId.systemDefault());return zdt.toLocalDateTime();}
    
  • 调整日期,参考LocalDate

4.4Instant

4.4.1常用API

方法 描述
static Instant now() 从系统时钟中获得当前时刻。
ZonedDateTime atZone(ZoneId zone) 结合即时时区创建 ZonedDateTime
long toEpochMilli() 把这瞬间的毫秒数从1970-01-01t00:00:00z时代。
long getEpochSecond() 从1970-01-01t00:00:00z java时代得到的秒数。
long until(Temporal endExclusive, TemporalUnit unit) 计算时间的量,直到指定单元的另一个时刻为止。

4.4.2概念关系

计算机存储的当前时间,本质上是一个不断递增的整数。Java提供的System.currentTimeMillis()返回的就是以毫秒表示的当前时间戳。这个时间戳在java.time中以Instant类型表示,我们用Instant.now()获取当前时间戳,效果System.currentTimeMillis()类似:

         Instant now = Instant.now();System.out.println(System.currentTimeMillis()); => 1617873014216System.out.println(now.getEpochSecond());//秒 => 1617873014System.out.println(now.toEpochMilli());//毫秒 => 1617873014216

实际上,Instant内部只有2个核心字段:

public final class Instant implements ... {private final long seconds;private final int nanos;
}

一个是以秒为单位的时间戳,一个是更精确的纳秒精度。它和System.currentTimeMillis()返回的long相比,只是多了更高精度的纳秒。既然Instant就是时间戳,那么,给它附加上一个时区,就可以创建出ZonedDateTime

   ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.systemDefault());System.out.println(zonedDateTime);2020-04-08T17:34:00.825+08:00[Asia/Shanghai]

可见,对于某一个时间戳或者时间,给它关联上指定的ZoneId,就得到了ZonedDateTime, 继而可以获得对应的LocalDateTimeZonedDateTime可以作为一个转换的媒介

4.5Period

Period类用来度量两个日期之间年、月、日的间隔值

注意: 如果是指定某年,某月,某日相差总数,请使用LocalDate的until(Temporal endExclusive, TemporalUnit unit)方法

4.5.1常用API

方法 描述
static Period of(int years, int months, int days) 获得Period代表数年、月、日
static Period between(LocalDate start, LocalDate end) 获得由年数Period月,和两个日期之间的天数
int getYears() 获取此期间的年数
int getMonths() 获取此期间的月份
int getDays() 获取此期间的天数
long toTotalMonths() 获取此期间的总月数
boolean isNegative() 检查这一时期的三个单位是否都是负的
Period minus(TemporalAmount temp) 返回此期间的一个副本,与指定的周期减去
Period minusYears(long yearsToSubtract) 返回此期间的一个副本,用指定的年份减去(月份和日类似)
Period plusYears(long yearsToAdd) 返回此期间的一个副本,用指定的年份加上(月份和日类似)
Period withYears(int years) 返回此期间的一个副本,指定年数
Perod withMonths(int months) 返回此期间的一个副本,指定月份
Period withDays(int days) 返回此期间的一个副本,指定日数

4.5.2案例使用

     LocalDate startDate = LocalDate.of(2019, 2, 2);LocalDate endDate = LocalDate.of(2020, 3, 28);//日期间隔内容获取Period period = Period.between(startDate, endDate);System.out.println(period.getYears()); => 1System.out.println(period.getMonths()); => 1System.out.println(period.getDays()); => 26System.out.println(period.toTotalMonths()); =>13System.out.println(period.isNegative()); => false: endDate>startDate, true: endDate<startDate//添加减少操作Period period1 = period.minus(Period.of(1, 2, 5)); => 批量扣减: 0, -1, 21System.out.println(period.plusYears(1));System.out.println(period.plusMonths(1));System.out.println(period.plusDays(1).getDays());System.out.println(period.minusYears(1));........//指定操作System.out.println(period.withYears(3).getYears()); => 3........

4.6Duration

Duration类用来度量秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性

注意: 如果是指定某年,某月,某日相差总数,请使用LocalDate的until(Temporal endExclusive, TemporalUnit unit)方法

4.6.1常用API

方法 描述
static Duration of(long amount, TemporalUnit unit) 获取Duratiion代表指定的单位数量,一般使用实现类ChronoUnit指定单位
static Duration between(Temporal start, Temporal end) 获得Duration表示两个时间对象之间的时间 => 和LocalDate不同,参数是接口,除了LocalDateTime,还可以指定时间戳Instant等…
int get(TemporalUnit unit) 获取所请求单元的值,一般使用实现类ChronoUnit指定单位
long toDays() 获取此期间的天数
long toHours() 获取此期间的几个小时数
long toMinutes() 获取此期间的分钟数
long getSeconds 获取此期间的秒数
long toMillis() 将此持续时间转换为毫秒内的总长度
long getNano 得到的纳秒数
plus(Duration duration) 返回此持续时间的副本,添加指定的持续时间。
plus(long amountToAdd, TemporalUnit unit) 返回此持续时间的副本,添加指定的持续时间。
minus(Duration duration) 返回此持续时间的副本,用指定的持续时间减去。
minus(long amountToAdd, TemporalUnit unit) 返回此期间的一个副本,用指定的持续时间减去。

4.6.2案例展示

        LocalDateTime localDateTime = LocalDateTime.of(2019, 2, 2, 10, 10, 10);LocalDateTime localDateTime2 = LocalDateTime.of(2020, 3, 3, 20, 20, 20);Duration between = Duration.between(localDateTime, localDateTime2);//获取间隔时间System.out.println(between.toDays());System.out.println(between.toHours());System.out.println(between.toMinutes());System.out.println(between.getSeconds());System.out.println(between.toMillis());System.out.println(between.getNano());  //增加或者减少等操作between.plus(1, ChronoUnit.Days) ...........between.minus(1, ChronoUnit.Days) .......//结合InstantInstant start = Instant.now();try {//代码..........Thread.currentThread().sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}Instant end = Instant.now();Duration between = Duration.between(start, end);//秒System.out.println(between.getSeconds());//毫秒System.out.println(between.toMillis());

异常处理:

//间隔增加年抛出异常
betwueen.plus(1, ChronoUnit.YEARS)
java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration


进去了Duration的plus方法,这行出现了问题, 再进入到该方法中,发现有进行顺序对比


原来是isDurationEstimated方法ordinal< Days的ordinal才会通过,查看Enum类的ordinal属性, 就是枚举类中的排列顺序,从0开始

ChronoUnit中,我们指定在Days之前的枚举就行了

4.7DateTimeFormatter

日期时间对象格式化和解析

4.7.1常用API

方法 描述
static DateTimeFormatter ofPattern(String pattern) 创建一个格式化程序使用指定的模式
static DateTimeFormatter ofPattern(String pattern,Locale locale) 获得由年数Period月,和两个日期之间的天数
String format(TemporalAccessor temporal) 使用格式化程序格式的日期时间对象
TemporalAccessor parse(CahrSequence text) 充分分析文本产生的时空对象
TemporalAccessor parse(CahrSequence text, ParsePostion position) 分析文本使用此格式化程序,提供对文本位置的控制
Strinig format(DateTimeFormatter formatter) 使用指定的格式的日期格式(LocalDate, LocalDateTime)
static LocalDate parse(CharSequence text, DateTimeFormatter formatter) 获得LocalDate实例从使用特定格式的字符串
static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) 获得LocalDateTime实例从使用特定格式的字符串

除了方法,DateTimeFormatter还初始化了很多静态字段对象, 比如ISO_LOCAL_DATE(yyyy-mm-dd)、BASIC_ISO_DATE

4.7.2案例展示

         //LocalDateLocalDate localDate = LocalDate.of(2014, 2, 2);String format = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));LocalDate parse = LocalDate.parse("2018-06-06", DateTimeFormatter.ofPattern("yyyy-MM-dd"));//LocalDateTimeLocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.of(10, 10, 10));String format1 = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));LocalDateTime parse1 = localDateTime.parse("2018-06-06 10:10:10", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

4.8ZoneId和ZonedDateTime

之前看到的日期和时间的种类都不包含时区信息,时区的处理是新版日期和时间API新增加的重要功能,使用新版日期和时间API被极大的简化了。新的java.time.ZoneId类是老板java.util.TimeZone的替代品。

时区是按照一定的规则将区域划分成的标准时间相同的区间。在ZoneRules这个类中包含了40个这样的实例。你可以简单地通过调用ZoneId的getRules()得到指定时区的规则。每个特定ZoneId对象都由一个地区ID标识,地区ID都为”{区域}/{城市}“的格式,比如:

ZoneId romeZone = ZoneId.of("Europe/Rome"); java

一旦得到一个ZoneId对象, 你就可以把LocalDate, LocalDateTime或者是Instant对象整合起来,构造为一个ZonedDateTime实例,它代表了相对于指定时区的时间点:

LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
ZonedDateTime zdt1 = date.atStartOfDay(romeZone); LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
ZonedDateTime zdt2 = dateTime.atZone(romeZone); Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone);

ZonedDateTIme的组成部分:

通过ZoneId->下面的romeZone,你还可以将LocalDateTime转换为Instant:

LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);

你也可以通过反向的方式得到LocalDateTime对象:

Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);

参考:
https://www.liaoxuefeng.com/wiki/1252599548343744/1298613246361634
https://docs.oracle.com/javase/8/docs/api/index.html

Java8之新日期时间篇相关推荐

  1. java8新日期时间类使用

    java8之后提供了新的日期和时间相关类,接口和枚举,放在了java.time包下(之前旧的日期时间类放在java.util包),使设置日期时间更加方便.java8的新日期时间类的设计,借鉴了joda ...

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

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

  3. 【Java8新特性】关于Java8中的日期时间API,你需要掌握这些!!

    写在前面 Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等.这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大.立志 ...

  4. 构造一个日期类java_Java8 新日期时间类(1)

    Java.time 包的优势 使用Java8,新的日期时间API引入覆盖旧的日期时间API的以下缺点. 非线程安全 - java.util.Date不是线程安全的,因此开发者必须在使用日期处理并发性问 ...

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

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

  6. java8的新特性_Java8的

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

  7. java获取时间的各种风格_Java8新特性之新日期API

    早期的日期 API 在早期也就是 Java 8 之前,JDK 原生比较有名的有两个类: Date 类 Calendar 类 这两个类相对来说用起来是比较困难的,之前我们往往是用的第三方的库. 新日期 ...

  8. 静态方法:关于Java8中的日期时间API,你需要掌握这些!!

    Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等.这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大.立志成为架构师 ...

  9. JDK1.8,Java8常用新特性

    A.Lamdba表达式 1.Java8概述 Java8,也就是jdk1.8,是意义深远的一个新版本 是Java5之后一个大的版本升级,让Java语言和库仿佛获得了新生 新特性包含: a.随着大数据的兴 ...

最新文章

  1. 深入入门正则表达式(java) - 匹配原理 - 1 - 引擎分类与普适原则
  2. 接入 SDK 结果翻车了?了解 SDK 的那些事
  3. 管理信息系统属于计算机的什么应用领域,全国2013自考《管理系统中计算机应用》...
  4. CentOSLinux安装Docker容器
  5. php 跳转到另外一个php,PHP: 其他变更 - Manual
  6. flutter持久化_开源项目【WanAndroid_Flutter】玩安卓 Flutter 版
  7. 终于!孙宇晨和巴菲特吃上 3153 万元的晚餐,还送了一个比特币!
  8. 拓端tecdat|R语言使用马尔可夫链对营销中的渠道归因建模
  9. matlab qpsk调制程序,MATLAB QPSK调制及解调.doc
  10. WebStorm中文乱码解决代码
  11. 全国省市区java_Jsoup获取全国地区数据(省市县镇村)
  12. html设置背景颜色宽度,如何设置div的背景色和高度 CSS示例代码
  13. 标准模式(standard mode) 和 兼容模式(qurik mode)
  14. 《指弹:November.28th》
  15. 宇宙无敌第一IED Visual studio 常用快捷键使用
  16. MATLAB三维画图函数使用总结
  17. Application.streamingAssetsPath在android和ios和pc上的读取
  18. 【NOIP2018提高组D2T2】填数游戏
  19. Chrome浏览器通过EasyPlayer播放多路flv视频流后浏览器崩溃是什么原因?
  20. jquery系列之-ajaxSubmit()提交表单示例

热门文章

  1. Java SE 基础(4) Java的语言特点
  2. [资源]--100张极简约的电脑桌面壁纸总有一张你喜欢
  3. gsoap中文文档(1.介绍)
  4. 比例模型 scale model
  5. Hadoop集群配置及运行
  6. 常用格式如何互相转换(jpg转png)
  7. ARMv8.1-M的一些特性
  8. 无法启动服务,错误1053
  9. Temporary failure in name resolution错误解决方法
  10. 智子社区上线FCoin、IDCM即将扬帆起航