java8日期时间API讲解

java日期时间API总结

Date

java中常见的表示时间的类。内部使用long类型的值表示自1970-01-01起的毫秒数。本质上是一个表示瞬时时间的类,表示级别为毫秒。且其为可变对象,即线程不安全的。目前大多数方法已废弃。可用且常见的方法如下:

方法 含义
new Date() 创建一个表示当前时间的对象
new Date(long time) 传入一个表示自1970年1月1日起的毫秒数,基于此时间创建对象
from(Instant instant) 以Instant类的对象构建对象,java8新增
toInstant() 将Date对象转为Instant对象,java8新增

Instant

java8新增类,专门用于表示时间戳。想获取当前时间的时间戳可用Instant.now()获取。

关于Instant比较常用的是与Date的相互转化及比较两时间戳的差值。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//获取当前时间戳
Instant now = Instant.now();
System.out.println(now);

Thread.sleep(1000);

// Date转Instant
Date today = new Date();
Instant cur = today.toInstant();

// 计算两Instant示例差值
long diff = Duration.between(now, cur).toMillis();
System.out.println(diff);

// Instant 转Date
Date date = Date.from(now);
System.out.println(date);

LocalDate

java8新增的表示日期的类。默认格式为yyyy-MM-dd,表示具体某一天。可由now()获取当前日期,也可传入年月日构造。类中有格式化方法。

常用方法如下:

方法 静态方法 含义
now() 获取当天日期
of(year,month,days) 根据传入的值构造日期
parse(dateStr) 解析日期字符串(需为yyyy-MM-dd格式)为日期格式
format 格式化日期为字符串
isLeapYear() 是否为闰年
lengthOfMonth() 该月长度
getDayOfWeek() 表示是周几,返回枚举类
plusXXX XXX可为年、月或日,表示添加一段时间,返回新日期
minusXXX 同plusXXX类似,在实例基础上减去某个值,返回新日期
equal() 比较两日期是否相等

总的来说,LocalDate表示代表本地时间的日期,API为我们提供了构造、解析、格式化及计算等方法,使得日期表示更简便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

LocalDate now = LocalDate.now();
//输出:2018-04-22 ,表示其默认格式为yyyy-MM-dd
System.out.println(now);

LocalDate lastDay = LocalDate.of(2018, 4, 21);
//输出:2018-04-21
System.out.println(lastDay);

// 输出:false,不是闰年
System.out.println(now.isLeapYear());

// 输出 2018-04-21,格式化字符串
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE));

// 注意,会报错,LocalDate类只有日期没有时间信息,不能格式化
// System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

// 获取某天的年月日信息
System.out.println(now.getYear());
System.out.println(now.getMonthValue());
System.out.println(now.getDayOfMonth());

// 比较两日期是否相等
System.out.println(now.equals(lastDay));

// 日期加减
// 明天
LocalDate tomorrow = now.plusDays(1);
System.out.println(tomorrow);
// 一周前
LocalDate monthDay = now.minusWeeks(1);
System.out.println(monthDay);
// 一年后
LocalDate afterDay = now.plus(1, ChronoUnit.YEARS);
System.out.println(afterDay);

LocalTime与LocalDateTime

LocalTime、LocalDateTime与LocalDate类似,LocalTime表示本地时间,LocalDateTime表示本地日期时间。用法也与LocalDate类似。下面简单介绍下。

LocalTime

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//获取当前时间
LocalTime curTime = LocalTime.now();
// 输出:10:52:12.108
System.out.println(curTime);

// 构造时间
LocalTime localTime = LocalTime.of(14, 34, 12);
// 输出:14:34:12
System.out.println(localTime);

// 时间加减,1小时后
LocalTime nextHour = curTime.plus(1, ChronoUnit.HOURS);
// 11:52:12.108
System.out.println(nextHour);

// 两时间差值
long minuteDiff = Duration.between(curTime, localTime).toMinutes();
// 输出:221
System.out.println(minuteDiff);

LocalDateTime

用来表示日期及时间,包含LocalDate与LocalTime的信息,比较常用。方法与前两者类似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取当前日期时间
LocalDateTime now = LocalDateTime.now();
// 输出:2018-05-05T10:58:17.119
System.out.println(now);
// 2018
System.out.println(now.getYear());
//5
System.out.println(now.getMonthValue());
//5
System.out.println(now.getDayOfMonth());
// 10
System.out.println(now.getHour());
//58
System.out.println(now.getMinute());

