Joda Time - difference in months between two dates [duplicate] - java

This question already has answers here:
Number of days between two dates in Joda-Time
(9 answers)
Closed 7 years ago.
I need to get the difference in months between two dates, I'm using Joda Time, the problem is this:
DateTime date1 = new DateTime().withDate(2015, 2, 1);
DateTime date2 = new DateTime().withDate(2015, 1, 1);
Months m = Months.monthsBetween(date1, date2);
int monthDif = m.getMonths();//this return 0
it returns 0 because there is no month in the middle of the two dates, I need to return the difference in months not a few months in between, and add 1 would be problematic when the dates are the same.

Changing the first date to 2015-02-02, Joda correctly returns 1 month:
DateTime date1 = new DateTime().withDate(2015, 2, 2);
DateTime date2 = new DateTime().withDate(2015, 1, 1);
System.out.println(Months.monthsBetween(date2, date1).getMonths());
// Returns 1.
So my guess is that because you didn't provide a time portion, Joda cannot be precise about exactly which point in time of 2015-01-01 date2 refers to. You might have as well referred to 23:59:59, in which case a full month wouldn't have elapsed yet, technically.
If you provide a zero time portion explicitly, it works as you initially expected:
DateTime date1 = new DateTime().withDate(2015, 2, 1).withTime(0, 0, 0, 0);
DateTime date2 = new DateTime().withDate(2015, 1, 1).withTime(0, 0, 0, 0);
System.out.println(Months.monthsBetween(date2, date1).getMonths());
// Returns 1.
Therefore, I recommend you specify a 00:00:00 time portion in each date explicitly.

While other answers are correct they still mask the real problem.
it returns 0 because there is no month in the middle of the two dates
No. It returns 0 because there is time part of DateTime object. You creating two istances of DateTime filled with current moment in time (with hours, minutes, seconds and milliseconds) and then modify just date part. There is no reasons to do it if you want to compare just two dates. use LocalDate instead.
LocalDate date1 = new LocalDate(2015, 2, 1);
LocalDate date2 = new LocalDate(2015, 1, 1);
Months m = Months.monthsBetween(date1, date2);
int monthDif = Math.abs(m.getMonths());//this return 1
Also need to pay attention to the fact that despite the fact that Months docs say nothing about it, Month can contain negative value if first date is after second date. So we need to use Math.abs to really count the number of months between two dates.
The docs say:
Creates a Months representing the number of whole months between the two specified partial datetimes.
But it isn't true. It really calculates the difference in months. Not the number of months.

The way this is calculated depends on the business logic that is to be used. Each month varies in length. One option would be to, in the monthsBetween() function, get the start of the month for both date1 and date2, and compare that.
Something like:
DateTime firstOfMonthDate1 = new DateTime(date1.getYear(), date1.getMonthOfYear(), 1, 0, 0);
DateTime firstOfMonthDate2 = new DateTime(date2.getYear(), date2.getMonthOfYear(), 1, 0, 0);
Months m = Months.monthsBetween(firstOfMonthDate1, firstOfMonthDate2)

Related

java chrono unit difference between year

i have below code to get difference between two years..
long yearsBetween = ChronoUnit.YEARS.between(
customDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
LocalDate.now());
my date value is as below
customDate = 2022-03-07
LocalDate.now() = 2021-10-07
but when i execute ChronoUnit.YEARS.between, it returns "0", but i am expecting "1" as return value. i want to compare only years for the given date and get the difference, excluding days..
If you want to ignore the month and day components of the LocalDate, you can just get the year from each LocalDate and then compare them, like so:
// Let's say we have two LocalDates, date1 and date2:
LocalDate date1 = LocalDate.of(2021, 10, 6);
LocalDate date2 = LocalDate.of(2022, 3, 7);
// We can get the year for each object and then subtract the two years:
long yearsBetween = date2.getYear() - date1.getYear();
// This will print 1 because 2022 is 1 year ahead of 2021:
System.out.println(yearsBetween);
As a side note, there is no need for yearsBetween to be a long data type (64-bit integer). The getYear() method returns an int (32-bit integer), and I doubt you'll ever have to deal with years that far in the future. We can just use:
int yearsBetween = date2.getYear() - date1.getYear();
You can then just plug in your dates where date1 and date2 are like so:
int yearsBetween = customDate.toInstant().atZone(ZoneId.systemDefault())
.toLocalDate().getYear()
- LocalDate.now().getYear();

Joda Time - difference in "complete" months between two dates

How to calculate the number of "full" months between two dates with joda time, dropping incomplete months?
For example, I have 2 dates
LocalDate from = new LocalDate (2018, 9, 10);
LocalDate to = new LocalDate (2018, 11, 15);
Between these dates there is one "full" month - October from 1 to 31.
So I want to get is the number "1" by dropping the "incomplete" months - September and November
I need something like this
System.out.println(Months.monthsBetween(from, to).getMonths()); // returns 2
System.out.println(Months.**completed**MonthsBetween(from, to).getMonths()); // returns 1
UPD 1.
I could achieve what I want as follows:
LocalDate from = new LocalDate (2018, 9, 10);
LocalDate to = new LocalDate (2018, 11, 15);
if (to.getDayOfMonth() != 1)
from = from.plusMonths(1).withDayOfMonth(1);
if (to.getDayOfMonth() != 1)
to = to.withDayOfMonth(1);
System.out.println(Months.monthsBetween(from, to).getMonths());
but maybe there is an out of the box method?
Wouldn't this means that you simply want to remove one month from each interval and do a difference between them?
LocalDate fromMinusOne = from.minus(Months.ONE);
LocalDate toMinusOne = to.minus(Months.ONE);
System.out.println(Months.monthsBetween(fromMinusOne, toMinusOne).getMonths());
Joda Time provides methods to extract days, months and years between two dates. Create two instances of you date.
DateTime startDate = DateTime.parse("1970-01-01", DateTimeFormat.forPattern("yyyy-MM-dd"))
DateTime endDate = DateTime.parse("2015-02-25", DateTimeFormat.forPattern("yyyy-MM-dd"))
You can create your date instances in LocalDate as well instead of DateTime.
Now, complete months between above two dates can be found easily with,
int months = Months.monthsBetween(startDate.withDayOfMonth(1), endDate.withDayOfMonth(1)).getMonths()
For days,
int days = Days.daysBetween(startDate, endDate).getDays()
Difference between two dates in months
For years,
int years = Years.yearsBetween(startDate, endDate).getYears();

