I tried to add full months from a given start date by using java DateTime
and method plusMonths()
.
When my start time is at the beginning of a month, everything works like expected:
DateTime startOfMonth = new DateTime(2013, 1, 1, 00, 00, 00);
System.out.println(startOfMonth.toString());
for (int i = 0; i < 12; i++) {
startOfMonth = startOfMonth.plusMonths(1);
System.out.println(startOfMonth.toString());
}
The output is the first day of every month like expected and everything is great!
2013-01-01T00:00:00.000+01:00
2013-02-01T00:00:00.000+01:00
2013-03-01T00:00:00.000+01:00
2013-04-01T00:00:00.000+02:00
2013-05-01T00:00:00.000+02:00
2013-06-01T00:00:00.000+02:00
2013-07-01T00:00:00.000+02:00
2013-08-01T00:00:00.000+02:00
2013-09-01T00:00:00.000+02:00
2013-10-01T00:00:00.000+02:00
2013-11-01T00:00:00.000+01:00
2013-12-01T00:00:00.000+01:00
2014-01-01T00:00:00.000+01:00
But when I change my example to the end of a month it doesn't return what I want!
System.out.println("");
DateTime endOfMonth = new DateTime(2012, 12, 31, 23, 59, 59);
System.out.println(endOfMonth.toString());
for (int i = 0; i < 12; i++) {
endOfMonth = endOfMonth.plusMonths(1);
System.out.println(endOfMonth.toString());
}
This returns:
2012-12-31T23:59:59.000+01:00
2013-01-31T23:59:59.000+01:00
2013-02-28T23:59:59.000+01:00
2013-03-28T23:59:59.000+01:00
2013-04-28T23:59:59.000+02:00
2013-05-28T23:59:59.000+02:00
2013-06-28T23:59:59.000+02:00
2013-07-28T23:59:59.000+02:00
2013-08-28T23:59:59.000+02:00
2013-09-28T23:59:59.000+02:00
2013-10-28T23:59:59.000+01:00
2013-11-28T23:59:59.000+01:00
2013-12-28T23:59:59.000+01:00
So, why is "2013-02-28T23:59:59.000+01:00"
plus one month not "2013-03-31T23:59:59.000+01:00"
?
Where are these three days?
The problem with date operations is that months have different number of days. In January, you have 31 days, February has only 28. If you add "one month" to January 31st, the software can't guess what you want to achieve, so it adds increments the month which gives you February, 31st - which isn't valid. The next step is then to reconcile the date which yields these odd results that you're seeing.
Note: In the original Java Date classes, you'd get 2nd or 3rd of March after adding one month to January which isn't exactly better :-)
The correct way to iterate over the end of month is to iterate over the first day of then month and the subtract one day (or one millisecond):
DateTime startOfMonth = new DateTime(2013, 1, 1, 00, 00, 00);
System.out.println(startOfMonth.toString());
for (int i = 0; i < 12; i++) {
startOfMonth = startOfMonth.plusMonths(1);
DateTime endOfMonth = startOfMonth.minusDays(1); // magic here
System.out.println(startOfMonth + "-" + endOfMonth);
}
If you just need a date range, use an half open range [start,end)
where end
is always the first of a month.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With