Reputation: 3578
I have a java programe which I can set a date in yyyy-MM-dd and I can get next and previous dates from it. following methods do the work,,
public void setDate(String date) {
StringTokenizer st = new StringTokenizer(date, "-");
year = Integer.parseInt(st.nextToken());
monthNo = Integer.parseInt(st.nextToken()) - 1;
day = Integer.parseInt(st.nextToken());
date = year + "-" + monthNo + "-" + day;
}
public String getPreviousMonth(boolean maxDate) {
Calendar calendar = Calendar.getInstance();
if (maxDate) {
calendar.set(year, monthNo, 1);
int maxD = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
calendar.set(year, monthNo, maxD);
} else {
calendar.set(year, monthNo, day);
}
if (monthNo == 0) {
calendar.add(calendar.MONTH, -1);
} else {
calendar.add(calendar.MONTH, -1);
}
String date = (calendar.get(calendar.YEAR)) + "-" + (calendar.get(calendar.MONTH) + 1) + "-" + calendar.get(calendar.DAY_OF_MONTH);
calendar.clear();
return date;
}
public String getNextMonth(boolean maxDate) {
Calendar calendar = Calendar.getInstance();
if (maxDate) {
calendar.set(year, monthNo, 1);
int maxD = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
calendar.set(year, monthNo, maxD);
} else {
calendar.set(year, monthNo, day);
}
if (monthNo == 11) {
calendar.add(calendar.MONTH, 1);
} else {
calendar.add(calendar.MONTH, 1);
}
public String getCurrentMonth(boolean maxDate){
Calendar calendar = Calendar.getInstance();
if (maxDate) {
calendar.set(year, monthNo, 1);
int maxD = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
calendar.set(year, monthNo, maxD);
} else {
calendar.set(year, monthNo, day);
}
String date = (calendar.get(calendar.YEAR)) + "-" + (calendar.get(calendar.MONTH) + 1) + "-" + calendar.get(calendar.DAY_OF_MONTH);
calendar.clear();
return date;
}
When I set the date to January and February, it gives me the correct output but if I select another month other than January and February I can't get the correct day, followings are some results,
this is OK
2012-1-31 - current month
2011-12-31 - previous month
2012-2-29 - next month
2012-2-29 current month
2012-1-29 previous month ***day should be 31
2012-3-29 next month ***day should be 31
this is OK
2011-12-31 current month
2011-11-30 previous month
2012-1-31 next month
2011-11-30 current month
2011-10-30 previous month *** this should be 31
2011-12-30 next month *** this should be 31
this is OK
2011-12-31 current month
2011-11-30 previous month
2012-1-31 next month
Please tell me where am I wrong...
Upvotes: 2
Views: 2591
Reputation: 338326
Use java.time.LocalDate
rather than the terribly-flawed legacy class Calendar
.
LocalDate
.parse( "2025-01-23" ) // Parse text in standard ISO 8601 format, YYYY-MM-DD.
.plusDays( 1 )
.minusDays( 2 )
.minusMonths( 1 )
.plusMonths( 2 )
.withDayOfMonth( 1 )
.toString() // Generate text in standard ISO 8601 format.
See that code run at Ideone.com.
2025-02-01
The terribly-flawed legacy classes Date
, Calendar
, SimpleDateFormat
, etc. were years ago supplanted by the modern java.time classes defined in JSR 310, built into Java 8 and later.
Your input text complies with ISO 8601 standard format, YYYY-MM-DD. The java.time classes use ISO 8601 formats by default when parsing/generating text. So no need to specify a formatting pattern.
LocalDate
To represent a date-only value, without time-of-day, without time zone, use LocalDate
.
String input = "2025-01-23" ;
LocalDate ld = LocalDate.parse( input ) ;
To perform date-math, use the minus
& plus
methods.
LocalDate dayBefore = ld.minusDays( 1 ) ;
LocalDate dayAfter = ld.plusDays( 1 ) ;
Move to another month.
LocalDate monthBefore = ld.minusMonths( 1 ) ;
LocalDate monthAfter = ld.plusMonths( 1 ) ;
Get first & last dates of the month.
LocalDate firstOfMonth = ld.withDayOfMonth( 1 ) ;
LocalDate lastOfMonth = ld.withDayOfMonth( ld.lengthOfMonth() ) ;
YearMonth
If you work frequently with the concept of month, use YearMonth
class.
YearMonth ym = YearMonth.from( ld ) ;
LocalDate firstOfMonth = ym.atDay( 1 ) ;
LocalDate endOfMonth = ym.atEndOfMonth() ;
Upvotes: 1
Reputation: 6392
The problem was that you retrieved maximum amount of days in current month BEFORE actually changing the month.
Here how should it look.
public String getNextMonth(boolean maxDate) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, monthNo, 1);
calendar.add(Calendar.MONTH, 1);
if (maxDate) {
int maxD = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, maxD);
} else {
calendar.set(Calendar.DAY_OF_MONTH, day);
}
String date = (calendar.get(Calendar.YEAR)) + "-" + (calendar.get(Calendar.MONTH) + 1) + "-" + calendar.get(Calendar.DAY_OF_MONTH);
calendar.clear();
return date;
}
Upvotes: 1
Reputation: 1751
Fixing getNextMonth for you. Same thing needs to be done for getPreviousMonth. See the comments inline with code below:
public String getNextMonth(boolean maxDate) {
Calendar calendar = Calendar.getInstance();
if (maxDate) {
calendar.set(year, monthNo, 1);
/* Move these two lines to end of method.
int maxD = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
calendar.set(year, monthNo, maxD);
*/
} else {
calendar.set(year, monthNo, day);
}
//Not sure why have you used if/else. Both are doing the same thing
if (monthNo == 11) {
calendar.add(calendar.MONTH, 1);
} else {
calendar.add(calendar.MONTH, 1);
}
//here i.e. After you have calculated your next month.
int maxD = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
calendar.set(year, monthNo, maxD);
}
Upvotes: 3