scratch-www/src/lib/format-time.js

51 lines
2.1 KiB
JavaScript
Raw Normal View History

// IMPORTANT: any changes to the time algorithm also need to be made in the corresponding
// scratchr2 file 'lib/format-time.js'
/**
Given a timestamp in the future, calculate the largest, closest unit to show.
2020-11-30 16:16:52 -05:00
On the high end we stop at hours. e.g. 15 days is still counted in hours not days or weeks.
On the low end we stop at minutes.
2020-11-30 16:16:52 -05:00
This rounds duration to the nearest integer. e.g. 5.7 minutes => will return 6 as duration.
@param {number} timeStamp A future time stamp in ms.
2020-11-30 16:16:52 -05:00
@returns {object} containing the unit (min, hours) and how many. e.g. {unit: minutes, duration: 3}
*/
2020-11-30 16:16:52 -05:00
const getTimeUnitAndDuration = timeStamp => {
const diff = timeStamp - Date.now();
const oneHourInMs = 1000 * 60 * 60;
const oneMinuteInMs = 1000 * 60;
2020-11-30 16:16:52 -05:00
let unit = 'minute';
let duration = diff / oneMinuteInMs;
2020-11-30 16:16:52 -05:00
// We show minutes up to 2 hours, then switch to hours.
if (diff >= 2 * oneHourInMs) {
unit = 'hour';
duration = diff / oneHourInMs;
}
// Round to nearest hour or minute, but always have at least 1
// so we don't show something like "0 minutes". Hours isn't
// affected by the math.max because we choose minutes up to 2 hours.
duration = Math.max(1, Math.round(duration));
return {
unit: unit,
duration: duration
};
};
/**
* Given a future timestamp and a langauge, constructs a phrase to describe that time relative to now.
2020-11-30 16:16:52 -05:00
* e.g. in 2 days, in 3 minutes, en 2 horas.
* The largest time unit is days, the smallest is minutes.
* @param {number} futureTime a timestamp in ms to build a phrase for.
* @param {string} lang Langauge to build the phrase in.
* @returns {string} A phrase representing the relative time in the future. e.g. 3 days 5 hours.
*/
2020-11-30 16:16:52 -05:00
module.exports.formatRelativeTime = (futureTime, lang) => {
const formatter = new Intl.RelativeTimeFormat([lang].concat(window.navigator.languages), {
localeMatcher: 'best fit',
numeric: 'always',
style: 'long'
});
2020-11-30 16:16:52 -05:00
const timeInfo = getTimeUnitAndDuration(futureTime);
return formatter.format(timeInfo.duration, timeInfo.unit);
};