how to find the total number of months between the two dates including extra days?

I have a requirement where I need to find out number of months between two dates including extra days.
example:
start date:01/01/2014
end date:21/02/2014
LocalDate startDate = new LocalDate(startDate1);
LocalDate endDate = new LocalDate(endDate1);
PeriodType monthDay =PeriodType.yearMonthDay().withYearsRemoved();
Period difference = new Period(startDate, endDate, monthDay);
int months = difference.getMonths();
int days = difference.getDays()
the out put I will get is:
months:1 days:20
but my requirement is I want get total months including that extra day.
like:1.66 months.
How to get this one in java?
In order to be able to say 1.66 months you need to define how long a month is. It's not always the same. If you assume that a month is 30 days long then you can solve this by using:
Date startDate = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2014");
Date endDate = new SimpleDateFormat("dd/MM/yyyy").parse("21/02/2014");
double result = (endDate.getTime() - startDate.getTime()) / (1000D*60*60*24*30);
This gives us 1.7 and if you divide with 31 you get 1.6451612903225807.
If you want a better (but not perfect) approximation of how long a month is you can try 365/12 which will give you 1.6767123287671233 but still this is not perfect because leap years have 366 days.
The problem though is not with the formula, but with the problem definition. Nobody in real life says "I'll be there in exactly 1.66 months" and nobody will ever ask you to convert 1.66 months in days.
This is my own answer, a variation on cherouvim's
final Date startDate = new GregorianCalendar (2014, 0, 1).getTime ();
final Date endDate = new GregorianCalendar (2014, 1, 21).getTime ();
System.out.println ((endDate.getTime () - startDate.getTime ()) / (float) (1000L * 60 * 60 * 24 * 30));

Joda-Time convert days to months and days

How can I convert the number of days to number of months and days using Joda-Time. For example, when I have 33 days, it should display 1 month and 2 days.
public static void main(String[]args)
{
Calendar calendar = new GregorianCalendar();
int years = calendar.get(Calendar.YEAR);
int month = (calendar.get(Calendar.MONTH))+1;
int day = calendar.get(Calendar.DATE);
DateTime startDate = new DateTime(years, month, day, 0, 0, 0, 0);
DateTime endDate = new DateTime(2014, 7, 3, 0, 0, 0, 0);
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
int t = 1000 * 60 * 60 *24;
int days = days/t;
System.out.println(days);
}
You can use class org.joda.time.Period for this.
Example:
Period p = new Period(startDate, endDate, PeriodType.yearMonthDayTime());
System.out.println(p.getMonths());
System.out.println(p.getDays());
Trying to create a decimal fraction number to represent months makes no sense to me, as months have different numbers of days (28, 29, 30, 31).
ISO 8601
The sensible ISO 8601 standard defines a textual way to represent a span of time in terms of months and days, called Durations. Joda-Time has a class for this purpose called Period. Forgive the mismatch in terms, as there is no standard definition of date-time terminology yet.
For an example of using the Period class, see this other answer by Ilya on this question.
ISO Duration
The textual format is PnYnMnDTnHnMnS where P means "Period" and the T separates the date portion from time portion. The other parts are optional. One month and two days would be P1M2D. The Joda-Time Period class both parses and generates such strings.

How to subtract two joda datetimes? [duplicate]

This question already has answers here:
Number of days between two dates in Joda-Time
(9 answers)
Closed 9 years ago.
I know this isn't "the way it's supposed to work", but still: If you have two DateTime objects, what's a good way to subtract them? Convert them to Date objects?
DateTime start = new DateTime();
System.out.println(start + " - doing some stuff");
// do stuff
DateTime end = new DateTime();
Period diff = // end - start ???
System.out.println(end + " - doing some stuff took diff seconds");
Period has a constructor that takes two ReadableInstant instances:
Period diff = new Period(start, end);
(ReadableInstant is an interface implemented by DateTime, as well as other classes.)
From your example you seem to want the difference in seconds so this should help :
Seconds diff = Seconds.secondsBetween(start, end);
Does this help? http://joda-time.sourceforge.net/key_period.html
It shows the below example
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0);
// period of 1 year and 7 days
Period period = new Period(start, end);
// calc will equal end
DateTime calc = start.plus(period);
// able to calculate whole days between two dates easily
Days days = Days.daysBetween(start, end);
Depends in which precision you want to get. You should check the org.joda.time package and check for the Helper classes such as Hours, Days, etc.
I think you can create a Period using this constructor which takes two DateTime objects.

Categories

Resources