Last active
March 6, 2022 17:46
-
-
Save jake-armour/432642b766dab65384475343a238aa9f to your computer and use it in GitHub Desktop.
Code challenge for Chiliz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Your program must print string with the number of years and months and the total number of days between the dates. | |
* Dates are provided in dd.mm.yyyy format. | |
* You are not allowed to plug in JS libraries such as moment.js or date-fns directly into the code. All code need to be written in this file. | |
* | |
* Result must be shown as a string in years, months and total days. If years or months are 0, then it should not be displayed in the output. | |
* | |
* Example: | |
* Input: ['01.01.2000', '01.01.2016'] | |
* Output: | |
* '16 years, total 5844 days' | |
* | |
* Example 2: | |
* Input: ['01.11.2015', '01.02.2017'] | |
* | |
* Output: | |
* '1 year, 3 months, total 458 days' | |
*/ | |
const dates = [ | |
['01.01.2000', '01.01.2016'], | |
['01.01.2016', '01.08.2016'], | |
['01.11.2015', '01.02.2017'], | |
['17.12.2016', '16.01.2017'], | |
['01.01.2016', '01.01.2016'], | |
['28.02.2015', '13.04.2018'], | |
['28.01.2015', '28.02.2015'], | |
['17.03.2022', '17.03.2023'], | |
['17.02.2024', '17.02.2025'], | |
]; | |
const MILLISECONDS_IN_DAY = 86400000; | |
/** | |
* Recieves array of start and end date strings in 'dd.MM.yyyy' format. | |
* | |
* @param {String[]} dates | |
* @returns {String} | |
*/ | |
function outputDate(dates) { | |
// Split dates into start and end dates | |
const [start, end] = dates; | |
// Convert dates from strings into date objects | |
const startDate = fromDayMonthYear(start); | |
const endDate = fromDayMonthYear(end); | |
// Initialise string for output | |
let outputString = ''; | |
// Get difference in years from function below | |
const yearDiff = differenceInYears(startDate, endDate); | |
// If there is a difference in years, add this to the output string | |
if (yearDiff > 0) outputString += `${yearDiff} ${pluralise('year', yearDiff)}, `; | |
// Get difference in months from function below | |
const monthDiff = differenceInMonths(startDate, endDate); | |
// If there is a difference in months, add this to the output string | |
if (monthDiff > 0) outputString += `${monthDiff} ${pluralise('month', monthDiff)}, `; | |
// Work out days between the two dates using MS in days | |
const differenceInDays = Math.round((endDate.getTime() - startDate.getTime()) / MILLISECONDS_IN_DAY); | |
// Add days to end of output string | |
outputString += `total ${differenceInDays} days`; | |
// Return the final output string | |
return outputString; | |
} | |
/** | |
* Takes a string and pluralises it if value is larger than 1 | |
* | |
* @param {String} string | |
* @param {Number} value | |
* @returns {String} | |
*/ | |
function pluralise(string, value) { | |
if (value > 1) string += 's'; | |
return string; | |
} | |
/** | |
* Function to take a date string in 'dd.MM.yyyy' format | |
* and return a date object using that date | |
* | |
* @param {String} date | |
* @returns {Date} | |
*/ | |
function fromDayMonthYear(date) { | |
// Split out values from provided date string | |
let [day, month, year] = date.split('.'); | |
// Parse int values from returned string values | |
year = parseInt(year); | |
month = parseInt(month) - 1; | |
day = parseInt(day); | |
// Create new date object using those values | |
return new Date(year, month, day); | |
} | |
/** | |
* Gets a value for full months between two provided dates | |
* | |
* @param {Date} start | |
* @param {Date} end | |
* @returns {Number} | |
*/ | |
function differenceInMonths(start, end) { | |
// Clone dates so no original values are changed | |
const startDate = new Date(start); | |
const endDate = new Date(end); | |
// Work out absolute values for year and month differences | |
const diffInYears = endDate.getFullYear() - startDate.getFullYear(); | |
const diffInMonths = endDate.getMonth() - startDate.getMonth(); | |
// Get complete difference in months using years*12 | |
const difference = diffInYears * 12 + diffInMonths | |
// Set end dates month to the current month - difference in months | |
endDate.setMonth(endDate.getMonth() - difference); | |
// If end date is then before start date, the last month wasnt a full month | |
const lastMonthNotFull = isAfter(startDate, endDate) === -1; | |
// Subtract 1 if the last month isnt full from the total difference | |
const result = difference - lastMonthNotFull; | |
// Modulo difference over 12 to remove full years from the final value | |
return result % 12 | |
} | |
/** | |
* Gets a value for full years between two dates | |
* | |
* @param {Date} start | |
* @param {Date} end | |
* @returns {Number} | |
*/ | |
function differenceInYears(start, end) { | |
// Clone dates so no original values are changed | |
const startDate = new Date(start); | |
const endDate = new Date(end); | |
// Work out absolute value for year difference | |
const difference = endDate.getFullYear() - startDate.getFullYear(); | |
// Set end dates year to the current year - difference in months | |
endDate.setFullYear(endDate.getFullYear() - difference) | |
// If end date is then before start date, the last year wasnt a full year | |
const lastYearNotFull = isAfter(startDate, endDate) === -1 | |
// Subtract 1 if the last year isnt full from the total difference | |
const result = difference - lastYearNotFull | |
// Return result | |
return result | |
} | |
/** | |
* Function to check if endDate is after startDate | |
* | |
* @param {Date} start | |
* @param {Date} end | |
* @returns {Number} | |
*/ | |
function isAfter(start, end) { | |
// Subtract startDate ms from endDate | |
const msDiff = end.getTime() - start.getTime() | |
// Return value depending on difference | |
if (msDiff < 0) { | |
return -1 | |
} else if (msDiff > 0) { | |
return 1 | |
} else { | |
return msDiff | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment