Issue
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
Solution
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 dayOfWeek = DayOfWeek.of(day);
LocalDate currDate = LocalDate.of(year, 1, 1)
.with(TemporalAdjusters.nextOrSame(dayOfWeek));
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.(1)
Note: DayOfWeek.MONDAY
has value 1, DayOfWeek.SUNDAY
has value 7.(2) But I agree with Ole V.V. here: you are better off using DayOfWeek
constants instead of integers, as this is better readable.
(1) LocalDate
itself is immutable, so nothing is actually added. Instead, a new instance is returned with one week added.
(2) Well, at least DayOfWeek.of(int dayOfWeek)
maps those values to the respective days-of-week. The enum itself does not hold a particular value, other than the enum's ordinal value.
Answered By - MC Emperor
Answer Checked By - Robin (JavaFixing Admin)