import { normalizeObjectUnits } from '../units/aliases';
import { getLocale } from '../locale/locales';
import isDurationValid from './valid.js';
+import multiply from '../utils/float-calculate';
export function Duration(duration) {
var normalizedInput = normalizeObjectUnits(duration),
// representation for dateAddRemove
this._milliseconds =
+milliseconds +
- seconds * 1e3 + // 1000
- minutes * 6e4 + // 1000 * 60
- hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
+ multiply(seconds, 1e3) + // 1000
+ multiply(minutes, 6e4) + // 1000 * 60
+ multiply(hours, 36e5); //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
this._days = +days + weeks * 7;
--- /dev/null
+export default function multiply(a, b) {
+ var bi1 = toBigInt(parseFloat(a)),
+ bi2 = toBigInt(parseFloat(b)),
+ mag1 = bi1.magnification,
+ mag2 = bi2.magnification,
+ num1 = bi1.num,
+ num2 = bi2.num;
+ return (num1 * num2) / (mag1 * mag2);
+}
+
+function toBigInt(floatNum) {
+ var bigInt = {
+ num: 0,
+ magnification: 1,
+ },
+ strNum,
+ len,
+ mag,
+ intNum;
+
+ if (Math.floor(floatNum) === floatNum) {
+ bigInt.num = floatNum;
+ return bigInt;
+ }
+
+ strNum = floatNum.toString();
+ len = strNum.length - strNum.indexOf('.') - 1;
+ mag = Math.pow(10, len);
+ intNum = Number(floatNum.toString().replace('.', ''));
+ bigInt.num = intNum;
+ bigInt.magnification = mag;
+ return bigInt;
+}
});
test('explicit cloning', function (assert) {
+ var duration = moment.duration(1.1234, 'hours');
+ assert.equal(duration.milliseconds(), 240,
+ 'Float number calculation will not lose accuracy'
+ );
+});
+
+test('float number calculation', function (assert) {
var durationA = moment.duration(5, 'milliseconds'),
durationB = durationA.clone();
durationA.add(5, 'milliseconds');