Home > Back-end >  How can i fix the problem printing all the saturdays and sundays of any given year?
How can i fix the problem printing all the saturdays and sundays of any given year?

Time:09-27

i'm trying to print all the saturdays and sundays of any given year. but for some reason the program won't print only saturdays but not fridays for the year 2022. i've tried different values for year but still didn't find any, other than 2022. what did i do wrong here??? bellow is the code.

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class JavaDayFinder extends Thread {

    int day;
    int year;

    JavaDayFinder(int day, int year) {
        this.day = day;
        this.year = year;
    }

    @Override
    public void run() {
        Calendar calendar = new GregorianCalendar();
        calendar.set(year, Calendar.JANUARY, 1);
        calendar.getTime();
        calendar.set(Calendar.DAY_OF_WEEK, day);
        calendar.getTime();

        while (calendar.get(Calendar.YEAR) == year) {
            System.out.println(calendar.getTime());
            calendar.add(Calendar.DAY_OF_MONTH, 7);
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("This program prints all the common holidays (Fridays & Saturdays) of any given year.");
        System.out.print("Please input the year of which you want to know the holidays: ");
        Scanner scan = new Scanner(System.in);
        int year = scan.nextInt();
        System.out.println("Given year : "   year);
        System.out.println();

        JavaDayFinder friday = new JavaDayFinder(6, year);
        JavaDayFinder saturday = new JavaDayFinder(7, year);
        friday.start();
        saturday.start();
    }
}

bellow is the output

This program prints all the common holidays (Fridays & Saturdays) of any given year.
Please input the year of which you want to know the holidays: 2022
Given year : 2022

Sat Jan 01 17:05:56 BDT 2022
Sat Jan 08 17:05:56 BDT 2022
Sat Jan 15 17:05:56 BDT 2022
Sat Jan 22 17:05:56 BDT 2022
Sat Jan 29 17:05:56 BDT 2022
Sat Feb 05 17:05:56 BDT 2022
Sat Feb 12 17:05:56 BDT 2022
Sat Feb 19 17:05:56 BDT 2022
Sat Feb 26 17:05:56 BDT 2022
Sat Mar 05 17:05:56 BDT 2022
Sat Mar 12 17:05:56 BDT 2022
Sat Mar 19 17:05:56 BDT 2022
Sat Mar 26 17:05:56 BDT 2022
Sat Apr 02 17:05:56 BDT 2022
Sat Apr 09 17:05:56 BDT 2022
Sat Apr 16 17:05:56 BDT 2022
Sat Apr 23 17:05:56 BDT 2022
Sat Apr 30 17:05:56 BDT 2022
Sat May 07 17:05:56 BDT 2022
Sat May 14 17:05:56 BDT 2022
Sat May 21 17:05:56 BDT 2022
Sat May 28 17:05:56 BDT 2022
Sat Jun 04 17:05:56 BDT 2022
Sat Jun 11 17:05:56 BDT 2022
Sat Jun 18 17:05:56 BDT 2022
Sat Jun 25 17:05:56 BDT 2022
Sat Jul 02 17:05:56 BDT 2022
Sat Jul 09 17:05:56 BDT 2022
Sat Jul 16 17:05:56 BDT 2022
Sat Jul 23 17:05:56 BDT 2022
Sat Jul 30 17:05:56 BDT 2022
Sat Aug 06 17:05:56 BDT 2022
Sat Aug 13 17:05:56 BDT 2022
Sat Aug 20 17:05:56 BDT 2022
Sat Aug 27 17:05:56 BDT 2022
Sat Sep 03 17:05:56 BDT 2022
Sat Sep 10 17:05:56 BDT 2022
Sat Sep 17 17:05:56 BDT 2022
Sat Sep 24 17:05:56 BDT 2022
Sat Oct 01 17:05:56 BDT 2022
Sat Oct 08 17:05:56 BDT 2022
Sat Oct 15 17:05:56 BDT 2022
Sat Oct 22 17:05:56 BDT 2022
Sat Oct 29 17:05:56 BDT 2022
Sat Nov 05 17:05:56 BDT 2022
Sat Nov 12 17:05:56 BDT 2022
Sat Nov 19 17:05:56 BDT 2022
Sat Nov 26 17:05:56 BDT 2022
Sat Dec 03 17:05:56 BDT 2022
Sat Dec 10 17:05:56 BDT 2022
Sat Dec 17 17:05:56 BDT 2022
Sat Dec 24 17:05:56 BDT 2022
Sat Dec 31 17:05:56 BDT 2022

Process finished with exit code 0

CodePudding user response:

Well, that is because for Friday, the code line calendar.set(Calendar.DAY_OF_WEEK, day) causes the year to be set to 2021, so the line while (calendar.get(Calendar.YEAR) == year) is immediately skipped because of the condition being false.

As Ole V.V. already said in the comments, you should not use Calendar anymore. Use LocalDate and DayOfWeek. Here is the modified code:

@Override
public void run() {
    var dow = DayOfWeek.of(day);
    LocalDate currDate = LocalDate.of(year, 1, 1).with(TemporalAdjusters.nextOrSame(dow));

    while (currDate.getYear() == year) {
        System.out.println(currDate);
        currDate = currDate.plusWeeks(1);
        try {
            Thread.sleep(250);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Here's what happens:

  • LocalDate.of(year, 1, 1) yields January 1st of the given year.
  • TemporalAdjusters.nextOrSame(DayOfWeek) takes a given date and moves to the next specified day-of-week, or stays on January 1st if it is the specified day-of-week. In the example of the year 2022, 1st of January is a Saturday, so the yielded date will be January 7th, 2022, because that's the next Friday.
  • Within the loop, currDate.plusWeeks(1) obviously adds a week to the current date.

CodePudding user response:

Explanation:

If the 1st Jan was a Saturday, which means that week's Friday will be 1 day before the 1st Jan i.e. 31st Dec. When you set the below field for Friday, it's setting the value to 31 Dec, and because of your while condition, it doesn't execute the loop.

calendar.set(Calendar.DAY_OF_WEEK, day);

This code won't work for an edge case i.e. any year starting with a Saturday won't print Fridays. E.g. 2011, 2028, etc.

The below method sets to the 1st Friday/Sat/Any-Weekday of the month:

    private void setNextAvailableDay(Calendar calendar, int day) {
        Date currTime = calendar.getTime();
        calendar.set(Calendar.DAY_OF_WEEK, day);
        if(currTime.after(calendar.getTime()))
            calendar.add(Calendar.DAY_OF_MONTH, 7);
    }
calendar.set(Calendar.DAY_OF_WEEK, day);
// can be replaced by
setNextAvailableDay(calendar, day)
  • Related