Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joda Time and Java8 Time difference

I'm looking for a solution to calculate the months between two date. I think joda or java8 time can do it. But when I compare them I found something really weird.

import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.Date; import org.joda.time.Months;  public class DateMain {     public static void main(String[] args) throws ParseException {      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");     Date d1 = simpleDateFormat.parse("2017-01-28 00:00:00.000");     Date d2 = simpleDateFormat.parse("2017-02-28 00:00:00.000");      System.out.println("Test Cast 1");     System.out.println("joda time api result: " + monthsBetweenJoda(d1, d2) + " month");     System.out.println("java8 time api result: " + monthsBetweenJava8(d1, d2) + " month");      Date dd1 = simpleDateFormat.parse("2017-01-29 00:00:00.000");     Date dd2 = simpleDateFormat.parse("2017-02-28 00:00:00.000");      System.out.println("Test Cast 2");     System.out.println("joda time api result: " + monthsBetweenJoda(dd1, dd2) + " month");     System.out.println("java8 time api result: " + monthsBetweenJava8(dd1, dd2) + " month"); }  public static int monthsBetweenJoda(Date fromDate, Date toDate) {     if (fromDate == null || toDate == null) {         throw new IllegalArgumentException();     }     org.joda.time.LocalDateTime fromLocalDateTime = org.joda.time.LocalDateTime         .fromDateFields(fromDate);     org.joda.time.LocalDateTime toLocalDateTime = org.joda.time.LocalDateTime         .fromDateFields(toDate);     Months months = Months.monthsBetween(fromLocalDateTime, toLocalDateTime);     return months.getMonths(); }  public static long monthsBetweenJava8(Date fromDate, Date toDate) {     if (fromDate == null || toDate == null) {         throw new IllegalArgumentException();     }     LocalDateTime ldt1 = fromDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();     LocalDateTime ldt2 = toDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();     return ChronoUnit.MONTHS.between(ldt1, ldt2); }  } 

the output is below:

Test Cast 1 joda time api result: 1 month java8 time api result: 1 month Test Cast 2 joda time api result: 1 month java8 time api result: 0 month 

I feel very confused with the test case 2, and which one is reasonable?

Sorry, it's my first question here. Completed code attached.

like image 363
Jiaqi Avatar asked Sep 15 '17 05:09

Jiaqi


People also ask

Is Joda-time followed in Java 8?

Joda-Time is an API created by joda.org which offers better classes and having efficient methods to handle date and time than classes from java. util package like Calendar, Gregorian Calendar, Date, etc. This API is included in Java 8.0 with the java.

What is the replacement of Joda-time Library in Java 8?

By tackling this problem head-on, Joda-Time became the de facto standard date and time library for Java prior to Java SE 8. Note that from Java SE 8 onwards, users are asked to migrate to java. time (JSR-310) - a core part of the JDK which replaces this project.

What is the replacement of Joda-time?

Correct Option: D. In java 8,we are asked to migrate to java. time (JSR-310) which is a core part of the JDK which replaces joda library project.

What is Joda-time used for?

Joda-Time is the most widely used date and time processing library, before the release of Java 8. Its purpose was to offer an intuitive API for processing date and time and also address the design issues that existed in the Java Date/Time API.


1 Answers

Joda-Time and Java 8 java.time.* have different algorithms for determining the number of months between.

java.time.* only declares a month has passed once the day-of-month is greater (or in the next month). From 2017-01-29 to 2017-02-28 it is clear that the second day-of-month (28) is less than the first (29) so a month has not yet been completed.

Joda-Time declares a month has passed because adding 1 month to 2017-01-29 will yield 2017-02-28.

Both are plausible algorithms, but I believe the java.time.* algorithm to be more in tune with what people expect (which is why I chose a different algorithm when writing java.time.*).

like image 108
JodaStephen Avatar answered Sep 23 '22 00:09

JodaStephen