题记
在项目当中我们经常会遇到一些处理时间的场景,譬如要取一个指定的时间、某个时间加上指定的天数、获取某个月份的星期几、某一年的某一个月的最后一天等等。这些场景在JDK1.8之前想想这些需求都是需要自己取封装的,如果你没有用过Joda的情况下。现在我们就来比较一下这两个还有jdk1.8之前要实现这些功能的代码对比。
方案
joda 官网:http://www.joda.org/joda-time/
本方案测试的环境如下:
1. maven、jdk1.8
2. maven 需要添加joda的jar包,本实验使用的是2.9.4版本
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.4</version>
</dependency>
下面我们就来看看有了joda和jdk1.8环境之后,我们处理题记中的问题会有多么的方便,代码也会变得非常的简洁。
向某一个瞬间加上 90 天
System.out.println("================================以 JDK<1.8 的方式向某一个瞬间加上 90 天并输出结果====================================");
Calendar calendar = Calendar.getInstance();
calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
SimpleDateFormat sdf = new SimpleDateFormat("E MM/dd/yyyy HH:mm:ss.SSS");
calendar.add(Calendar.DAY_OF_MONTH, 90);
System.out.println(sdf.format(calendar.getTime()));
System.out.println("================================以 JDK1.8 的方式向某一个瞬间加上 90 天并输出结果====================================");
LocalDateTime currentTime = LocalDateTime.of(2000, 1, 1, 0, 0, 0, 0);
System.out.println(currentTime.plusDays(90).format(DateTimeFormatter.ofPattern("E MM/dd/yyyy HH:mm:ss.SSS")));
System.out.println("================================以 Joda 的方式向某一个瞬间加上 90 天并输出结果====================================");
DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
System.out.println(dateTime.plusDays(90).toString("E MM/dd/yyyy HH:mm:ss.SSS"));
计算 11 月中第一个星期二
System.out.println("================================以 JDK<1.8 的方式计算 11 月中第一个星期二并输出结果====================================");
System.out.println("jdk1.8之前是现实这个逻辑是非常复杂的,要自己实现逻辑");
System.out.println("================================以 JDK1.8 的方式计算 11 月中第一个星期二并输出结果====================================");
LocalDate testDateNow = LocalDate.now();
testDateNow = testDateNow.withMonth(11).with(TemporalAdjusters.firstInMonth(DayOfWeek.TUESDAY));
System.out.println("JDK1.8 的方式计算 11 月中第一个星期二:"+testDateNow);
System.out.println("================================以 Joda 的方式计算 11 月中第一个星期二并输出结果====================================");
/**
* .setCopy("Monday") 是整个计算的关键。不管中间 LocalDate 值是多少,将其 dayOfWeek 属性设置为 Monday 总是能够四舍五入,
* 这样的话,在每月的开始再加上 6 天就能够让您得到第一个星期一。再加上一天就得到第一个星期二。Joda 使得执行此类计算变得非常容易。
*/
org.joda.time.LocalDate cur = new org.joda.time.LocalDate();
org.joda.time.LocalDate electionDate = cur.monthOfYear().setCopy(11).dayOfMonth().withMinimumValue().plusDays(6).dayOfWeek().setCopy(DateTimeConstants.MONDAY).plusDays(1);
System.out.println("Joda 的方式计算 11 月中第一个星期二:"+electionDate);
计算五年后的第二个月的最后一天
System.out.println("================================以 JDK<1.8 的方式计算五年后的第二个月的最后一天并输出结果====================================");
System.out.println("jdk1.8之前是现实这个逻辑是非常复杂的,要自己实现逻辑");
System.out.println("================================以 JDK1.8 的方式计算五年后的第二个月的最后一天并输出结果====================================");
LocalDate testDateNowLast = LocalDate.now();
testDateNowLast = testDateNowLast.plusYears(5).withMonth(2).with(TemporalAdjusters.lastDayOfMonth());
System.out.println("JDK1.8 的方式计算五年后的第二个月的最后一天:"+testDateNowLast);
System.out.println("================================以 Joda 的方式计算五年后的第二个月的最后一天并输出结果====================================");
org.joda.time.LocalDate curr = new org.joda.time.LocalDate();
org.joda.time.LocalDate lastDayDate = curr.plusYears(5).monthOfYear().setCopy(2).dayOfMonth().withMaximumValue();
System.out.println("Joda 的方式计算五年后的第二个月的最后一天:"+lastDayDate);
计算两个日期相差多少年、月、周、天
System.out.println(
"================================以 JDK<1.8 的方式计算两个日期相差多少年、月、周、天并输出结果====================================");
System.out.println("jdk1.8之前是现实这个逻辑是非常复杂的,要自己实现逻辑");
System.out.println(
"================================以 JDK1.8 的方式计算计算两个日期相差多少年、月、周、天并输出结果====================================");
LocalDate period1 = LocalDate.now();
LocalDate period2 = LocalDate.of(2014, 1, 1);
Period periodFull = Period.between(period1, period2);
System.out.println("JDK1.8 的方式计算计算两个日期相差多少年零多少个月零多少天:" + Math.abs(periodFull.getYears()) + "年零" + Math
.abs(periodFull.getMonths()) + "个月零" + Math.abs(periodFull.getDays()) + "天");
System.out.println("JDK1.8 的方式计算计算两个日期相差多少年:" + Math.abs(period1.until(period2, ChronoUnit.YEARS)));
System.out.println("JDK1.8 的方式计算计算两个日期相差多少个月:" + Math.abs(period1.until(period2, ChronoUnit.MONTHS)));
System.out.println("JDK1.8 的方式计算计算两个日期相差多少周:" + Math.abs(period1.until(period2, ChronoUnit.WEEKS)));
System.out.println("JDK1.8 的方式计算计算两个日期相差多少天:" + Math.abs(period1.until(period2, ChronoUnit.DAYS)));
System.out.println(
"================================以 Joda 的方式计算计算两个日期相差多少年、月、周、天并输出结果====================================");
org.joda.time.LocalDate currPeriod1 = new org.joda.time.LocalDate();
org.joda.time.LocalDate currPeriod2 = new org.joda.time.LocalDate(2014, 1, 1);
org.joda.time.Period periodJoda = org.joda.time.Period.fieldDifference(currPeriod1, currPeriod2);
System.out.println("Joda 的方式计算计算两个日期相差多少年零多少个月零多少天:" + Math.abs(periodJoda.getYears()) + "年零" + Math
.abs(periodJoda.getMonths()) + "个月零" + Math.abs(periodJoda.getDays()) + "天");
System.out
.println("Joda 的方式计算计算两个日期相差多少年:" + Math.abs(Years.yearsBetween(currPeriod1, currPeriod2).getYears()));
System.out.println(
"Joda 的方式计算计算两个日期相差多少个月:" + Math.abs(Months.monthsBetween(currPeriod1, currPeriod2).getMonths()));
System.out
.println("Joda 的方式计算计算两个日期相差多少周:" + Math.abs(Weeks.weeksBetween(currPeriod1, currPeriod2).getWeeks()));
System.out.println("Joda 的方式计算计算两个日期相差多少天:" + Math.abs(Days.daysBetween(currPeriod1, currPeriod2).getDays()));
获取毫秒数、判断是不是闰年
Instant instant = Instant.now();
LocalDateTime localDateTime1 = LocalDateTime.now();
System.out.println(instant);
System.out.println(instant.toEpochMilli());
localDateTime1.toLocalDate().isLeapYear();//判断闰年
System.out.println(currPeriod2.monthOfYear().setCopy(2).monthOfYear().isLeap());//根据月份来判断闰年
以上便是joda和jdk1.8以及1.8之前处理对应场景的代码对比,对于joda真的是相见恨晚啊。这个项目貌似从2004年发布的第一个版本,算是一个专业的处理时间的第三方工具类。但是jdk1.8出了之后感觉也是很方便的,基本和joda代码简洁度一样,处理的场景都是比较全面的。看看类名两个都有挺多一样的,不管怎么样有了这样的工具类。对于我们写代码来说是更加方便快捷了,不至于像之前那样处理上述场景想想都头大。发上文以共勉~
参考: