Bhavin Chauhan
Bhavin Chauhan

Reputation: 2010

Joda-Time Period issues in some cases

I have used Joda-Time joda-time-2.3.jar for day calcution with android app. My code is…

Period Nextperiod = new Period(ddate, nextdt,PeriodType.yearMonthDay());

In this ddate and nextdt are DateTime both dates are input type which is format with SimpleDateFormat , For day difference I have used Nextperiod.getDays() Now Test case are,

Case 1 Right
ddate=2014-06-01T00:00:00.000+05:30
nextdt =2015-04-11T00:00:00.000+05:30
Day: 10
Month: 10
year: 0

Case 2 Wrong ddate= 2014-05-28T00:00:00.000+05:30 nextdt=2015-03-12T00:00:00.000+05:30 Day: 12 Month: 9 year: 0

In case 2 it should be 14 and When I insert 29 may or 30 may the days are 12 same result. I don't know whats wrong with this date. I tested some more date and result are as per my expectation.Let me know my mistake.
Also tried,
Period Nextperiod = new Period(new LocalDate(Ddate), new LocalDate(Ddate),PeriodType.yearMonthDay());
Thanks In advance.

Upvotes: 3

Views: 586

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 340188

tl;dr

java.time.Period.between( startLocalDate , stopLocalDate )

java.time

The accepted Answer by Modus Tollens is correct.

FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. See Tutorial by Oracle.

Here is the modern version of your code.

Parsing your given strings as OffsetDateTime as they include an offset-from-UTC but not a full time zone.

OffsetDateTime start = OffsetDateTime.parse( "2014-05-28T00:00:00.000+05:30" ) ;

Better to use a time zone than an offset, if known.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime start = LocalDate.parse( "2014-05-28" ).atStartOfDay( z ) ;

If your really want to work with a date-only rather than a date-time moment, use the LocalDate class.

LocalDate start = LocalDate.parse( "2014-05-28" ) ;

You can extract a date-only LocalDate from either the OffsetDateTime or ZonedDateTime by calling toLocalDate.

Represent the span of time you want to jump, using the Period class.

Period p = Period.ofMonths( 9 ).plus( Period.ofDays( 12 ) ) ;

Verify that value by generating a string is standard ISO 8601 format.

String pOutput = p.toString() ;

P9M12D

Add the period to the starting date or date-time.

LocalDate later = start.plus( p ) ; // Add the `Period` span-of-time to our starting date.

To calculate elapsed time, use Period.between.

Period p = Period.between( startLocalDate , stopLocalDate ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

Upvotes: 1

Modus Tollens
Modus Tollens

Reputation: 5123

You can see why the Case 2 example is correct if you try to add 9 months and 12 days to your start date (ddate) step by step.

Adding 9 months to 2014-05-28 results in 2015-02-28. This is the last day of February 2015, so adding 12 days yields 2015-03-12.

This also applies to the test cases with a start date of May 29th or May 30th: the Period between these dates and the end date is 9 months and 12 days.

Upvotes: 2

Related Questions