综述
时间API分类概述
新的API: java.time,由5个包组成
-
java.time
- 包含值对象的基础包 -
java.time.chrono
- 提供对不同的日历系统的访问 -
java.time.format
- 格式化和解析时间和日期 -
java.time.temporal
- 包括底层框架和扩展特性 -
java.time.zone
- 包含市区支持的类
我们平时只会用到基础和format包,也可能用到temporal包,因此虽然新的API提供了多达68个新的公开类型,但是我们一般只会用到其中的三分之一
关键日期/时间概述
- 不可变性。借鉴于java.util.Calendar的前车之鉴,设计这个API的时候着重考虑了原有方法的不可变性,不允许任何更改,如果必须改变的话就会返回一个新的实例,所以我们必须捕获该方法的返回值
- 瞬间性。表示时间上的某个精确的时刻,使用从epoch开始计算的毫秒表示
关键API使用
Clock
他可以通过时区来获取当前的instant,日期和时间。Clock类可以用来代替System.currentTimeMillis()
和TimeZone.getDefault()
Clock clock=Clock.systemUTC();//获取格林尼治时间
System.out.println(clock.instant());//获取Instant类型数据,后面会讲到
System.out.println(clock.millis());//获取标准毫秒数
Instant
所谓的Instant累代表的是某个时间(有点类似与java.util.Date),他是精确到纳秒的,而Date是精确到毫秒的。instant表示的是时间线上的一点,而不需要任何上下文信息,例如:时区。概念上讲他只是简单的表示自1970年1月1日0是0分0秒开始的秒数。下面给去确定一个方法的运行时间长度的代码
Instant start = Instant.now();
doSomeThing();
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
long seconds = duration.getSeconds();//秒表示
long millis = duration.toMillis();//毫秒表示
boolean isAfter = end.isAfter(start);//时间点end是否在start之后
常用函数
-
now()
静态函数,获取当前时间戳 -
isAfter()/isBefore()
判断两个时间点的先后顺序 -
plusXXX()
在该时间点加上某段时间 -
minusXXX()
在该时间点上减去某段时间
Instant用在当你需要记录事件的发生时间,额如需要记录任何有关时区信息时。Instant只能包含秒数和毫秒数,例如如下代码就会抛出异常
instant.get(ChronoField.MONTH_OF_YEAR);
instant.plus(6, ChronoUnit.YEARS);
LocalDate
LocalDate
表示日期的不可变类型,不包含时间和时区。LocalDate和下面要讲的LocalTime都被设计成值类型的,这意味着我们不能用==
来判断两个LocalDate是不是相等而是应该通过equals()
。下面给出一个获取当前年月日的例子
LocalDate today = LocalDate.now();
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.printf(<span class="string">"Year : %d Month : %d day : %d \t %n", year, month, day);
常用函数
-
now()
根据当前时间戳创建LocalDate
-
of()
根据制定的年月日创建LocalDate
-
parse(charqueue, DateTimeFormatter)
根据传入的format将字符串转化为LocalDate对象 -
ofYearDay()
根据指定的年和一年中的第几天创建LocalDate
-
getXXX()
获取当前LocalDate
中关于日期的信息,年月日等等 -
plusXXX()
在当前的LocalDate
的基础上增加指定时间类型来创建一个新的LocalDate
-
minusXXX()
在当前的LocalDate
的基础上减去指定时间类型来创建一个新的LocalDate
-
withXXX()
在当前的LocalDate
的基础上指定某个时间类型的值来创建一个新的LocalDate
-
isXXX()
判断两个LocalDate
的大小关系,特别(isLeepYear()
判断是否为闰年) -
lengthOfXXX()
获取LocalDate代表的年或月的天数 -
with(TemporalAdjuster)
TemporalAdjusters提供了几个用来获取TemporalAdjuster
的方法,用来处理比较复杂的逻辑,比如获取当月的最后一天lastDayOfMonth()
-
atTime()
将LocalDate
转化为LocalDateTime
LocalTime
LocalTime
是值类型,且和日期,时区没有关联。当我们对时间进行加减操作时,以午夜为基准,24小时一个周期。因此,20:00加上6小时,结果是02:00。LocalTime用法和LocalDate类似
LocalTime time = LocalTime.of(20, 30);
int hour = date.getHour(); // 20
int minute = date.getMinute(); // 30
time = time.withSecond(6); // 20:30:06
time = time.plusMinutes(3); // 20:33:06
常用函数
- 和
LocalDate
基本类似,只是将对年月日的操作转换为时分秒 -
toSecondOfDay()
获取该时间点距离0:00的秒数
LocalDateTime
这个值类型只是LocalDate
和LocalTime
的简单组合。他表示一个和时区无关的日期和时间。LocalDateTime可以直接创建或者组合时间和日期
LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30);
LocalDateTime dt2 = LocalDateTime.of(date, time);
Month month = dt1.getMonth();
int minute = dt1.getMinute();
常用函数
- 将
LocalDate
和LocalTime
两个类的plusXXX()
,minusXXX()
,withXXX()
,getXXX()
简单相加 - 与
LocalDate
对象其他函数完全类似 -
isXXX()
与LocalDate完全一样 -
toLocalDate()/toLocalTime()
将LocalDateTime
转换为LocalTime
或者LocalDate
时间长度
Duration
表示以秒和纳秒位基准的时长;Period
表示以年,月,日衡量的时长。他们可以作为参数,传给主要的时间/日期类的增加或减少的方法,也可以计算两个时间点之间的间隔
Duration duration = Duration.ofDays(10);
LocalTime start = LocalTime.now();
doSoneThing();
LocalTime end = LocalTime.now();
Duration spend = Duration.between(start, end);
常用函数
-
ofXXX()
根据参数指定的大小计算以XXX
个单位的时间间隔 -
between(arg1, arg2)
计算两个参数时间点的时间间隔 -
plusXXX()/minuxXXX()
在当前时间间隔的基础上加上或减去指定个单位的时间 -
toXXX()
将时间间隔格式化位指定单位的时间,Duration一般使用该类型函数,Period一般使用getXXX()
-
abs()
求时间间隔的绝对值,保证时间间隔不为负数 -
isZero()/isNegative()
判断时间间隔是否为0或负 -
withXXX()
直接指定某个单位的值
格式化
java.time.format
包是专门用来格式化输出输入时间/日期的。这个包围绕DateTimeFormatter
类和它的辅助创建类DateTimeFormatterBuilder
展开。静态方法ofPattern(Charqueue)
和DateTimeFormatter
中的常量是最通用的创建格式化器的方式
- 常用ISO格式常量,如ISO_LOCAL_DATE
- 字母模式,如ofPattern(“dd/MM/uuuu”)
- 本地化样式,如ofLocalizedDate(FormatStyle.MEDIUM)
有了格式化器,我们就可以将该实例传递给parse()
或者format()
作为参数,用来将字符串格式化为对象或者将对象格式化位字符串
//按照内置的不同方式格式化
String format = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now());
String format2 = DateTimeFormatter.ISO_LOCAL_TIME.format(LocalTime.now());
String format3 = DateTimeFormatter.ISO_DATE.format(LocalDateTime.now());
String format4 = DateTimeFormatter.ISO_INSTANT.format(Instant.now());
System.out.println(format);
System.out.println(format2);
System.out.println(format3);
System.out.println(format4);
//按照标准格式格式化
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
String format5 = formatter.format(LocalDateTime.now());
System.out.println(format5);
//按照指定方式格式化
DateTimeFormatter pattern = DateTimeFormatter.ofPattern(<span class="string">"yyyy-MM-dd E HH:mm:ss");
String format6 = pattern.format(LocalDateTime.now());
System.out.println(format6);
其他
YearMonth
仅仅包含年和月字段,操作也LocalDate
类似
MonthDay
仅仅包含月和日字段,操作与LocalDate
类似