日期格式化

java8的日期格式化再也不用SimpleDateFormat类做复杂的日期转化了,格式化的函数都包含在各自的日期时间类中。以LocalDateTime为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@Test
public void formatDate() {
LocalDateTime now = LocalDateTime.now();

// 默认输出:2018-05-05T11:11:59.221
System.out.println(now);
// iso日期时间格式,输出:2018-05-05T11:11:59.221
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// iso 日期格式,输出:2018-05-05
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE));
// 自定义格式:2018/05/05 11:11:59
System.out.println(now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")));

// 字符串转日期,默认字符串格式需为ISO_LOCAL_DATE_TIME风格
LocalDateTime localDateTime = LocalDateTime.parse("2018-05-01T11:00:00");
System.out.println(localDateTime);

// 字符串转日期,字符串格式需与模式相匹配
LocalDateTime localDateTime1 = LocalDateTime.parse("2018/05/05 12:00", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));
System.out.println(localDateTime1);

}

时间差值

java8可以计算时间差值的类有:PeriodDuration以及ChronoUnit。其中ChronoUnit计算时间差值主要也是用到了Duration。而Period主要是针对日期的间隔计算,而Duration主要是针对时间的。看一下示例:

Period

Period表示以日期为单位的时间段,即其最小单位也要是day。常用于计算两LocalDate之间的差值

1
2
3
4
5
6
7
8
9

// 计算距22年冬奥会还有多久
LocalDate now = LocalDate.now();
// 输出:当前日期:2018年05月06日
System.out.println("当前日期:" + now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
LocalDate olympicDay = LocalDate.of(2022, 2, 4);
Period period = Period.between(now, olympicDay);
// 输出:距冬奥会还有:3年8月29天
System.out.println("距冬奥会还有:" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天");

Duration

相比Period,Duration用于表示两个时间的时间差值,而不仅仅是日期。如可以表示两时间点差值,日期差值。

需注意的是,Duration内部表示时间差是用两个long类型的值:秒(second)及纳秒(nanos)表示的,若用于计算两日期相差天数等问题,通常是将秒换算成天得到的。这样也表明,两时间值至少需要精确到秒,否则不能完成转化,即LocalDate是不能用Duration

1
2
3
4
5
6
7
8
9
10
11
12
13

// 计算两个LocalTime相差的毫秒数
LocalTime start = LocalTime.now();
TimeUnit.SECONDS.sleep(1);
Duration duration = Duration.between(start, LocalTime.now());
// 输出:1004
System.out.println("1秒后相差毫秒数:" + duration.toMillis());


// 距冬奥会天数,不能使用LocalDate,因其没有时分秒等单位
LocalDateTime curTime = LocalDateTime.now();
LocalDateTime nextTime = LocalDateTime.of(2022, 2, 4, 0, 0);
System.out.println("距冬奥会相差:" + Duration.between(curTime, nextTime).toDays() + "天");

ChronoUnit

上面说Duration不能用在LocalDate上,而我需要计算两日期相差天数,就不能直接计算得到吗。事实上当然可以了,可以使用ChronoUnit

1
2
3

//输出: 距冬奥会相差:1370天
System.out.println("距冬奥会相差:" + Duration.between(curTime, nextTime).toDays() + "天");

不仅如此,ChronoUnit类可用于计算上述所提到的各种时间差。计算模式也很固定

ChronoUnit.计量单位.between(start,end)

1
2
3
4
5


// 1秒钟后
long diffOneMinute = ChronoUnit.MILLIS.between(start, LocalTime.now());
System.out.println("1秒钟后" + diffOneMinute);

新旧时间转化

Date与Instant

Date与Instant都可表示瞬时时间,转化方式上面也有所提及,即:

1
2
3
4
5
6
7

// Date转Instant
Date today = new Date();
Instant cur = today.toInstant();

// Instant 转Date
Date date = Date.from(now);

Data与LocalDate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


// Date转LocalDateTime、LocalDate
LocalDateTime now = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
// 输出:2018-05-06T18:29:52.184
System.out.println(now);
LocalDate today = now.toLocalDate();
//输出:2018-05-06
System.out.println(today);

// LocalDateTime 转Date
Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());

// LocalDate 转Date
Date date1 = Date.from(today.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
分享到:
0%