Skip to content

Instantly share code, notes, and snippets.

@jake-armour
Last active March 6, 2022 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jake-armour/432642b766dab65384475343a238aa9f to your computer and use it in GitHub Desktop.
Save jake-armour/432642b766dab65384475343a238aa9f to your computer and use it in GitHub Desktop.
Code challenge for Chiliz
/*
* 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