class UnitConverter {
// Conversion lookup tables mapped to base SI units:
// Mass -> Grams
// Length -> Meters
// Time -> Seconds
static MASS_IN_GRAMS = {
// Base / SI
g: 1.0, gram: 1.0, grams: 1.0,
kg: 1000.0, kilogram: 1000.0, kilograms: 1000.0,
mg: 0.001, milligram: 0.001, milligrams: 0.001,
ug: 1e-6, mcg: 1e-6, microgram: 1e-6, micrograms: 1e-6,
// Imperial / Customary
oz: 28.349523125, ounce: 28.349523125, ounces: 28.349523125,
lb: 453.59237, lbs: 453.59237, pound: 453.59237, pounds: 453.59237,
st: 6350.29318, stone: 6350.29318,
ton: 1016046.9088, tons: 1016046.9088,
us_ton: 907184.74,
tonne: 1000000.0, metric_ton: 1000000.0,
};
static LENGTH_IN_METERS = {
// Base / SI
m: 1.0, meter: 1.0, meters: 1.0, metre: 1.0, metres: 1.0,
km: 1000.0, kilometer: 1000.0, kilometers: 1000.0,
cm: 0.01, centimeter: 0.01, centimeters: 0.01,
mm: 0.001, millimeter: 0.001, millimeters: 0.001,
um: 1e-6, micron: 1e-6, micrometer: 1e-6,
nm: 1e-9, nanometer: 1e-9,
// Imperial / Customary
in: 0.0254, inch: 0.0254, inches: 0.0254,
ft: 0.3048, foot: 0.3048, feet: 0.3048,
yd: 0.9144, yard: 0.9144, yards: 0.9144,
mi: 1609.344, mile: 1609.344, miles: 1609.344,
furlong: 201.168, furlongs: 201.168,
chain: 20.1168, chains: 20.1168,
nmi: 1852.0, nautical_mile: 1852.0,
// Astronomical
au: 149597870700.0, astronomical_unit: 149597870700.0,
ly: 9460730472580800.0, light_year: 9460730472580800.0, lightyears: 9460730472580800.0,
pc: 3.0856775814913673e16, parsec: 3.0856775814913673e16,
};
static TIME_IN_SECONDS = {
// SI Units
s: 1.0, sec: 1.0, second: 1.0, seconds: 1.0,
ms: 0.001, millisecond: 0.001, milliseconds: 0.001,
us: 1e-6, microsecond: 1e-6, microseconds: 1e-6,
ns: 1e-9, nanosecond: 1e-9, nanoseconds: 1e-9,
ps: 1e-12, picosecond: 1e-12, picoseconds: 1e-12,
// Clock / Calendar
min: 60.0, minute: 60.0, minutes: 60.0,
h: 3600.0, hr: 3600.0, hrs: 3600.0, hour: 3600.0, hours: 3600.0,
d: 86400.0, day: 86400.0, days: 86400.0,
wk: 604800.0, week: 604800.0, weeks: 604800.0,
fortnight: 1209600.0, fortnights: 1209600.0,
mo: 2629746.0, month: 2629746.0, months: 2629746.0,
yr: 31556952.0, year: 31556952.0, years: 31556952.0,
decade: 315569520.0, decades: 315569520.0,
century: 3155695200.0, centuries: 3155695200.0,
};
/**
* Internal generic converter.
* Converts a object of source unit/value pairs to a base SI value,
* then scales to target unit.
*/
static _convert(table, targetUnit, inputs) {
const targetKey = String(targetUnit).toLowerCase();
if (!(targetKey in table)) {
throw new Error(`Unknown target unit '${targetUnit}'.`);
}
const inputKeys = Object.keys(inputs);
if (inputKeys.length === 0) {
throw new Error("Must supply at least one input unit value.");
}
let baseTotal = 0;
for (const key of inputKeys) {
const unitKey = String(key).toLowerCase();
if (!(unitKey in table)) {
throw new Error(`Unknown input unit '${key}'.`);
}
baseTotal += inputs[key] * table[unitKey];
}
return baseTotal / table[targetKey];
}
/**
* Converts mass inputs to target unit (default SI: 'kg').
* @param {string} unit Target unit
* @param {Object} inputs Object map of input unit/values (e.g. { kg: 3 })
*/
static toMassUnit(unit = "kg", inputs = {}) {
return this._convert(this.MASS_IN_GRAMS, unit, inputs);
}
/**
* Converts length inputs to target unit (default SI: 'm').
* @param {string} unit Target unit
* @param {Object} inputs Object map of input unit/values (e.g. { ly: 1 })
*/
static toLengthUnit(unit = "m", inputs = {}) {
return this._convert(this.LENGTH_IN_METERS, unit, inputs);
}
/**
* Converts time inputs to target unit (default SI: 's').
* @param {string} unit Target unit
* @param {Object} inputs Object map of input unit/values (e.g. { min: 1, sec: 30 })
*/
static toTimeUnit(unit = "s", inputs = {}) {
return this._convert(this.TIME_IN_SECONDS, unit, inputs);
}
}
// Mass (default target: "kg")
console.log(UnitConverter.toMassUnit("oz", { kg: 3 }));
// Output: 105.82188584874129
console.log(UnitConverter.toMassUnit("kg", { lb: 10, oz: 5 }));
// Output: 4.677669815625
// Length (default target: "m")
console.log(UnitConverter.toLengthUnit("km", { ly: 1 }));
// Output: 9460730472580.8
console.log(UnitConverter.toLengthUnit("in", { furlongs: 4 }));
// Output: 31680
// Time (default target: "s")
console.log(UnitConverter.toTimeUnit("ms", { min: 1, sec: 30 }));
// Output: 90000
console.log(UnitConverter.toTimeUnit("days", { hours: 36, min: 120 }));
// Output: 1.5833333333333333
console.log(UnitConverter.toTimeUnit("s", { weeks: 2, hours: 12 }));
// Output: 1252800