155 lines
4.3 KiB
JavaScript
155 lines
4.3 KiB
JavaScript
// @flow
|
|
export const SECONDS_PER_SECOND = 1.0;
|
|
export const SECONDS_PER_MINUTE = 60;
|
|
export const SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
|
|
export const SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;
|
|
|
|
const designations = [
|
|
['D', SECONDS_PER_DAY],
|
|
['H', SECONDS_PER_HOUR],
|
|
['M', SECONDS_PER_MINUTE],
|
|
['S', SECONDS_PER_SECOND],
|
|
];
|
|
|
|
/**
|
|
* Converts a Number to a String of HH:MM:SS
|
|
*
|
|
* @param {Number} totalSeconds
|
|
* @return {string}
|
|
*/
|
|
export function getSecondsAsHHMMSS(totalSeconds: Number) {
|
|
// SCORM spec does not deal with negative durations, give zero back
|
|
if (!totalSeconds || totalSeconds <= 0) {
|
|
return '00:00:00';
|
|
}
|
|
|
|
const hours = Math.floor(totalSeconds / SECONDS_PER_HOUR);
|
|
|
|
const dateObj = new Date(totalSeconds * 1000);
|
|
const minutes = dateObj.getUTCMinutes();
|
|
// make sure we add any possible decimal value
|
|
const seconds = dateObj.getSeconds() + (totalSeconds % 1.0);
|
|
|
|
return hours.toString().padStart(2, '0') + ':' +
|
|
minutes.toString().padStart(2, '0') + ':' +
|
|
seconds.toString().padStart(2, '0');
|
|
}
|
|
|
|
/**
|
|
* Calculate the number of seconds from ISO 8601 Duration
|
|
*
|
|
* @param {Number} seconds
|
|
* @return {String}
|
|
*/
|
|
export function getSecondsAsISODuration(seconds: Number) {
|
|
// SCORM spec does not deal with negative durations, give zero back
|
|
if (!seconds || seconds <= 0) {
|
|
return 'P0S';
|
|
}
|
|
|
|
let duration = 'P';
|
|
let remainder = seconds;
|
|
|
|
designations.forEach(([sign, current_seconds]) => {
|
|
let value = Math.floor(remainder / current_seconds);
|
|
|
|
remainder = remainder % current_seconds;
|
|
// If we have anything left in the remainder, and we're currently adding
|
|
// seconds to the duration, go ahead and add the decimal to the seconds
|
|
if (sign === 'S' && remainder > 0) {
|
|
value += remainder;
|
|
}
|
|
|
|
if (value) {
|
|
duration += `${value}${sign}`;
|
|
}
|
|
});
|
|
|
|
return duration;
|
|
}
|
|
|
|
/**
|
|
* Calculate the number of seconds from HH:MM:SS.DDDDDD
|
|
*
|
|
* @param {string} timeString
|
|
* @param {RegExp} timeRegex
|
|
* @return {number}
|
|
*/
|
|
export function getTimeAsSeconds(timeString: String, timeRegex: RegExp) {
|
|
if (!timeString || typeof timeString !== 'string' ||
|
|
!timeString.match(timeRegex)) {
|
|
return 0;
|
|
}
|
|
const parts = timeString.split(':');
|
|
const hours = Number(parts[0]);
|
|
const minutes = Number(parts[1]);
|
|
const seconds = Number(parts[2]);
|
|
return (hours * 3600) + (minutes * 60) + seconds;
|
|
}
|
|
|
|
/**
|
|
* Calculate the number of seconds from ISO 8601 Duration
|
|
*
|
|
* @param {string} duration
|
|
* @param {RegExp} durationRegex
|
|
* @return {number}
|
|
*/
|
|
export function getDurationAsSeconds(duration: String, durationRegex: RegExp) {
|
|
if (!duration || !duration.match(durationRegex)) {
|
|
return 0;
|
|
}
|
|
|
|
const [, years, months, , days, hours, minutes, seconds] = new RegExp(
|
|
durationRegex).exec(duration) || [];
|
|
|
|
const now = new Date();
|
|
const anchor = new Date(now);
|
|
anchor.setFullYear(anchor.getFullYear() + Number(years || 0));
|
|
anchor.setMonth(anchor.getMonth() + Number(months || 0));
|
|
anchor.setDate(anchor.getDate() + Number(days || 0));
|
|
anchor.setHours(anchor.getHours() + Number(hours || 0));
|
|
anchor.setMinutes(anchor.getMinutes() + Number(minutes || 0));
|
|
anchor.setSeconds(anchor.getSeconds() + Number(seconds || 0));
|
|
if (seconds && String(seconds).indexOf('.') > 0) {
|
|
const milliseconds = Number(Number(seconds) % 1).toFixed(6) * 1000.0;
|
|
anchor.setMilliseconds(anchor.getMilliseconds() + milliseconds);
|
|
}
|
|
|
|
return ((anchor * 1.0) - now) / 1000.0;
|
|
}
|
|
|
|
/**
|
|
* Adds together two ISO8601 Duration strings
|
|
*
|
|
* @param {string} first
|
|
* @param {string} second
|
|
* @param {RegExp} durationRegex
|
|
* @return {string}
|
|
*/
|
|
export function addTwoDurations(
|
|
first: String,
|
|
second: String,
|
|
durationRegex: RegExp) {
|
|
const firstSeconds = getDurationAsSeconds(first, durationRegex);
|
|
const secondSeconds = getDurationAsSeconds(second, durationRegex);
|
|
|
|
return getSecondsAsISODuration(firstSeconds + secondSeconds);
|
|
}
|
|
|
|
/**
|
|
* Add together two HH:MM:SS.DD strings
|
|
*
|
|
* @param {string} first
|
|
* @param {string} second
|
|
* @param {RegExp} timeRegex
|
|
* @return {string}
|
|
*/
|
|
export function addHHMMSSTimeStrings(
|
|
first: String,
|
|
second: String,
|
|
timeRegex: RegExp) {
|
|
const firstSeconds = getTimeAsSeconds(first, timeRegex);
|
|
const secondSeconds = getTimeAsSeconds(second, timeRegex);
|
|
return getSecondsAsHHMMSS(firstSeconds + secondSeconds);
|
|
}
|