Reputation: 57
I choose the starting date (example 31/01/2014) and ending date (example 31/12/2014), I insert a record every month. If I get the next month is February 28th, but then I always get 28 though March, April, etc. .. How can I fix? I hope I explained
SimpleDateFormat sdf1 = new SimpleDateFormat( "yyyy-MM-dd" );
ContentValues cv = new ContentValues();
for(
int i=0;
calendar1.getTime().before(calendar2.getTime());
i++
) {
calendar1.add(Calendar.MONTH, 1);
if (calendar1.getTime().before(calendar2.getTime())) {
String strDate = sdf1.format(calendar1.getTime());
cv.put(etableTable.DATE, strDate);
db.insert(etableTable.TABLE_NAME, null, cv);
...
}
}
Upvotes: 1
Views: 2616
Reputation: 339342
List < LocalDate > endOfMonths =
start
.datesUntil( end ) // Returns `Stream` of `LocalDate` objects.
.map ( YearMonth :: from ) // For each `LocalDate`, produce a `YearMonth`. Returns a `Stream` of `YearMonth` objects.
.distinct () // Eliminate duplicates.
.map ( YearMonth :: atEndOfMonth ) // For each `YearMonth`, produce a `LocalDate` that is the last date of that month. Returns a `Stream` of `LocalDate` objects.
.toList () ; // Collect `LocalDate` objects into an unmodifiable `List`.
Avoid the terribly-flawed legacy classes such as Date
, Calendar
, SimpleDateFormat
, etc. In modern Java (8+) use only the java.time classes.
YearMonth
If you want to work with specific months, use YearMonth
class.
We can easily get all the months of your date range. Start by getting all the dates as LocalDate
objects.
LocalDate start = LocalDate.parse ( "2013-01-01" ) ; // Standard ISO 8601 formatted text.
LocalDate end = LocalDate.parse( "2013-12-31" ) ;
List < LocalDate > datesOfYear = start.datesUntil( end ).toList() ;
For each date, get its year-month. Eliminate duplicates.
List < YearMonth > yearMonths =
datesOfYear
.stream ()
.map ( YearMonth :: from )
.distinct ()
.toList () ;
Of course, we could combine those operations.
List < YearMonth > yearMonths =
start
.datesUntil( end ) // Returns `Stream` of `LocalDate` objects.
.map ( YearMonth :: from ) // For each `LocalDate`, produce a `YearMonth`. Returns a `Stream` of `YearMonth` objects.
.distinct () // Eliminate duplicates.
.toList () ; // Collect into an unmodifiable `List`.
Apparently you want the end of each month. So ask each YearMonth
object for a LocalDate
representing its end-of-month date.
List < LocalDate > endOfMonths = yearMonths.stream ().map ( YearMonth :: atEndOfMonth ).toList () ;
Again, we could combine with operations above.
List < LocalDate > endOfMonths =
start
.datesUntil( end ) // Returns `Stream` of `LocalDate` objects.
.map ( YearMonth :: from ) // For each `LocalDate`, produce a `YearMonth`. Returns a `Stream` of `YearMonth` objects.
.distinct () // Eliminate duplicates.
.map ( YearMonth :: atEndOfMonth ) // For each `YearMonth`, produce a `LocalDate` that is the last date of that month. Returns a `Stream` of `LocalDate` objects.
.toList () ; // Collect `LocalDate` objects into an unmodifiable `List`.
Now you have the dates you need to do your database work.
for ( LocalDate endOfMonth : endOfMonths )
{
…
}
Upvotes: 1
Reputation: 44071
Assuming that you speak about class GregorianCalendar
- Instead of calendar1.add(Calendar.MONTH, 1)
try to also call following method as work-around:
static GregorianCalendar moveToEndOfMonth(GregorianCalendar gcal) {
gcal.add(Calendar.MONTH, 1); // moving to some day of next month
gcal.set(Calendar.DAY_OF_MONTH, 1); // moving to first day of current month
gcal.add(Calendar.DATE, -1); // moving to last day of previous month
}
So your final code should look like:
calendar1.add(Calendar.MONTH, 1);
moveToEndOfMonth(calendar1);
Why? The analysis of @DavidCAdams is right, see his answer.
Upvotes: 1
Reputation: 1973
Where are you creating the calendar objects? Since you are incrementing the MONTH, and it is January 30, you get February 28 for the next month, since next month only has 28 days in it. There is no Feb 30, 2014. Thereafter, when you increment the month, you get March 28, April 28, etc. etc.
Upvotes: 1