How to resolve the algorithm Calendar step by step in the JavaScript programming language
How to resolve the algorithm Calendar step by step in the JavaScript programming language
Table of Contents
Problem Statement
Create a routine that will generate a text calendar for any year.
Test the calendar by generating a calendar for the year 1969, on a device of the time.
Choose one of the following devices:
(Ideally, the program will generate well-formatted calendars for any page width from 20 characters up.) Kudos (κῦδος) for routines that also transition from Julian to Gregorian calendar. This task is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983. For further Kudos see task CALENDAR, where all code is to be in UPPERCASE. For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Calendar step by step in the JavaScript programming language
This code snippet provides a JavaScript function that generates a neatly formatted calendar for a given year, locale, number of columns, and column spacing. Here's a breakdown of its functionality:
-
Function
printCenter(width)
: This function takes the desired width as input and returns a new function. The returned function, when invoked with a string, pads the string evenly on both sides to achieve the specified width, using spaces for padding. -
Function
localeName(locale, options)
: Given a locale string and formatting options, this function returns a new function. The returned function takes a date object as input and formats it based on the provided locale and options. -
Function
addDay(date, inc)
: This function increments the provided date by the specified number of days (defaults to 1) and returns the modified date. -
Function
makeWeek(date)
: This function takes a date object as input and generates a string representing the week, including day numbers, for the week containing the input date. It also returns the modified date and a flag indicating whether the month has changed since the input date. -
Function
cal(year, locale, cols, coll_space)
: This is the main function that generates and prints the calendar. It takes several parameters:year
: The year for which the calendar is to be generated.locale
(optional): The locale string; defaults to 'en-US'.cols
(optional): The number of columns in which the calendar months are arranged; defaults to 3.coll_space
(optional): The number of spaces between columns; defaults to 5.
Implementation Details:
- Month Table Heading and Columns: The function starts by setting up the heading and columns for the month table.
- Week Accumulation: It then enters a loop that accumulates lines representing the weeks in the year. Within this loop, a further function,
makeWeek
, is used to generate the week lines. - Printing the Calendar: Finally, the accumulated lines are printed to form the calendar. The output is formatted and centered using the
pageCenter
function.
Sample Usage:
At the end of the code, the cal
function is called with the following parameters:
1969
: The year for the calendar.'en-US'
: The locale string (optional; defaults to 'en-US').3
: The number of columns (optional; defaults to 3).5
: The spacing between columns (optional; defaults to 5).
This will print a nicely formatted calendar for the year 1969, arranged in a 3-column layout with 5 spaces between each column.
Source code in the javascript programming language
/**
* Given a width, return a function that takes a string, and
* pads it at both ends to the given width
* @param {number} width
* @returns {function(string): string}
*/
const printCenter = width =>
s => s.padStart(width / 2 + s.length / 2, ' ').padEnd(width);
/**
* Given an locale string and options, return a function that takes a date
* object, and retrurns the date formatted to the locale and options.
* @param {string} locale
* @param {DateTimeFormatOptions} options
* @returns {function(Date): string}
*/
const localeName = (locale, options) => {
const formatter = new Intl.DateTimeFormat(locale, options);
return date => formatter.format(date);
};
/**
* Increment the date by number.
* @param {Date} date
* @param {number} inc
* @returns {Date}
*/
const addDay = (date, inc = 1) => {
const res = new Date(date.valueOf());
res.setDate(date.getDate() + inc);
return res;
}
/**
* Given a date, build a string of the week, and return it along with
* the mutated date object.
* @param {Date} date
* @returns {[boolean, Date, string]}
*/
const makeWeek = date => {
const month = date.getMonth();
let [wdi, md, m] = [date.getUTCDay(), date.getDate(), date.getMonth()];
const line = Array(7).fill(' ').map((e, i) => {
if (i === wdi && m === month) {
const result = (md + '').padStart(2, ' ');
date = addDay(date);
[wdi, md, m] = [date.getUTCDay(), date.getDate(), date.getMonth()];
return result;
} else {
return e;
}
}).join(' ');
return [month !== m, date, line];
}
/**
* Print a nicely formatted calender for the given year in the given locale.
* @param {number} year The required year of the calender
* @param {string} locale The locale string. Defaults to US English.
* @param {number} cols The number of columns for the months. Defaults to 3.
* @param {number} coll_space The space between the columns. Defaults to 5.
*/
const cal = (year, locale = 'en-US', cols = 3, coll_space = 5) => {
const MONTH_LINES = 9; // Number of lines that make up a month.
const MONTH_COL_WIDTH = 20; // Character width of a month
const COL_SPACE = ' '.padStart(coll_space);
const FULL_WIDTH = MONTH_COL_WIDTH * cols + coll_space * (cols - 1);
const collArr = Array(cols).fill('');
const monthName = localeName(locale, {month: 'long'});
const weekDayShort = localeName(locale, {weekday: 'short'});
const monthCenter = printCenter(MONTH_COL_WIDTH);
const pageCenter = printCenter(FULL_WIDTH);
// Get the weekday in the given locale.
const sun = new Date(Date.UTC(2017, 0, 1)); // A sunday
const weekdays = Array(7).fill('').map((e, i) =>
weekDayShort(addDay(sun, i)).padStart(2, ' ').substring(0, 2)).join(' ');
// The start date.
let date = new Date(Date.UTC(year, 0, 1, 0, 0, 0));
let nextMonth = true;
let line = '';
const fullYear = date.getUTCFullYear();
// The array into which each of the lines are populated.
const accumulate = [];
// Populate the month table heading and columns.
const preAmble = date => {
accumulate.push(monthCenter(' '))
accumulate.push(monthCenter(monthName(date)));
accumulate.push(weekdays);
};
// Accumulate the week lines for the year.
while (date.getUTCFullYear() === fullYear) {
if (nextMonth) {
if (accumulate.length % MONTH_LINES !== 0) {
accumulate.push(monthCenter(' '))
}
preAmble(date);
}
[nextMonth, date, line] = makeWeek(date);
accumulate.push(line);
}
// Print the calendar.
console.log(pageCenter(String.fromCodePoint(0x1F436)));
console.log(pageCenter(`--- ${fullYear} ---`));
accumulate.reduce((p, e, i) => {
if (!p.includes(i)) {
const indexes = collArr.map((e, ci) => i + ci * MONTH_LINES);
console.log(indexes.map(e => accumulate[e]).join(COL_SPACE));
p.push(...indexes);
}
return p;
}, []);
};
cal(1969, 'en-US', 3);
You may also check:How to resolve the algorithm Jensen's Device step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Population count step by step in the Ol programming language
You may also check:How to resolve the algorithm Check input device is a terminal step by step in the Wren programming language
You may also check:How to resolve the algorithm Smarandache prime-digital sequence step by step in the Raku programming language
You may also check:How to resolve the algorithm Harshad or Niven series step by step in the Eiffel programming language