java8 joda_Java 基础之如何取舍 Joda 与 Java8 日期库

在 Java8 以前,时间和日期的类库很难用,而且有线程安全等诸多问题。

Joda time 弥补了 Java 在这方面的不足,但是在 Java8 时,增加了 java.time 包,对 Java 在日期 API 方面的进行了增强,这些代码实现了 JSR-310 的标准。Joda 的官方推荐迁移到 Java8 的时间类库上来。

下面来详细对比对比一下两个类库,看看 Java8 的日期 API 是否能真正替代 Joda time。

基础概念对比

Joda Date 的核心概念,这些概念在 java time 中基本也能找到对应:

instant

表示一个时刻,使用从 1970-01-01 00:00:00 至今的毫秒数表示

Joda time:

DateTime dt = new DateTime();

Instant instant = dt.toInstant();

Java time:

Clock clock = Clock.systemDefaultZone();

Instant instant = clock.instant();

interval

表示两个 instant 之间的间隔,左闭右开。

Joda time:

DateTime dt = new DateTime();

DateTime dt1 = new DateTime();

Interval interval = new Interval(dt.toInstant(), dt1.toInstant());

java time 中没有提供类似的 API,因为 JSR-310 标准中没有这个概念。

duration

用毫秒表示的时间段,通常从 interval 获得 Joda time:

Java time:

LocalDateTime l1 = LocalDateTime.now();

LocalDateTime l2 = LocalDateTime.now();

Period period = Period.between(l1.toLocalDate(), l2.toLocalDate());

period

同样表示时间段,比如 3 年,5 个月,而 duration 使用毫秒表示

Joda time:

DateTime dt1 = new DateTime();

DateTime dt2 = new DateTime();

Period period = Period.fieldDifference(dt1.toLocalDateTime(), dt2.toLocalDateTime());

Java time:

LocalDateTime l1 = LocalDateTime.now();

LocalDateTime l2 = LocalDateTime.now();

Period period = Period.between(l1.toLocalDate(), l2.toLocalDate());

chronology

年表,这是 joda-time 设计的基础

Joda time:

DateTime dt = new DateTime();

Chronology chronology = dt.getChronology();

Java time:

LocalDateTime localDateTime = LocalDateTime.now();

Chronology ch = localDateTime.getChronology();

timezones

表示时区。

Joda time:

DateTime dt = new DateTime();

DateTimeZone dateTimeZone = dt.getZone();

Set zones = DateTimeZone.getAvailableIDs();

Java time:

Clock clock = Clock.systemDefaultZone();

ZoneId zoneId = clock.getZone();

Set zones = ZoneId.getAvailableZoneIds();

从上面可以看到,除了 JSR-310 中没有的 Interval 的定义之外,这两个库在基础概念方面的实现相差不大。

因为 Unix 系统从 1970-01-01 00:00:00 开始计时,这个时间也称之为 Epoch Time,后续使用 Unix 的这种计时方式。

具体使用

Joda time 依赖 JDK5 及后续版本,没有额外的依赖。

为了起到对比的效果,挑几个比较常用的场景进行对比:

获取 1970 至今的毫秒数

获取当前时间

获取年、月、日、星期几

日期的增减

日期的格式化

获取时间戳

在代码中,经常会使用这个功能来表示唯一性:

Joda time:

DateTime dt = new DateTime();

long mills = dt.getMillis();

Java time:

Clock clock = Clock.systemDefaultZone();

long mills = clock.millis();

获取当前时间

这块两个库没有太大的差异:

Joda time:

DateTime dt = new DateTime();

LocalDateTime localDateTime = dt.toLocalDateTime();

Java time:

LocalDateTime localDateTime = LocalDateTime.now();

获取年、月、日、星期几

Joda time:

DateTime dt = new DateTime();

int dayOfYear = dt.getDayOfYear();

int dayOfMonth = dt.getDayOfMonth();

int dayOfWeek = dt.getDayOfWeek();

int hourOfDay = dt.getHourOfDay();

Java time:

Clock clock = Clock.systemDefaultZone();

LocalDateTime localDateTime = LocalDateTime.now(clock);

int dayOfYear = localDateTime.getDayOfYear();

int dayOfMonth = localDateTime.getDayOfMonth();

int dayOfWeek = localDateTime.getDayOfWeek().getValue();

int hourOfDay = localDateTime.getHour();

获取这些值两个库也没有太大的差异,但是对于一些场景,比如我想获得 "星期四" 这个字符串。 在 Joda 库中,可以 dt.dayOfWeek().getAsShortText(); // 星期四 这样获得。在 Java 中,localDateTime.getDayOfWeek().name(); //THURSDAY 只能获取到英文。

Joda time 在本地化方面比 Java time 做的更好。

日期增减

Joda time:

DateTime dt = new DateTime();

dt = dt.plusDays(2); //当前日期添加两天

dt = dt.plusHours(5); // 当前时间加上两个小时

dt = dt.minusDays(1); // 当前日期减一天

dt = dt.minusHours(2); // 当前日期减两个小时

Java time:

LocalDateTime localDateTime = LocalDateTime.now();

localDateTime = localDateTime.plusDays(2); // 增加两天

localDateTime = localDateTime.plusHours(2); // 增加两个小时

localDateTime = localDateTime.minusDays(1); //减少一天

localDateTime = localDateTime.minusHours(1); // 减少一个小时

日期的格式化

日期格式化是日常使用最频繁的功能,下面来对比一下这两者的区别。

Joda time:

// 方式一

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

DateTime dt = new DateTime();

System.out.println(dt.toString(formatter)); // 方式二

String dateFormat = "yyyy-MM-dd HH:mm:ss";

System.out.println(dt.toString(dateFormat));

Java time:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

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

通过上面的对比,可以发现这两个类库都可以完成相同的功能。虽然在细节上是有一些细微的差别。

java.util.Date 是 Java 中最早的日期类,后来就不推荐使用这个类了,java.util.Calendar 用来替代 Date。Calendar 有 Date 的所有功能,并且提供了更加丰富的获取年月日的 API。

Calendar 是一个虚拟类,GregorianCalendar 则是 Calendar 的实现类。

Java time 与 java.util 下的时间类相互转化,可以将 Date 或者 Calendar 转化成 Java time 中的 LocalDateTime.

java.util.Date 转 java.time.LocalDateTime:

Date date = new Date();

LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());

java.util.Carlendar 转 java.time.LocalDateTime:

Calendar calendar = Calendar.getInstance();

LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault());

Joda time 也可以与 java.util.Date 可以进行相互的转化:

// from Joda to JDK

DateTime dt = new DateTime();

Date jdkDate = dt.toDate();

// from JDK to Joda

dt = new DateTime(jdkDate);

// from Joda to JDK

DateTime dt = new DateTime();

Calendar jdkCal = dt.toCalendar(Locale.CHINESE);

// from JDK to Joda

dt = new DateTime(jdkCal);

// from Joda to JDK

DateTime dt = new DateTime();

GregorianCalendar jdkGCal = dt.toGregorianCalendar();

// from JDK to Joda

dt = new DateTime(jdkGCal);

设计思想

Joda time 与 Java time 在功能上已经相差不大,常用的功能这两个类库都可以完成,而且两个库都是线程安全的。

但我认为 Joda time 的 API 更加简洁一些,Joda time 的使用可以直接从 DateTime 这个类开始。而 Java time 的使用则更加繁琐。

从设计上来说 Java time 都不再使用 new 来创建实例,而是使用工厂方法来创建实例。这点上比 Joda time 的设计要更好,而且更加安全。

既然 Joda time 都推荐迁移回 Java time 了,那么最终肯定是要迁移的。但是目前来说,我觉得 Joda time 用起来更加顺手一些,暂时还会继续使用这个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值