Comparing version
{ | ||
"name": "luxon", | ||
"version": "3.4.1", | ||
"version": "3.4.2", | ||
"description": "Immutable date wrapper", | ||
@@ -5,0 +5,0 @@ "author": "Isaac Cambron", |
@@ -13,3 +13,2 @@ import { InvalidArgumentError, InvalidDurationError, InvalidUnitError } from "./errors.js"; | ||
roundTo, | ||
signedFloor, | ||
} from "./impl/util.js"; | ||
@@ -131,23 +130,42 @@ import Settings from "./settings.js"; | ||
// this is needed since in some test cases it would return 0.9999999999999999 instead of 1 | ||
function removePrecisionIssue(a) { | ||
return Math.trunc(a * 1e3) / 1e3; | ||
function durationToMillis(matrix, vals) { | ||
let sum = vals.milliseconds ?? 0; | ||
for (const unit of reverseUnits.slice(1)) { | ||
if (vals[unit]) { | ||
sum += vals[unit] * matrix[unit]["milliseconds"]; | ||
} | ||
} | ||
return sum; | ||
} | ||
// NB: mutates parameters | ||
function convert(matrix, fromMap, fromUnit, toMap, toUnit) { | ||
const conv = matrix[toUnit][fromUnit]; | ||
const raw = fromMap[fromUnit] / conv; | ||
const added = signedFloor(raw); | ||
function normalizeValues(matrix, vals) { | ||
// the logic below assumes the overall value of the duration is positive | ||
// if this is not the case, factor is used to make it so | ||
const factor = durationToMillis(matrix, vals) < 0 ? -1 : 1; | ||
toMap[toUnit] = removePrecisionIssue(toMap[toUnit] + added); | ||
fromMap[fromUnit] = removePrecisionIssue(fromMap[fromUnit] - added * conv); | ||
} | ||
// NB: mutates parameters | ||
function normalizeValues(matrix, vals) { | ||
reverseUnits.reduce((previous, current) => { | ||
if (!isUndefined(vals[current])) { | ||
if (previous) { | ||
convert(matrix, vals, previous, vals, current); | ||
const previousVal = vals[previous] * factor; | ||
const conv = matrix[current][previous]; | ||
// if (previousVal < 0): | ||
// lower order unit is negative (e.g. { years: 2, days: -2 }) | ||
// normalize this by reducing the higher order unit by the appropriate amount | ||
// and increasing the lower order unit | ||
// this can never make the higher order unit negative, because this function only operates | ||
// on positive durations, so the amount of time represented by the lower order unit cannot | ||
// be larger than the higher order unit | ||
// else: | ||
// lower order unit is positive (e.g. { years: 2, days: 450 } or { years: -2, days: 450 }) | ||
// in this case we attempt to convert as much as possible from the lower order unit into | ||
// the higher order one | ||
// | ||
// Math.floor takes care of both of these cases, rounding away from 0 | ||
// if previousVal < 0 it makes the absolute value larger | ||
// if previousVal >= it makes the absolute value smaller | ||
const rollUp = Math.floor(previousVal / conv); | ||
vals[current] += rollUp * factor; | ||
vals[previous] -= rollUp * conv * factor; | ||
} | ||
@@ -586,9 +604,3 @@ return current; | ||
let sum = this.values.milliseconds ?? 0; | ||
for (let unit of reverseUnits.slice(1)) { | ||
if (this.values[unit]) { | ||
sum += this.values[unit] * this.matrix[unit]["milliseconds"]; | ||
} | ||
} | ||
return sum; | ||
return durationToMillis(this.matrix, this.values); | ||
} | ||
@@ -703,3 +715,10 @@ | ||
* Reduce this Duration to its canonical representation in its current units. | ||
* Assuming the overall value of the Duration is positive, this means: | ||
* - excessive values for lower-order units are converted to higher order units (if possible, see first and second example) | ||
* - negative lower-order units are converted to higher order units (there must be such a higher order unit, otherwise | ||
* the overall value would be negative, see second example) | ||
* | ||
* If the overall value is negative, the result of this method is equivalent to `this.negate().normalize().negate()`. | ||
* @example Duration.fromObject({ years: 2, days: 5000 }).normalize().toObject() //=> { years: 15, days: 255 } | ||
* @example Duration.fromObject({ days: 5000 }).normalize().toObject() //=> { days: 5000 } | ||
* @example Duration.fromObject({ hours: 12, minutes: -45 }).normalize().toObject() //=> { hours: 11, minutes: 15 } | ||
@@ -711,7 +730,4 @@ * @return {Duration} | ||
const vals = this.toObject(); | ||
if (this.valueOf() >= 0) { | ||
normalizeValues(this.matrix, vals); | ||
return clone(this, { values: vals }, true); | ||
} | ||
return this.negate().normalize().negate(); | ||
normalizeValues(this.matrix, vals); | ||
return clone(this, { values: vals }, true); | ||
} | ||
@@ -766,2 +782,4 @@ | ||
// only keep the integer part for now in the hopes of putting any decimal part | ||
// into a smaller unit later | ||
const i = Math.trunc(own); | ||
@@ -771,8 +789,2 @@ built[k] = i; | ||
// plus anything further down the chain that should be rolled up in to this | ||
for (const down in vals) { | ||
if (orderedUnits.indexOf(down) > orderedUnits.indexOf(k)) { | ||
convert(this.matrix, vals, down, built, k); | ||
} | ||
} | ||
// otherwise, keep it in the wings to boil it later | ||
@@ -793,3 +805,4 @@ } else if (isNumber(vals[k])) { | ||
return clone(this, { values: built }, true).normalize(); | ||
normalizeValues(this.matrix, built); | ||
return clone(this, { values: built }, true); | ||
} | ||
@@ -796,0 +809,0 @@ |
@@ -127,6 +127,2 @@ /* | ||
export function signedFloor(number) { | ||
return number > 0 ? Math.floor(number) : Math.ceil(number); | ||
} | ||
export function roundTo(number, digits, towardZero = false) { | ||
@@ -133,0 +129,0 @@ const factor = 10 ** digits, |
@@ -12,3 +12,3 @@ import DateTime from "./datetime.js"; | ||
const VERSION = "3.4.1"; | ||
const VERSION = "3.4.2"; | ||
@@ -15,0 +15,0 @@ export { |
{ | ||
"type": "module", | ||
"version": "3.4.1" | ||
"version": "3.4.2" | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
4076350
0.23%42489
0.15%