w3resource

JavaScript: Create and print a calendar

JavaScript Datetime: Exercise-56 with Solution

Display Month Calendar

Write a JavaScript program that accepts a month in the format mm/yyyy and display the month’s calendar.

It uses an epoch of 1/1/1900, Monday

Test Data: ('1/2019') ->

"M   T   W   Th  F   S   Su"
"    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  "
(‘2/1990’) ->
"M   T   W   Th  F   S   Su"
"        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  "

Sample Solution:

JavaScript Code:

/*
*  Print out the month's calendar.
*  License:shorturl.at/mJOR8
*/
// Class to represent a month
class Month {
  constructor () {
    // Array of days in a week
    this.Days = ['M', 'T', 'W', 'Th', 'F', 'S', 'Su']
    // Array of days in a week starting from Sunday
    this.BDays = ['M', 'Su', 'S', 'F', 'Th', 'W', 'T']
    // Epoch for reference
    this.epoch = { month: 1, year: 1900 }
    // Number of days in each month for a non-leap year
    this.monthDays = [31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    // Number of days in each month for a leap year
    this.monthDaysLeap = [31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  }
  // Method to print the calendar of the month
  printCal (days, startDay, output = value => console.log(value)) {
    // Output the days of the week
    output('M   T   W   Th  F   S   Su')
    const dates = []; let i
    // Populate dates array with day numbers
    for (i = 1; i <= days; i++) {
      dates.push(i)
    }
    // Push empty spaces to align days correctly
    for (i = 0; i < this.Days.indexOf(startDay); i++) {
      dates.unshift(' ')
    }
    // Iterate through dates array and output each row of the calendar
    while (true) {
      let row = ''
      for (i = 0; (i < 7) && (dates.length !== 0); i++) {
        row += dates.shift()
        while ((row.length % 4) !== 0) {
          row += ' '
        }
      }
      output(row)
      if (dates.length === 0) break
    }
  }
  // Method to parse date string into object
  parseDate (date) {
    const dateAr = []; let block = ''; let i
    for (i = 0; i < date.length; i++) {
      if (date[i] === '/') {
        dateAr.push(parseInt(block))
        block = ''
        continue
      }
      block += date[i]
    }
    dateAr.push(parseInt(block))
    if (dateAr.length !== 2) throw new Error('Improper string encoding')
    const dateOb = { month: dateAr[0], year: dateAr[1] }
    return dateOb
  }
  // Method to check if a year is a leap year
  isLeapYear (year) {
    if (((year % 400) === 0) || (((year % 100) !== 0) && ((year % 4) === 0))) return true
    return false
  }
  // Method to compare two dates
  isGreater (startDate, endDate) {
    if (startDate.year > endDate.year) {
      return true
    } else if (startDate.year < endDate.year) {
      return false
    } else if (startDate.month > endDate.month) {
      return true
    } else if (startDate.month < endDate.month) {
      return false
    }
    return true
  }
  // Method to get the difference in days between two dates
  getDayDiff (startDate, endDate) {
    if (this.isGreater(startDate, endDate) === null) {
      return 0
    } else if ((this.isGreater(startDate, endDate) === true)) {
      const midDate = startDate
      startDate = endDate
      endDate = midDate
    }
    let diff = 0
    while (startDate.year !== endDate.year) {
      diff += (this.isLeapYear(startDate.year)) ? 366 : 365
      startDate.year = startDate.year + 1
    }
    while (startDate.month !== endDate.month) {
      if (startDate.month < endDate.month) {
        if (this.isLeapYear(startDate.year)) diff += this.monthDaysLeap[startDate.month]
        else diff += this.monthDays[startDate.month]
        startDate.month = startDate.month + 1
      } else {
        if (this.isLeapYear(startDate.year)) diff -= this.monthDaysLeap[startDate.month - 1]
        else diff -= this.monthDays[startDate.month - 1]
        startDate.month = startDate.month - 1
      }
    }
    return diff
  }
  // Method to generate the calendar for a given month
    generateMonthCal (date) {
    const Month = this.parseDate(date); let day = ''
    let difference = this.getDayDiff(this.epoch, Month)
    difference = difference % 7
    let Month2 = this.parseDate(date)
    day = (this.isGreater(Month2, this.epoch)) ? this.Days[difference] : this.BDays[difference]
    Month2 = this.parseDate(date)
    if (this.isLeapYear(Month2.year)) this.printCal(this.monthDaysLeap[Month2.month], day)
    else this.printCal(this.monthDays[Month2.month], day)
  }
}
const x = new Month()
x.generateMonthCal('1/2019')
x.generateMonthCal('2/1990')

Output:

M   T   W   Th  F   S   Su
    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  
M   T   W   Th  F   S   Su
        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  

Explanation:

In the exercise above,

  • Class Initialization: The "Month" class is initialized with properties and methods for calendar generation.
  • Print Calendar Method: The "printCal()" method prints the calendar for the specified month.
  • Parse Date Method: The "parseDate()" method parses a date string into an object containing the month and year.
  • Leap Year Check: The "isLeapYear()" method checks if a given year is a leap year.
  • Date Comparison: The "isGreater()" method compares two dates to determine if one is greater than the other.
  • Day Difference Calculation: The "getDayDiff()" method calculates the difference in days between two dates.
  • Generate Month Calendar: The "generateMonthCal()" method generates and prints the calendar for a specific month based on the provided date string.
  • Instantiation and Usage: Finally, an instance of the "Month" class is created, and the "generateMonthCal()" method is called twice to print calendars for different months.

Flowchart:

Flowchart: JavaScript- Create and print a calendar
Flowchart: JavaScript- Create and print a calendar
Flowchart: JavaScript- Create and print a calendar

Live Demo:

See the Pen javascript-date-exercise-56 by w3resource (@w3resource) on CodePen.


Improve this sample solution and post your code through Disqus.

Previous: Check if a given date is weekday, weekend.
Next: Identify a day based on a date.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Become a Patron!

Follow us on Facebook and Twitter for latest update.

It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.

https://www.w3resource.com/javascript-exercises/javascript-date-exercise-56.php