user16376117
user16376117

Reputation: 31

An effective way of making a dedicated calendar for a month in java programming

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");
        }
    }
}

Upvotes: 1

Views: 423

Answers (3)

deHaar
deHaar

Reputation: 18578

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

Upvotes: 1

Lovesh Dongre
Lovesh Dongre

Reputation: 1344

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"
    );

Upvotes: 1

DevilsHnd - 退した
DevilsHnd - 退した

Reputation: 9192

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

Upvotes: 1

Related Questions