Java8 中 joda-time 时间操作工具常用常用 API

Java8 中 joda-time 时间操作工具常用常用 API

薛定谔的汪

前言

最近公司要对一个老系统进行重构、服务拆分,老系统毕竟是几年前的项目了,在重构的过程中发现代码里对日期的操作还是用的Date、Calendar、SimpleDateFormatter 等API,甚至某些地方还存在线程安全问题。

重构项目采用的是 Java8 的最新版本,所以可以使用其新特性 joda-time 来操作日期,使代码更简洁、优雅、安全。

Joda-Time

在 Java8 之前,日期处理是比较繁琐,令人头疼的部分,不仅是复杂的 API 操作,甚至还有线程安全问题。因此,产生了强大的 Joda-Time,可以替换 Java 日期操作的 API,Java8 吸收了Joda-Time 的精华,包含了所有关于日期、时间、日期时间、时区、Instant(跟 Date 类似但精确到纳秒)、duration(持续时间精确到秒)、Period(持续时间精确到天)和时钟操作的类,而且 Joda-Time 这些类都具有可变性,当我们修改一个时间的时候,会返回一个新的对象,这样也解决了线程安全问题。

Clock

CLock 可以用来获取当前的 Instant 、毫秒数等:

1
2
3
4
5
6
final Clock clock = Clock.systemUTC();
System.out.println(clock.millis());
System.out.println(clock.instant());
//上海时钟
final Clock shanghaiClk = Clock.system(ZoneId.of("Asia/Shanghai"));

查看`Clock.systemUTC();注释可以得知,这个可以用来替代System.currentTimeMillis()``来获取当前时间的毫秒数

Instant

1
2
3
4
5
6
7
8
9
Instant instant = Instant.now();
//精确到秒 得到相对于1970-01-01 00:00:00 UTC的一个时间
System.out.println(instant.getEpochSecond());
//精确到毫秒
System.out.println(instant.toEpochMilli());
// Instant 转 Date
Date date=Date.from(instant);
// Date 转 Instant
Instant instant2 = new Date().toInstant();

和 Date 类似,但是可以精确到纳秒。

LocalDate、LocalTime、LocalDateTime

获取当地的日期和时间:

1
2
3
4
5
6
7
8
9
10
11
12
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
// 判断今年是否是闰年
System.out.println(localDate.isLeapYear());
// 获得本月天数
System.out.println(localDate.lengthOfMonth());

LocalTime localTime = LocalTime.now();
System.out.println(localTime);

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);

LocalDate 只保留本地当前时间的年月日部分,LocalTIme 保存本地当前时间的后半段部分,而 LocalDateTime 则是完整的当前时间。

这三个类也可以用 of方法来构造:

1
2
LocalDateTime of = LocalDateTime.of(2019, 3, 16, 11, 10, 10);
System.out.println(of);

如果需要获得带时区的时间,可以使用 ZonedDateTime(我平时开发基本用不到)。

Duration

用于计算日期的间隔:

1
2
3
4
5
LocalDateTime from = LocalDateTime.of( 2019, Month.JANUARY, 1, 0, 0, 0 );
LocalDateTime to = LocalDateTime.of( 2019, Month.JANUARY, 1, 0, 0, 0 );
Duration duration = Duration.between(from, to);
System.out.println(duration.toDays());
System.out.println(duration.toHours());

Duration 也可以使用of来构造。

日期加减等操作

Joda-Time 把日期的加减操作也变得非常简单、易读:

1
2
3
4
5
6
7
8
9
10
11
12
LocalDateTime localDateTime =LocalDateTime.now();
// 加一天
LocalDateTime plusDays = localDateTime.plusDays(1);
// 减一年
LocalDateTime minusYears = localDateTime.minusYears(1);
// 设置年
LocalDateTime withYear = localDateTime.withYear(2020);

// 判断日期是否是同一天,判断日期先后
boolean equal = localDateTime.isEqual(withYear);
boolean after = localDateTime.isAfter(withYear);
boolean before = localDateTime.isBefore(withYear);

LocalDateTime 和 String 互转

1
2
3
4
5
6
LocalDateTime localDateTime =LocalDateTime.now();
String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(format);

String dateStr = "2019-03-16";
LocalDateTime parse = LocalDateTime.parse(dateStr);

获取年、月、日、时、分、秒

1
2
3
4
5
6
7
8
9
10
LocalDateTime localDateTime =LocalDateTime.now();
// 年
int year = localDateTime.getYear();
// 月
Month month = localDateTime.getMonth();
int monthValue = month.getValue();
// 日
int dayOfMonth = localDateTime.getDayOfMonth();
......

获得本月的第一天和最后一天

1
2
3
4
5
LocalDate today = LocalDate.now();
//本月的第一天
LocalDate firstday = LocalDate.of(today.getYear(),today.getMonth(),1);
//本月的最后一天
LocalDate lastDay =today.with(TemporalAdjusters.lastDayOfMonth());

判断今天是否是生日

做过电商项目的话,这个需求一定很熟悉:用户生日的当天给用户发贺卡,短信生日祝福、生日促销券等,如何判断今天是不是用户的生日呢?可以使用 MonthDay的 API,非常简单地完成判断:

1
2
3
4
5
6
7
8
9
10
11
12
// 今天
LocalDate today = LocalDate.now();
// 生日
LocalDate birthDay = LocalDate.of(1991, 9, 28);
// 使用 MonthDay 只存月、日
MonthDay birthMonthday = MonthDay.from(birthDay);
MonthDay currentMonthDay = MonthDay.from(today);
if(currentMonthDay.equals(birthMonthday)){
System.out.println("祝你生日快乐!!");
}else{
System.out.println("今年不是你的生日");
}

更多丰富的 API 操作,等后面遇到了会继续补充,未完待续……

  • Title: Java8 中 joda-time 时间操作工具常用常用 API
  • Author: 薛定谔的汪
  • Created at : 2019-01-16 18:01:54
  • Updated at : 2023-11-17 19:37:37
  • Link: https://www.zhengyk.cn/2019/01/16/java/joda-time-common-use/
  • License: This work is licensed under CC BY-NC-SA 4.0.