Properly handling ISO 8601 durations that have milliseconds

This commit is contained in:
Jonathan Putney
2020-01-22 13:38:22 -05:00
parent 3c6e460d44
commit 81528274a4
2 changed files with 20 additions and 3 deletions

View File

@@ -63,6 +63,9 @@ export function getSecondsAsISODuration(seconds: Number) {
let value = Math.floor(remainder / current_seconds);
remainder = remainder % current_seconds;
if (countDecimals(remainder) > 2) {
remainder = Number(Number(remainder).toFixed(2));
}
// 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) {
@@ -124,7 +127,7 @@ export function getDurationAsSeconds(duration: String, durationRegex: RegExp) {
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) {
if (seconds && countDecimals(String(seconds)) > 0) {
const milliseconds = Number(Number(seconds) % 1).toFixed(6) * 1000.0;
anchor.setMilliseconds(anchor.getMilliseconds() + milliseconds);
}
@@ -237,6 +240,7 @@ export function unflatten(data) {
* @return {number}
*/
export function countDecimals(num: number) {
if (Math.floor(num) === num) return 0;
return num.toString().split('.')[1].length || 0;
if (Math.floor(num) === num || String(num).indexOf('.') < 0) return 0;
const parts = num.toString().split('.')[1];
return parts.length || 0;
}

View File

@@ -83,6 +83,12 @@ describe('Utility Tests', () => {
).to.equal('PT1M10S');
});
it('916.88 returns PT15M16.88S', () => {
expect(
Utilities.getSecondsAsISODuration(916.88),
).to.equal('PT15M16.88S');
});
it('3670 returns PT1H1M10S', () => {
expect(
Utilities.getSecondsAsISODuration(3670),
@@ -185,6 +191,13 @@ describe('Utility Tests', () => {
).to.equal(70);
});
it('PT15M16.88S returns 916.88', () => {
expect(
Utilities.getDurationAsSeconds('PT15M16.88S',
scorm2004_regex.CMITimespan),
).to.equal(916.88);
});
it('P1D returns 86400', () => {
expect(
Utilities.getDurationAsSeconds('P1D', scorm2004_regex.CMITimespan),