vlina
vlina

Reputation: 81

Java How to use for loop to populate Year and Month list?

How can I loop year and months to display below output? Limit of the period to show is current month and year Also, show 3 years inclusive of the year as of date. Meaning if its 2019 now, show 2018 and 2017.

I tried with some code to run as java application in hope to get the expected output below but this is what I've tried and got.

Would appreciate much if anyone can shed some light here.

public class TestClass {
public static void main(String[] args) {
    Calendar today = Calendar.getInstance();
    //month=5, index starts from 0
    int month = today.get(Calendar.MONTH);
    //year=2019
    int year = today.get(Calendar.YEAR);

    for(int i = 0; i < 3; i++) {    //year
        for(int j= 0; j <= month; j++) {    //month
        System.out.println("Value of year: " + (year - 2)); //start from 2017 and iterate to 2 years ahead
        System.out.println("Value of month: " + (month + 1)); //start from January (index val: 1) and iterate to today's month
        }
    }
}

}

Expected Output:

2017 1 2017 2 2017 3 2017 4 2017 5 2017 6 2017 7 2017 8 2017 9 2017 10 2017 11 2017 12

2018 1 2018 2 2018 3 2018 4 2018 5 2018 6 2018 7 2018 8 2018 9 2018 10 2018 11 2018 12

2019 1 2019 2 2019 3 2019 4 2019 5 2019 6

Upvotes: 0

Views: 2983

Answers (4)

fan
fan

Reputation: 2364

I would go with the stream API.

    var from =  YearMonth.now().minusYears(3).withMonth(Month.JANUARY.getValue());
var to = YearMonth.now().withMonth(Month.DECEMBER.getValue());
Stream.iterate(
    from,
    ym -> !ym.isAfter(to),
    ym -> ym.plusMonths(1))
  .forEach(ym -> {
    System.out.println(ym);
  });

You iterate over stream. The first parameter defines the start The second parameter is the condition to satisfy. The third is the increment.

Upvotes: 0

Vimukthi
Vimukthi

Reputation: 880

Try below code. I'm using java 8 and java.time.LocalDate,

LocalDate currentDate = LocalDate.now();
int year = currentDate.getYear();
int month = currentDate.getMonthValue();

for (int i = year - 2; i <= year; i++) {
    for (int j = 1; j <= 12; j++) {
        if (i == year && j == month) {
            System.out.print(i + " " + j + " ");
            break;
        }
            System.out.print(i + " " + j + " ");
        }
    }
}

Output

2017 1 2017 2 2017 3 2017 4 2017 5 2017 6 2017 7 2017 8 2017 9 2017 10 2017 11 2017 12 2018 1 2018 2 2018 3 2018 4 2018 5 2018 6 2018 7 2018 8 2018 9 2018 10 2018 11 2018 12 2019 1 2019 2 2019 3 2019 4 2019 5 2019 6 

Upvotes: 1

Basil Bourque
Basil Bourque

Reputation: 339332

tl;dr

YearMonth                        // Represent a specific month as a whole.
.now(                            // Determine the current month as seen in the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "Asia/Tokyo" )    // Specify your desired/expected time zone.
)                                // Returns a `YearMonth` object.
.withMonth( 1 )                  // Move back to January of this year. Returns another `YearMonth` object rather than changing (mutating) the original, per the immutable objects pattern.
.minusYears( 2 )                 // Jump back two years in the past. Returns yet another `YearMonth` object.

java.time

You are using terrible old date-time classes that were supplanted years ago by the modern java.time classes.

Also, you are ignoring the issue of time zone. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

YearMonth

You care only about the year and the month, without any date. So use the YearMonth class.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
YearMonth yearMonthNow = YearMonth.now( z ) ;

YearMonth yearMonthJanuaryTwoYearAgo = yearMonthNow.withMonth( 1 ).minusYears( 2 ) ;

Increment a month at a time, collecting as we go.

ArrayList< YearMonth > yearMonths = new ArrayList<>();
YearMonth ym = yearMonthJanuaryTwoYearAgo ;
while( ! ym.isAfter( yearMonthNow ) ) 
{
    yearMonths.add( ym ) ;
    // Set up the next loop.
    ym = ym.plusMonths( 1 ) ;
}

Dump to console.

System.out.println( yearMonths ) ;

See this code run live at IdeOne.com.

[2017-01, 2017-02, 2017-03, 2017-04, 2017-05, 2017-06, 2017-07, 2017-08, 2017-09, 2017-10, 2017-11, 2017-12, 2018-01, 2018-02, 2018-03, 2018-04, 2018-05, 2018-06, 2018-07, 2018-08, 2018-09, 2018-10, 2018-11, 2018-12, 2019-01, 2019-02, 2019-03, 2019-04, 2019-05, 2019-06]

If you want to exclude the current month, use:

while( ym.isBefore( yearMonthNow ) ) 

Upvotes: 3

kars89
kars89

Reputation: 48

Edit: using the year and month in the loop

for(int i = year-2; i <= year; i++) {    //year

    for(int j= 1; (j <= 12 || (j == month && i == year)); j++) {    //month
        System.out.println("Value of year: " + i); //start from 2017 and iterate to 2 years ahead
        System.out.println("Value of month: " + j); //start from January (index val: 1) and iterate to today's month
    }
}

Upvotes: -1

Related Questions