diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js index 2e1129a0..653b3de3 100644 --- a/95_Weekday/javascript/weekday.js +++ b/95_Weekday/javascript/weekday.js @@ -36,9 +36,9 @@ function tab(space) { } class DateStruct { - year; - month; - day; + #year; + #month; + #day; /** * Build a DateStruct @@ -47,9 +47,25 @@ class DateStruct { * @param {number} day */ constructor(year, month, day) { - this.year = year; - this.month = month; - this.day = day; + this.#year = year; + this.#month = month; + this.#day = day; + } + + get year() { + return this.#year; + } + + get month() { + return this.#month; + } + + get day() { + return this.#day; + } + + clone = () => { + return new DateStruct(this.#year, this.#month, this.#day) } /** @@ -58,14 +74,14 @@ class DateStruct { * see https://en.wikipedia.org/wiki/Gregorian_calendar * @returns {boolean} true if date could be Gregorian; otherwise false. */ - isGregorianDate() { + isGregorianDate = function () { let result = false; - if (this.year > 1582) { + if (this.#year > 1582) { result = true; - } else if (this.year === 1582) { - if (this.month > 10) { + } else if (this.#year === 1582) { + if (this.#month > 10) { result = true; - } else if (this.month === 10 && this.day >= 15) { + } else if (this.#month === 10 && this.#day >= 15) { result = true; } } @@ -76,15 +92,15 @@ class DateStruct { * Returns a US formatted date, i.e. Month/Day/Year. * @returns {string} */ - getFormattedDate() { - return this.month + "/" + this.day + "/" + this.year; + toString = function () { + return this.#month + "/" + this.#day + "/" + this.#year; } } class Duration { - years; - months; - days; + #years; + #months; + #days; /** * Build a Duration @@ -93,9 +109,70 @@ class Duration { * @param {number} days */ constructor(years, months, days) { - this.years = years; - this.months = months; - this.days = days; + this.#years = years; + this.#months = months; + this.#days = days; + } + + get years() { + return this.#years; + } + + get months() { + return this.#months; + } + + get days() { + return this.#days; + } + + clone = () => { + return new Duration(this.#years, this.#months, this.#days) + } + + /** + * Adjust Duration by removing years, months and days from supplied Duration. + * This is a naive calculation which assumes all months are 30 days. + * @param {Duration} timeToRemove + */ + remove = (timeToRemove) => { + this.#years -= timeToRemove.years; + this.#months -= timeToRemove.months; + this.#days -= timeToRemove.days; + if (this.#days < 0) { + this.#days += 30; + this.#months--; + } + if (this.#months < 0) { + this.#months += 12; + this.#years--; + } + } + + toString = () => { + return this.#years + "/" + this.#months + "/" + this.#days; + } + + /** + * Determine approximate Duration between two dates. + * This is a naive calculation which assumes all months are 30 days. + * @param {DateStruct} date1 + * @param {DateStruct} date2 + * @returns {Duration} + */ + static between(date1, date2) { + let years = date1.year - date2.year; + let months = date1.month - date2.month; + let days = date1.day - date2.day; + if (days < 0) { + months--; + days += 30; + } + if (months < 0) { + years--; + months += 12; + } + return new Duration(years, months, days); } } @@ -140,25 +217,6 @@ function printTimeSpent(duration) { print(duration.years + "\t" + duration.months + "\t" + duration.days + "\n"); } -/** - * Adjust unaccounted time by remove years, months and days supplied. - * @param {Duration} unaccountedTime - * @param {Duration} timeToRemove - */ -function adjustUnaccountedTime(unaccountedTime, timeToRemove) { - unaccountedTime.years -= timeToRemove.years; - unaccountedTime.months -= timeToRemove.months; - unaccountedTime.days -= timeToRemove.days; - if (unaccountedTime.days < 0) { - unaccountedTime.days += 30; - unaccountedTime.months--; - } - if (unaccountedTime.months <= 0) { - unaccountedTime.months += 12; - unaccountedTime.years--; - } -} - /** * Determine if the given year is a leap year. * @param year @@ -193,7 +251,7 @@ function getDayOfWeek(date) { const yearInCenturyOffsets = yearInCentury / 4 + yearInCentury; // combine offsets with day and month - let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month-1]; + let dayOfWeek = centuryOffset + yearInCenturyOffsets + date.day + COMMON_YEAR_MONTH_OFFSET[date.month - 1]; dayOfWeek = Math.floor(dayOfWeek % 7) + 1; if (date.month <= 2 && isLeapYear(date.year)) { @@ -254,28 +312,6 @@ function getNormalisedDay(date) { return (date.year * 12 + date.month) * 31 + date.day; } -/** - * Determine approximate difference between two dates. - * This is a naive calculation which assumes all months are 30 days. - * @param {DateStruct} date1 - * @param {DateStruct} date2 - * @returns {Duration} - */ -function difference(date1, date2) { - let years = date1.year - date2.year; - let months = date1.month - date2.month; - let days = date1.day - date2.day; - if (days < 0) { - months--; - days += 30; - } - if (months < 0) { - years--; - months += 12; - } - return new Duration(years, months, days); -} - // Main control section async function main() { print(tab(32) + "WEEKDAY\n"); @@ -300,19 +336,18 @@ async function main() { const normalisedToday = getNormalisedDay(today); const normalisedDob = getNormalisedDay(dateOfBirth); - const dateOfBirthText = dateOfBirth.getFormattedDate(); let dayOfWeekText = getDayOfWeekText(dateOfBirth); if (normalisedToday < normalisedDob) { - print(dateOfBirthText + " WILL BE A " + dayOfWeekText + "\n"); + print(dateOfBirth + " WILL BE A " + dayOfWeekText + "\n"); } else if (normalisedToday === normalisedDob) { - print(dateOfBirthText + " IS A " + dayOfWeekText + "\n"); + print(dateOfBirth + " IS A " + dayOfWeekText + "\n"); } else { - print(dateOfBirthText + " WAS A " + dayOfWeekText + "\n"); + print(dateOfBirth + " WAS A " + dayOfWeekText + "\n"); } if (normalisedToday !== normalisedDob) { print("\n"); - let differenceBetweenDates = difference(today, dateOfBirth); + let differenceBetweenDates = Duration.between(today, dateOfBirth); if (differenceBetweenDates.years >= 0) { if (differenceBetweenDates.days === 0 && differenceBetweenDates.months === 0) { print("***HAPPY BIRTHDAY***\n"); @@ -323,19 +358,19 @@ async function main() { printTimeSpent(differenceBetweenDates); const approximateDaysBetween = (differenceBetweenDates.years * 365) + (differenceBetweenDates.months * 30) + differenceBetweenDates.days + Math.floor(differenceBetweenDates.months / 2); // Create an object containing time unaccounted for - const unaccountedTime = {...differenceBetweenDates}; + const unaccountedTime = differenceBetweenDates.clone(); // Calculate time spent in the following functions. print("YOU HAVE SLEPT \t\t\t"); const sleepTimeSpent = time_spent(0.35, approximateDaysBetween); printTimeSpent(sleepTimeSpent); - adjustUnaccountedTime(unaccountedTime, sleepTimeSpent); + unaccountedTime.remove(sleepTimeSpent); print("YOU HAVE EATEN \t\t\t"); const eatenTimeSpent = time_spent(0.17, approximateDaysBetween); printTimeSpent(eatenTimeSpent); - adjustUnaccountedTime(unaccountedTime, eatenTimeSpent); + unaccountedTime.remove(eatenTimeSpent); if (unaccountedTime.years <= 3) { print("YOU HAVE PLAYED \t\t\t"); } else if (unaccountedTime.years <= 9) { @@ -346,7 +381,7 @@ async function main() { const workPlayTimeSpent = time_spent(0.23, approximateDaysBetween); printTimeSpent(workPlayTimeSpent); - adjustUnaccountedTime(unaccountedTime, workPlayTimeSpent); + unaccountedTime.remove(workPlayTimeSpent); if (unaccountedTime.months === 12) { unaccountedTime.years++; unaccountedTime.months = 0;