Java8新特性(五)新日期时间的API
1、新时间日期APIjava.time – 包含值对象的基础包java.time.chrono – 提供对不同的日历系统的访问java.time.format – 格式化和解析时间和日期java.time.temporal – 包括底层框架和扩展特性java.time.zone – 包含时区支持的类说明:大多数开发者只会用到基础包和format包,也可能会用到temporal...
1、新时间日期API
- java.time – 包含值对象的基础包
- java.time.chrono – 提供对不同的日历系统的访问
- java.time.format – 格式化和解析时间和日期
- java.time.temporal – 包括底层框架和扩展特性
- java.time.zone – 包含时区支持的类
说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。
2、LocalDate、LocalTime、LocalDateTime
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。
方法 | 描述 |
now() / * now(ZoneId zone) | 静态方法,根据当前时间创建对象/指定时区的对象 |
of() | 静态方法,根据指定日期/时间创建对象 |
getDayOfMonth()/getDayOfYear() | 获得月份天数(1-31) /获得年份天数(1-366) |
getDayOfWeek() | 获得星期几(返回一个 DayOfWeek 枚举值) |
getMonth() | 获得月份, 返回一个 Month 枚举值 |
getMonthValue() / getYear() | 获得月份(1-12) /获得年份 |
getHour()/getMinute()/getSecond() | 获得当前对象对应的小时、分钟、秒 |
withDayOfMonth()/withDayOfYear()/ withMonth()/withYear() | 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象 |
plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours() | 向当前对象添加几天、几周、几个月、几年、几小时 |
minusMonths() / minusWeeks()/ minusDays()/minusYears()/minusHours() | 从当前对象减去几月、几周、几天、几年、几小时 |
2.1、LocalDate、LocalTime
开始使用新的日期和时间API时,你最先碰到的可能是LocalDate类。该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
你可以通过静态工厂方法of创建一个LocalDate实例。LocalDate实例提供了多种方法来 读取常用的值,比如年份、月份、星期几等,如下所示:
package java8;
import java.time.LocalDate;
public class DateTimeTest {
public static void main(String[] a) {
//获取当前日期
LocalDate now = LocalDate.now();
//获取指定年月日的localdate
LocalDate date = LocalDate.of(2018, 12, 24);
System.out.println("年:" + date.getYear());
System.out.println("月:" + date.getMonthValue());
System.out.println("几号:" + date.getDayOfMonth());
System.out.println("星期几:" + date.getDayOfWeek().getValue());
System.out.println("当年中的第几天:" + date.getDayOfYear());
System.out.println("当月的天数:"+date.lengthOfMonth());
System.out.println("当年的天数:"+date.lengthOfYear());
}
}
类似地,一天中的时间,比如13:45:20,可以使用LocalTime类表示。你可以使用of重载的两个工厂方法创建LocalTime的实例。第一个重载函数接收小时和分钟,第二个重载函数同时还接收秒。同LocalDate一样,LocalTime类也提供了一些getter方法访问这些变量的值,如下所示。
//表示11:30分
LocalTime time=LocalTime.of(11,30);
//11:30:50
LocalTime time2=LocalTime.of(11,30,50);
System.out.println("时:"+time2.getHour());
System.out.println("分:"+time2.getMinute());
System.out.println("秒:"+time2.getSecond());
LocalDate和LocalTime都可以通过解析代表它们的字符串创建。使用静态方法parse,你可以实现这一目的:
LocalDate date = LocalDate.parse("2018-12-24");
LocalTime time = LocalTime.parse("13:45:20");
你可以向parse方法传递一个DateTimeFormatter。该类的实例定义了如何格式化一个日期或者时间对象。
2.2、合并日期和时间
这个复合类名叫LocalDateTime,是LocalDate和LocalTime的合体。它同时表示了日期和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象构造。
//2017-05-29 11:30:50
LocalDateTime dateTime=LocalDateTime.of(2017,5,29,11,30,50);
LocalDateTime dateTime2=LocalDateTime.of(date,time2);
可以通过它们各自的atTime或者atDate方法,向LocalDate传递一个时间对象,或者向LocalTime传递一个日期对象的方式,你可以创建一个LocalDateTime对象。你也可以使用toLocalDate或者toLocalTime方法,从LocalDateTime中提取LocalDate或LocalTime对象。
LocalDateTime ldt=time2.atDate(date);
LocalDateTime dateTime3=date.atTime(time2);
LocalDate localDate = dateTime3.toLocalDate();
LocalTime localTime=dateTime3.toLocalTime();
3、 Instant 时间戳
在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机处理。在UNIX中,这个数从1970年开始,以秒为的单位;同样的,在Java中,也是从1970年开始,但以毫秒为单位。
java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间单位。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。(1 ns = 10-9 s) 1秒 = 1000毫秒 =10^6微秒=10^9纳秒。
方法 | 描述 |
now() | 静态方法,返回默认UTC时区的Instant类的对象 |
ofEpochMilli(long epochMilli) | 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象 |
atOffset(ZoneOffset offset) | 结合即时的偏移来创建一个 OffsetDateTime |
toEpochMilli() | 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳 |
- 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
作为人,我们习惯于以星期几、几号、几点、几分这样的方式理解日期和时间。毫无疑问, 这种方式对于计算机而言并不容易理解。新的java.time.Instant类是以Unix元年时间(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的秒数来表示时间。可以通过向静态工厂方法ofEpochSecond传递一个代表秒数的值创建一个该类的实例。静态工厂方法ofEpochSecond还有一个增强的重载版本,它接收第二个以纳秒为单位的参数值,对传入作为秒数的参数进行调整。一旦得到Instant对象,你就可以像之前的LocalDate和LocalTime一样获取该时间的各个信息。
//获取当前时间的instant
Instant now_instant=Instant.now();
//传入秒得到instant
Instant instant=Instant.ofEpochSecond(100);
//传入毫秒
Instant instant2=Instant.ofEpochMilli(100000);
now.getDayOfMonth();
now.getDayOfYear();
now.getMonthValue();
now.getYear();
now.lengthOfYear();
4、Duration 和 Period
- Duration:用于计算两个“时间”间隔
- Period:用于计算两个“日期”间隔
Duration类主要用于以秒和纳秒衡量时长。Duration类的静态工厂方法between用于创建两个时间之间的时长。
你可以创建两个LocalTime对象、两个LocalDateTime或者两个Instant对象之间的duration。
//创建两个localTime之间的时长对象
Duration duration = Duration.between(LocalTime.of(19, 20), LocalTime.of(19, 30));
//获取相差多少秒
System.out.println(duration.getSeconds());
//创建两个LocalDateTime之间的时长对象
Duration duration2 = Duration.between(LocalDateTime.of(2017, 5, 29, 19, 20), LocalDateTime.of(2017, 5, 29, 19, 30));
//获取相差多少秒
System.out.println(duration2.getSeconds());
//获取相差多少秒的绝对值
System.out.println(duration2.abs().getSeconds());
//相差多少天
System.out.println(duration2.toDays());
//相差多少时
System.out.println(duration2.toHours());
//相差多少分钟
System.out.println(duration2.toMinutes());
//相差多少毫秒
System.out.println(duration2.toMillis());
由于LocalDateTime和Instant是为不同的目的而设计的,一个是为了便于人阅读使用, 另一个是为了便于机器处理,所以你不能将二者混用。如果你试图在这两类对象之间创建 duration,会触发一个DateTimeException异常。此外,由于Duration类主要用于以秒和纳秒衡量时间的长短,你不能仅向between方法传递一个LocalDate对象做参数。
如果你需要以年、月或者日的方式对多个时间单位建模,可以使用Period类。使用该类的 工厂方法between,你可以使用得到两个LocalDate之间的时长,如下所示:
Period tenDays = Period.between(LocalDate.of(2017, 3, 8), LocalDate.of(2017, 3, 18));
Duration和Period类都提供了很多非常方便的工厂类,用于直接创建对应的实例。
//1天的时长转成小时
System.out.println(Duration.ofDays(1).toHours());
//1小时的时长转成分钟
System.out.println(Duration.ofHours(1).toMinutes());
//10天的时长
System.out.println(Period.ofDays(10).getDays());
5、日期的操纵
- TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。
- TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。
例如获取下个周日:
6、格式化与解析日期或时间
java.time.format.DateTimeFormatter 类:该类提供了三种格式化方法:
- 预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE
- 本地化相关的格式。如:ofLocalizedDate(FormatStyle.FULL)
- 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss E”)
方法 | 描述 |
ofPattern(String pattern) | 静态方法,返回一个指定字符串格式的DateTimeFormatter |
format(TemporalAccessor t) | 格式化一个日期、时间,返回字符串 |
parse(CharSequence text) | 将指定格式的字符序列解析为一个日期、时间 |
7、时区的处理
Java8 中加入了对时区的支持,带时区的时间为分别为:
ZonedDate、ZonedTime、ZonedDateTime
其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
例如 :Asia/Shanghai 等
- ZoneId:该类中包含了所有的时区信息
- getAvailableZoneIds() : 可以获取所有时区时区信息
- of(id) : 用指定的时区信息获取 ZoneId 对象
8、与传统日期处理的转换
更多推荐
所有评论(0)