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:
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.
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://w3resource.com/javascript-exercises/javascript-date-exercise-56.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics