From 81528274a45db9b3873c2ca01fd558ed8bf9c6da Mon Sep 17 00:00:00 2001 From: Jonathan Putney Date: Wed, 22 Jan 2020 13:38:22 -0500 Subject: [PATCH] Properly handling ISO 8601 durations that have milliseconds --- src/utilities.js | 10 +++++++--- test/utilities.spec.js | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/utilities.js b/src/utilities.js index 3c5b7bc..01b5d25 100644 --- a/src/utilities.js +++ b/src/utilities.js @@ -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; } diff --git a/test/utilities.spec.js b/test/utilities.spec.js index bd797f2..440a508 100644 --- a/test/utilities.spec.js +++ b/test/utilities.spec.js @@ -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),