0

I want to categorize values based on months so to filter those values required 1st & last date of last three months based on current month including current month values. Here how many last months is parameter. I wanted list of all months 1st date and last date. Any logic for the same will be helpful.

for example:-

     //     parameters 
          int lastMonths = 3;
          date currentDate= 26-04-2019;

 //expected output
 current month is 04-2019 ,1st date is 1-04-2019 and last date is 30-04-2019 
 previous month is 03-2019, 1st date is 01-03-2019 and last date is 31-03-2019
 previous month is 02-2019, 1st date is 01-02-2019 and last date is 28-02-2019

6 Answers 6

1

Use java.util.Calendar for addition and subraction in date

and

java.text.DateFormat to format date

    DateFormat format = new SimpleDateFormat("dd-MM-yyyy", Locale.US);
    DateFormat monthFormat = new SimpleDateFormat("MM-yyyy", Locale.US);
    Calendar cal = Calendar.getInstance();
    cal.setTime(format.parse("26-04-2019"));
    for (int i = 0; i < 3; i++){
        System.out.println("currentDate: " + monthFormat.format(cal.getTime())); // print current month

        cal.set(Calendar.DAY_OF_MONTH, 1);
        System.out.println("first date: " + format.format(cal.getTime())); // print first date

        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.DATE, -1);

        System.out.println("last date: " + format.format(cal.getTime())); // print last date


        cal.add(Calendar.MONTH, -1);
    }
1
  • These terrible classes were supplanted years ago by the java.time classes with the adoption of JSR 310. Suggesting their use in 2019 is poor advice. Commented Apr 26, 2019 at 18:18
1

Important to say - there are tons of libraries who will give you this specific need, but I would like relying on one that does the work and was actually designed for (some of yours...) those use cases - Java.time.LocalDate library (already built into Java 8)

import java.time.LocalDate;

LocalDate now = LocalDate.now(); // 2019-04-26

In order to get first and last days of month, you can use:

LocalDate start = YearMonth.now().atDay(1);

(now can be some other month, of course)

LocalDate end = YearMonth.now().atEndOfMonth();

You can use it specifically on one / two months, or with some for loop. Examples below:
1. Specific call:

LocalDate earlierOneMonth = now.minusMonths(1); // 2019-03-26
earlierOneMonth.getDay(); // 26

2. For Loop: (so you'll need something like an array / list to store those values...)

for(int i=0; i < lastMonths - 1; i++){
   arr(i) = now.minusMonths(i + 1);

}

Also, in order to get the name of the month, you can use ->

earlierOneMonth.getMonth(); // APRIL
earlierOneMonth.getMonth.getValue(); // 04

Lastly, in order to get the year, you can use ->

earlier.getYear(); // 2019

Once you have all of your desired values, you can print them out as you requested, with that expected output:

 "current month is" + nowMonth + "-" + nowYear + " ,1st date is" +  nowDay + "-" + nowMonth + "-" + nowYear + " and last date is ...

Let me know if it's clear enough :)

1

tl;dr

YearMonth.now().minusMonths( 3 ).atDay( 1 )      // Get the first day of the month of three months ago. Returns `LocalDate` object.
YearMonth.now().minusMonths( 3 ).atEndOfMonth()  // Get the last day of the month of three months ago. Returns `LocalDate` object.

YearMonth

You really care about the months. The dates are secondary. So focus on the months. Java has a class for that!

The YearMonth class represents a particular month of a particular year.

ZoneId z = ZoneId.of( "America/Edmonton" ) ;
YearMonth currentYm = YearMonth.now( z ) ;

Collect your months of interest.

List< YearMonth > yms = new ArrayList<>() ;
int limit = 3 ; // We want current month plus three previous months. 
for( int i = 0 ; i <= limit ; i ++ ) {
    YearMonth ym = currentYm.minusMonths( i ) ;
    yms.add( ym ) ;
}

When you need dates, loop the list. Let YearMonth determine the first and last days of the month.

for( YearMonth ym : yms ) {
    System.out.println( "YearMonth: " + ym + " starts: " + ym.atDay( 1 ) +  " ends: " + ym.atEndOfMonth() ) ; 
}

See this code run live at IdeOne.com.

YearMonth: 2019-04 starts: 2019-04-01 ends: 2019-04-30

YearMonth: 2019-03 starts: 2019-03-01 ends: 2019-03-31

YearMonth: 2019-02 starts: 2019-02-01 ends: 2019-02-28

YearMonth: 2019-01 starts: 2019-01-01 ends: 2019-01-31

0

If you need a Date object then the following will do just fine

        Date date = getDate(targetDate);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -3);
        calendar.set(Calendar.DAY_OF_MONTH, 1);

        // calendar.getTime()
        // The line above returns Date object

If you need a plain String then you can format it any way you want by simply using DateTimeFormatter from org.joda.time library and just use it's print() method on calendar.getTimeInMillis().

1
  • These terrible classes were supplanted years ago by the java.time classes with the adoption of JSR 310. Commented Apr 26, 2019 at 18:00
0
    LocalDate currentDate = LocalDate.of(2019, 4, 26);//current date
    System.out.println(currentDate);
    int lastMonths = 3;//number of months
    LocalDate prevDate = null;
    LocalDate start = null;
    LocalDate end = null;

    for(int i = 0; i < lastMonths; i++) {
        if(prevDate == null) {
            start = currentDate.withDayOfMonth(1);//First day of current month
            end = currentDate.withDayOfMonth(currentDate.lengthOfMonth());//Last day of current month
            prevDate = currentDate.minusMonths(1);//subtracting one month from current month 
        } else {
            start = prevDate.withDayOfMonth(1);//First day of previous month
            end = prevDate.withDayOfMonth(prevDate.lengthOfMonth());//Last day of previous month
            prevDate = prevDate.minusMonths(1);//subtracting one month from previous month
        }
        System.out.println(start + " " + end);
    }

Output:

2019-04-26
2019-04-01 2019-04-30
2019-03-01 2019-03-31
2019-02-01 2019-02-28

Reference: Get first and last day of month using threeten, LocalDate

0
    int lastMonths = 3;

    Calendar calendar = Calendar.getInstance();

    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH) + 1;
    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);

    DateFormat monthYearFormat = new SimpleDateFormat("MM-yyyy");

    for (int i = 0; i < lastMonths; i++) {

        int monthOfYear = month - i;

        // if month is january, reset couter and month
        if(monthOfYear == 0) {
            month = 13;
            year -= 1;
            i = 0;
            continue;
        }

        // get last day of month (month length)
        YearMonth yearMonth = YearMonth.of(year, monthOfYear);
        int firstDay = 1;
        int lastDay  = yearMonth.lengthOfMonth();

        // create date with given year, month and day
        Date date = new GregorianCalendar(year, monthOfYear - 1, firstDay).getTime();

        String monthAndYear = monthYearFormat.format(date);

        String currentOrPrevious;

        if (i == 0) {
            currentOrPrevious = "current";
        } else {
            currentOrPrevious = "previous";
        }

        String output = String.format("%s month is %s, 1st date is %02d-%s and last date is %d-%s", currentOrPrevious, monthAndYear, firstDay, monthAndYear, lastDay, monthAndYear);

        System.out.println(output);
    }

Output:

current month is 04-2019, 1st date is 01-04-2019 and last date is 30-04-2019
previous month is 03-2019, 1st date is 01-03-2019 and last date is 31-03-2019
previous month is 02-2019, 1st date is 01-02-2019 and last date is 28-02-2019
1
  • These terrible classes were supplanted years ago by java.time with the adoption of JSR 310. Commented Apr 26, 2019 at 17:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.