1

I need some help; I've been stuck with this situation for a while. My goal is to display a calendar form for the month of August 2021. I have my code here. I only need the month of August since I just want to post a calendar of the month for users to see the date for the opening of classes. It displays the calendar, but I feel it has a more efficient way of writing this type of program, but I don't know how. Can you please help me?

Here is my code:

public class Calendar {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.println("\t\tMONTH OF AUGUST 2021");
        System.out.println("–––––––––––––––-------------------------––––––––––––––");
        System.out.println("\nSun\tMon\tTue\tWed\tThu\tFri\tSat\n");
        System.out.println("–––––––––––––––-------------------------––––––––––––––");
        int [][]num={{1,2,3,4,5,6,7},{8,9,10,11,12,13,14},{15,16,17,18,19,20,21},{22,23,24,25,26,27,28},{29,30,31,1,2,3,4}};
      
        for (int i=1; i<num.length;i++){
            for(int j=8; j<num[i].length; j++){
                num[i][j]=i+j;
            }
        }
        for(int[] a: num){
            for(int i:a){
                System.out.print(i + "\t");
            }
            System.out.println("\n");
        }
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Does this answer your question? [How to display calendar in java](https://stackoverflow.com/questions/35679827/how-to-display-calendar-in-java) – Stefan Freitag Jul 04 '21 at 09:35

3 Answers3

1

To display a calendar in the Console window (and it shouldn't matter what month) then you can do it with this java method:

public static void displayConsoleCalendar(int day, int month, int year, 
                                          boolean... useColorCodes) {
    boolean useColor = false;
    if (useColorCodes.length > 0) {
        useColor = useColorCodes[0];
    }
    String red = "\033[0;31m";
    String blue = "\033[0;34m";
    String reset = "\033[0m";
    java.util.Calendar calendar = new java.util.GregorianCalendar(year, month - 1, day + 1);
    calendar.set(java.util.Calendar.DAY_OF_MONTH, 1); //Set the day of month to 1
    int dayOfWeek = calendar.get(java.util.Calendar.DAY_OF_WEEK); //get day of week for 1st of month
    int daysInMonth = calendar.getActualMaximum(java.util.Calendar.DAY_OF_MONTH);

    //print month name and year
    System.out.println(new java.text.SimpleDateFormat("MMMM YYYY").format(calendar.getTime()));
    System.out.println((useColor?blue:"") + " S  M  T  W  T  F  S" + (useColor?reset:""));
    
    //print initial spaces
    String initialSpace = "";
    for (int i = 0; i < dayOfWeek - 1; i++) {
        initialSpace += "   ";
    }
    System.out.print(initialSpace);

    //print the days of the month starting from 1
    for (int i = 0, dayOfMonth = 1; dayOfMonth <= daysInMonth; i++) {
        for (int j = ((i == 0) ? dayOfWeek - 1 : 0); j < 7 && (dayOfMonth <= daysInMonth); j++) {
            if (dayOfMonth == day && useColor) {
                System.out.printf(red + "%2d " + reset, dayOfMonth);
            }
            else {
                System.out.printf("%2d ", dayOfMonth);
            }
            dayOfMonth++;
        }
        System.out.println();
    }
}

If your terminal supports escape color codes then the day you supplied would be red within the calendar. This method also takes care of leap years. Just provide the integer values for day, month, and year as arguments. The last parameter to apply color codes is optional.

If you want to display the month of August and you want the 20th of that month to be highlighted in red then you would make the following call:

displayConsoleCalendar(20, 8, 2021, true);

The console window may display something like this:

enter image description here

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
  • Hi I tried it but I have a hard time understanding the part of boolean UseColor=false. What is the purpose for that part? and the value that was initialize to the red, blue, and reset. I'm sorry for the questions – user16376117 Jul 04 '21 at 10:22
  • 1
    I recommend you don’t use `java.util.Calendar`. That class is poorly designed and long outdated. Instead use `LocalDate` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). See the answer by deHaar. – Ole V.V. Jul 04 '21 at 17:32
1

To come up with this solution (linear time complexity):

  1. run a for loop with i from 0 to 34
  2. print a new line only when i != 0 && i % 7 == 0
  3. use i % 31 + 1 on the current number i to keep it within bounds
public static void main(String[] args) {
    System.out.println("\t\tMONTH OF AUGUST 2021");
    System.out.println("–––––––––––––––-------------------------––––––––––––––");
    System.out.println("\nSun\tMon\tTue\tWed\tThu\tFri\tSat\n");
    System.out.println("–––––––––––––––-------------------------––––––––––––––");

    for(int i = 0; i < 35; i++) {
        if(i!= 0 && i % 7 == 0)
            System.out.println("\n");
        System.out.print(i % 31 + 1 + "\t");
    }

}

There is a complex and shorter version for this (for curious people)

while(i < 35)
    System.out.print(
        ((i != 0 && i % 7 == 0) ? "\n": "")
        + (i++ % 31 + 1)
        + "\t"
    );
Lovesh Dongre
  • 1,294
  • 8
  • 23
  • Wow, I knew it there is a more simple way of doing it but I want to ask why we need to make I from 0 to 34? I'm having a hard time with the logic aspect – user16376117 Jul 04 '21 at 10:23
  • 1
    I need to print nos from 1 to 31 and then again from 1 to 4, so instead of just using a for loop from 0 to 30 (to just print 1 to 31) I used a for loop from 0 to 34 and print the remaining 1 to 4 nos at the end of the calendar indicating the next month. Now how on using i = 31, 32, 33, 34 prints 1, 2, 3, 4 respectively. Simply calculate i % 31 + 1 for each and you will get 1, 2, 3, 4 respectively. – Lovesh Dongre Jul 04 '21 at 10:46
  • Thank you so much for the explanation now I understand. Thank you to you sir! – user16376117 Jul 04 '21 at 11:55
  • If your question is answered you can accept this solution. – Lovesh Dongre Jul 04 '21 at 12:58
  • Hi I want to ask if why is there no bracket after the if statement? – user16376117 Jul 04 '21 at 19:19
  • we can omit brackets if the body of the if condition contains only a single statement, if more than one statement consists of the body then brackets are mandatory. Similarly one can omit brackets for any other construct even for `for` loops if it contains only one statement inside it. – Lovesh Dongre Jul 05 '21 at 20:10
1

Here's an alternative that isn't actually more elegant or efficient, but uses a different approach (different library), and it supports different languages:

public static void printCalendarFor(int month, int year, Locale locale) {
    // build the given month of the given year
    YearMonth yearMonth = YearMonth.of(year, month);
    // extract its name in the given locale
    String monthName = yearMonth.getMonth().getDisplayName(TextStyle.FULL, locale);
    // create a builder for the calendar
    StringBuilder calendarBuilder = new StringBuilder();
    // and append a header with the month name and the year
    calendarBuilder.append("\t\t    ").append(monthName).append(" ").append(year).append(System.lineSeparator());
    // then append a second header with all the days of week
    calendarBuilder.append(DayOfWeek.MONDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.TUESDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.WEDNESDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.THURSDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.FRIDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.SATURDAY.getDisplayName(TextStyle.SHORT, locale)).append("\t")
                    .append(DayOfWeek.SUNDAY.getDisplayName(TextStyle.SHORT, locale)).append(System.lineSeparator());
    // get the first day of the given month
    LocalDate dayOfMonth = yearMonth.atDay(1);
    
    // and go through all the days of the month handling each day
    while (!dayOfMonth.isAfter(yearMonth.atEndOfMonth())) {
        // in order to fill up the weekday table's first line, specially handle the first
        if (dayOfMonth.getDayOfMonth() == 1) {
            switch (dayOfMonth.getDayOfWeek()) {
            case MONDAY:
                calendarBuilder.append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case TUESDAY:
                calendarBuilder.append("\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case WEDNESDAY:
                calendarBuilder.append("\t\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case THURSDAY:
                calendarBuilder.append("\t\t\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case FRIDAY:
                calendarBuilder.append("\t\t\t\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case SATURDAY:
                calendarBuilder.append("\t\t\t\t\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append("\t");
                break;
            case SUNDAY:
                calendarBuilder.append("\t\t\t\t\t\t")
                                .append(String.format("%3d", dayOfMonth.getDayOfMonth()))
                                .append(System.lineSeparator());
                break;
            }
        } else {
            // for all other days, just append their numbers
            calendarBuilder.append(String.format("%3d", dayOfMonth.getDayOfMonth()));
            // end the line on Sunday, otherwise append a tabulator
            if (dayOfMonth.getDayOfWeek() == DayOfWeek.SUNDAY) {
                calendarBuilder.append(System.lineSeparator());
            } else {
                calendarBuilder.append("\t");
            }
        }
        // finally increment the day of month
        dayOfMonth = dayOfMonth.plusDays(1);
    }
    // print the calender
    System.out.println(calendarBuilder.toString());
}

Here's some example use

public static void main(String[] args) {
    printCalendarFor(8, 2021, Locale.ENGLISH);
}

The output of that example use is

            August 2021
Mon Tue Wed Thu Fri Sat Sun
                          1
  2   3   4   5   6   7   8
  9  10  11  12  13  14  15
 16  17  18  19  20  21  22
 23  24  25  26  27  28  29
 30  31
deHaar
  • 17,687
  • 10
  • 38
  • 51