-
取两个时间之间的差值
LocalTime time1 = LocalTime.of(8,00);
LocalTime time2 = LocalTime.of(9,00);
Duration between = Duration.between(time1, time2); //PT1H
-
LocalTime,LocalDateTime,Instant可以用于Duration,Duration适用于以秒和纳秒,所以就不能向其传入LocalDate
LocalDate date1 = LocalDate.of(2018,7,7);
LocalDate date2 = LocalDate.of(2018,8,10);
Period between = Period.between(date1, date2); //P1M3D
-
当然他们不仅限于计算差值,还可以创建对象以代表具体的时间值
Duration duration = Duration.ofMillis(3);
System.out.println("duration = " + duration);//duration = PT0.003S
Period period = Period.ofDays(10);
System.out.println("period = " + period);//period = P10D
- 对于其他的方法,大家可以查询文档即可:java8 api文档
- 对于以上的介绍目前为止日期对象都是不可变的,这是考虑函数式编程以及线程安全而做的决定
-
创建类实现TemporalAdjuster接口
/**
* 需求:返回下一个工作日,如果日期在周一到周五之间,就返回下一天就好,如果是周五六日就需要返回下周一的日期
*/
public class NextWorkingDay implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
//得到参数中是这周的第几天
int day = temporal.get(ChronoField.DAY_OF_WEEK);
//根据第几天构造出DayOfWeek枚举类,容易观察,当然也可以不用构造
//如果不够再下面的判断相等直接改成上面的day就行了
DayOfWeek dayOfWeek = DayOfWeek.of(day);
//需要在参数的基础上增加几天
int dayNeedAdd = 1;
//如果是周五,就需要推后三天才是周一
if (dayOfWeek == DayOfWeek.FRIDAY){
dayNeedAdd = 3;
}
//如果是周六,就需要推后两天才是周一
if (dayOfWeek == DayOfWeek.SATURDAY){
dayNeedAdd = 2;
}
//如果是周日或者当天就是在周一到周五之间的,直接加一就可以,即返回下一天
return temporal.plus(dayNeedAdd, ChronoUnit.DAYS);
}
}
-
上面说此接口是函数式接口,当然就可以使用Lmabda传入了,使用如下
LocalDate date = LocalDate.of(2018, 11, 25);//周日
LocalDate nextWorkDay = date.with(new NextWorkingDay()); //2018-11-26
-
使用lambda
LocalDate date = LocalDate.of(2018, 11, 25);//周日
LocalDate nextWorkDay = date.with(temporal -> {
//具体实现是把上面的实现类NextWorkingDay内实现的方法体贴进来就行了
});
-
也可以这样
LocalDate date = LocalDate.of(2018, 11, 25);//周日
TemporalAdjuster nextWorkDay = TemporalAdjusters.ofDateAdjuster(temporal -> {
//具体实现是把上面的实现类NextWorkingDay内实现的方法体贴进来就行了
});
LocalDate date1 = date.with(nextWorkDay);
- 如上是一个静态方法,传入一个UnaryOperator函数式接口的实现即可,就能够返回一个TemporalAdjuster对象,然后传入with方法即可
-
java.time.format包就是解析日期格式化日期的,最重要的是DateTimeFormatter类,他有一些预定义常量
LocalDate date = LocalDate.of(2018, 8, 8);
String format = date.format(DateTimeFormatter.BASIC_ISO_DATE);//20180808
String format1 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);//2018-08-08
-
也可以通过指定解析模式来解析Sring时间字符串
LocalDate parse = LocalDate.parse("20180808", DateTimeFormatter.BASIC_ISO_DATE); //2018-08-08
LocalDate parse1 = LocalDate.parse("2018-08-08", DateTimeFormatter.ISO_LOCAL_DATE); //2018-08-08
- 与之前的DateFormat相比,DateTimeFormatter是线程安全的
-
按照指定格式创建解析器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM-dd");
LocalDate date = LocalDate.of(2018, 12, 6);
//按照指定格式返回时间字符串
String format = date.format(formatter);
System.out.println("format = " + format); //2018/12-06
//根据指定的解析格式解析指定时间字符串
LocalDate parse = LocalDate.parse(format, formatter);
System.out.println("parse = " + parse); //2018-12-06
-
创建一个更加复杂的解析器
DateTimeFormatter builder = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH) //首先解析的是一个月的第几天
.appendLiteral("(") //分隔符
.appendText(ChronoField.MONTH_OF_YEAR) //一年的第几个月
.appendLiteral("+") //分隔符
.appendText(ChronoField.YEAR) //年份
.parseCaseInsensitive() //开始解析,不区分大小写
.toFormatter(Locale.CHINA); //按照哪个国家的方言开始解析
LocalDate date = LocalDate.of(2018, 2, 25);
String format = date.format(builder);
System.out.println("format = " + format); //25(二月+2018
- 到这里,我们介绍了时间类的使用和解析,以及自定义如何实现自己的日期转换逻辑,至于本书剩下的时区和计算时区的偏差,本文不再记录