w3resource

JavaScript: Create and print a calendar

JavaScript Datetime: Exercise-56 with Solution

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.



Follow us on Facebook and Twitter for latest update.