Java8之新日期时间篇
文章目录
- 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
, 继而可以获得对应的LocalDateTime
。ZonedDateTime
可以作为一个转换的媒介
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之新日期时间篇相关推荐
- java8新日期时间类使用
java8之后提供了新的日期和时间相关类,接口和枚举,放在了java.time包下(之前旧的日期时间类放在java.util包),使设置日期时间更加方便.java8的新日期时间类的设计,借鉴了joda ...
- 高级JAVA开发必备技能:java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量)(JAVA 小虚竹)
技术活,该赏 点赞再看,养成习惯 大家好,我是小虚竹.之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来.答案是肯定的,谁让我宠粉呢.由于内容偏多(超十万字了) ...
- 【Java8新特性】关于Java8中的日期时间API,你需要掌握这些!!
写在前面 Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等.这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大.立志 ...
- 构造一个日期类java_Java8 新日期时间类(1)
Java.time 包的优势 使用Java8,新的日期时间API引入覆盖旧的日期时间API的以下缺点. 非线程安全 - java.util.Date不是线程安全的,因此开发者必须在使用日期处理并发性问 ...
- 学习笔记之-java8的新特性-函数式接口,lambda表达式,方法引用,Stream API,Optional类
1.Lambda表达式 用匿名内部类的方法去创建多线程1.new Thread2.参数传递new Runnable3.重写run方法4.在run方法中去设置线程任务5.调用start问题:我们最终目标 ...
- java8的新特性_Java8的
java8的新特性 Java8没有安排释放,直到2014年3月,但早期发行版本已经可用了一段时间. 一些最有趣的新功能是: 流 功能接口 默认方法 Lambdas Java时间 流 新的java.ut ...
- java获取时间的各种风格_Java8新特性之新日期API
早期的日期 API 在早期也就是 Java 8 之前,JDK 原生比较有名的有两个类: Date 类 Calendar 类 这两个类相对来说用起来是比较困难的,之前我们往往是用的第三方的库. 新日期 ...
- 静态方法:关于Java8中的日期时间API,你需要掌握这些!!
Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等.这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大.立志成为架构师 ...
- JDK1.8,Java8常用新特性
A.Lamdba表达式 1.Java8概述 Java8,也就是jdk1.8,是意义深远的一个新版本 是Java5之后一个大的版本升级,让Java语言和库仿佛获得了新生 新特性包含: a.随着大数据的兴 ...
最新文章
- 深入入门正则表达式(java) - 匹配原理 - 1 - 引擎分类与普适原则
- 接入 SDK 结果翻车了?了解 SDK 的那些事
- 管理信息系统属于计算机的什么应用领域,全国2013自考《管理系统中计算机应用》...
- CentOSLinux安装Docker容器
- php 跳转到另外一个php,PHP: 其他变更 - Manual
- flutter持久化_开源项目【WanAndroid_Flutter】玩安卓 Flutter 版
- 终于!孙宇晨和巴菲特吃上 3153 万元的晚餐,还送了一个比特币!
- 拓端tecdat|R语言使用马尔可夫链对营销中的渠道归因建模
- matlab qpsk调制程序,MATLAB QPSK调制及解调.doc
- WebStorm中文乱码解决代码
- 全国省市区java_Jsoup获取全国地区数据(省市县镇村)
- html设置背景颜色宽度,如何设置div的背景色和高度 CSS示例代码
- 标准模式(standard mode) 和 兼容模式(qurik mode)
- 《指弹:November.28th》
- 宇宙无敌第一IED Visual studio 常用快捷键使用
- MATLAB三维画图函数使用总结
- Application.streamingAssetsPath在android和ios和pc上的读取
- 【NOIP2018提高组D2T2】填数游戏
- Chrome浏览器通过EasyPlayer播放多路flv视频流后浏览器崩溃是什么原因?
- jquery系列之-ajaxSubmit()提交表单示例