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:
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.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics