Skip to content

Commit 39027ea

Browse files
Converter utility added
1 parent 6556022 commit 39027ea

2 files changed

Lines changed: 433 additions & 0 deletions

File tree

src/utils/converter/Converter.js

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Length — mm, cm, m, km, inch, foot, mile
2+
// Weight — mg, g, kg, lb, oz
3+
// Temperature — Celsius, Fahrenheit, Kelvin
4+
// Digital storage — bits, bytes, KB, MB, GB, TB
5+
// Time — ms, seconds, minutes, hours, days
6+
7+
export default class Converter {
8+
/**
9+
* Converts a value from one unit to another.
10+
* @param {number} value - The numeric value to convert.
11+
* @param {string} fromUnit - The unit to convert from (e.g. 'km').
12+
* @param {string} toUnit - The unit to convert to (e.g. 'mile').
13+
* @returns {number}
14+
*/
15+
convert(value, fromUnit, toUnit) {
16+
if (fromUnit === toUnit) return value;
17+
18+
const fromFactor = Converter.conversionMap[fromUnit];
19+
const toFactor = Converter.conversionMap[toUnit];
20+
21+
if (fromFactor === undefined) {
22+
throw new Error(`Unknown unit: "${fromUnit}"`);
23+
}
24+
if (toFactor === undefined) {
25+
throw new Error(`Unknown unit: "${toUnit}"`);
26+
}
27+
28+
if (!Converter.sameCategory(fromUnit, toUnit)) {
29+
throw new Error(`Cannot convert "${fromUnit}" to "${toUnit}": different categories.`);
30+
}
31+
32+
// Convert: value -> base unit -> target unit
33+
return (value * fromFactor) / toFactor;
34+
}
35+
36+
// <-------- Length (base unit: meter) -------->
37+
38+
/**
39+
* Converts a length value from one unit to another.
40+
* @param {number} value
41+
* @param {string} fromUnit - One of: 'mm', 'cm', 'm', 'km', 'inch', 'foot', 'yard', 'mile'
42+
* @param {string} toUnit
43+
* @returns {number}
44+
*/
45+
convertLength(value, fromUnit, toUnit) {
46+
if (!Converter.lengthUnits.includes(fromUnit) || !Converter.lengthUnits.includes(toUnit)) {
47+
throw new Error('Both units must be valid length units.');
48+
}
49+
return this.convert(value, fromUnit, toUnit);
50+
}
51+
52+
/**
53+
* Converts a weight value from one unit to another.
54+
* @param {number} value
55+
* @param {string} fromUnit - One of: 'mg', 'g', 'kg', 'lb', 'oz'
56+
* @param {string} toUnit
57+
* @returns {number}
58+
*/
59+
convertWeight(value, fromUnit, toUnit) {
60+
if (!Converter.weightUnits.includes(fromUnit) || !Converter.weightUnits.includes(toUnit)) {
61+
throw new Error('Both units must be valid weight units.');
62+
}
63+
return this.convert(value, fromUnit, toUnit);
64+
}
65+
66+
// <---- Temperature needs special handling (formulas, not ratios) ---->
67+
/**
68+
* Converts a temperature value from one unit to another.
69+
* @param {number} value
70+
* @param {string} fromUnit - One of: 'C', 'F', 'K'
71+
* @param {string} toUnit
72+
* @returns {number}
73+
*/
74+
convertTemperature(value, fromUnit, toUnit) {
75+
if (
76+
!Converter.temperatureUnits.includes(fromUnit)
77+
|| !Converter.temperatureUnits.includes(toUnit)
78+
) {
79+
throw new Error('Both units must be valid temperature units.');
80+
}
81+
return Converter.convertTemperatureHelper(value, fromUnit, toUnit);
82+
}
83+
84+
/**
85+
* Converts a digital storage value from one unit to another.
86+
* @param {number} value
87+
* @param {string} fromUnit - One of: 'bit', 'byte', 'KB', 'MB', 'GB', 'TB'
88+
* @param {string} toUnit
89+
* @returns {number}
90+
*/
91+
convertStorage(value, fromUnit, toUnit) {
92+
if (
93+
!Converter.storageUnits.includes(fromUnit)
94+
|| !Converter.storageUnits.includes(toUnit)) {
95+
throw new Error('Both units must be valid digital storage units.');
96+
}
97+
return this.convert(value, fromUnit, toUnit);
98+
}
99+
100+
/**
101+
* Converts a time value from one unit to another.
102+
* @param {number} value
103+
* @param {string} fromUnit - One of: 'ms', 'second', 'minute', 'hour', 'day'
104+
* @param {string} toUnit
105+
* @returns {number}
106+
*/
107+
convertTime(value, fromUnit, toUnit) {
108+
if (!Converter.timeUnits.includes(fromUnit)
109+
|| !Converter.timeUnits.includes(toUnit)) {
110+
throw new Error('Both units must be valid time units.');
111+
}
112+
return this.convert(value, fromUnit, toUnit);
113+
}
114+
115+
// <---------- Static helpers ---------->
116+
117+
/**
118+
* Checks whether two units belong to the same category.
119+
* @param {string} unitA
120+
* @param {string} unitB
121+
* @returns {boolean}
122+
*/
123+
static sameCategory(unitA, unitB) {
124+
const categories = [
125+
Converter.lengthUnits,
126+
Converter.weightUnits,
127+
Converter.storageUnits,
128+
Converter.timeUnits,
129+
];
130+
return categories.some(
131+
(category) => category.includes(unitA) && category.includes(unitB),
132+
);
133+
}
134+
135+
/**
136+
* Handles temperature conversion using explicit formulas.
137+
* @param {number} value
138+
* @param {string} fromUnit - 'C', 'F', or 'K'
139+
* @param {string} toUnit - 'C', 'F', or 'K'
140+
* @returns {number}
141+
*/
142+
143+
static convertTemperatureHelper(value, fromUnit, toUnit) {
144+
if (String(fromUnit) === String(toUnit)) return value;
145+
146+
// Convert to Celsius first, then to target
147+
let celsius;
148+
switch (fromUnit) {
149+
case 'C': celsius = value; break;
150+
case 'F': celsius = (value - 32) * (5 / 9); break;
151+
case 'K': celsius = value - 273.15; break;
152+
default: throw new Error(`Unknown temperature unit: "${fromUnit}"`);
153+
}
154+
155+
switch (toUnit) {
156+
case 'C': return celsius;
157+
case 'F': return celsius * (9 / 5) + 32;
158+
case 'K': return celsius + 273.15;
159+
default: throw new Error(`Unknown temperature unit: "${toUnit}"`);
160+
}
161+
}
162+
163+
// <---------- Unit lists (used for category validation) ---------->
164+
165+
/** @returns {string[]} */
166+
static get lengthUnits() {
167+
return ['mm', 'cm', 'm', 'km', 'inch', 'foot', 'yard', 'mile'];
168+
}
169+
170+
/** @returns {string[]} */
171+
static get weightUnits() {
172+
return ['mg', 'g', 'kg', 'lb', 'oz'];
173+
}
174+
175+
/** @returns {string[]} */
176+
static get temperatureUnits() {
177+
return ['C', 'F', 'K'];
178+
}
179+
180+
/** @returns {string[]} */
181+
static get storageUnits() {
182+
return ['bit', 'byte', 'KB', 'MB', 'GB', 'TB'];
183+
}
184+
185+
/** @returns {string[]} */
186+
static get timeUnits() {
187+
return ['ms', 'second', 'minute', 'hour', 'day'];
188+
}
189+
190+
// <--------- Conversion map (each value = how many base units this unit equals) --------->
191+
192+
/**
193+
* A flat map of unit -> base-unit factor.
194+
* Base units: meter | gram | bit | millisecond
195+
* @returns {Object.<string, number>}
196+
*/
197+
198+
static get conversionMap() {
199+
return {
200+
// Length (base: meter)
201+
mm: 0.001,
202+
cm: 0.01,
203+
m: 1,
204+
km: 1000,
205+
inch: 0.0254,
206+
foot: 0.3048,
207+
yard: 0.9144,
208+
mile: 1609.344,
209+
210+
// Weight (base: gram)
211+
mg: 0.001,
212+
g: 1,
213+
kg: 1000,
214+
lb: 453.592,
215+
oz: 28.3495,
216+
217+
// Digital storage (base: bit)
218+
bit: 1,
219+
byte: 8,
220+
KB: 8000,
221+
MB: 8000000,
222+
GB: 8000000000,
223+
TB: 8000000000000,
224+
225+
// Time (base: millisecond)
226+
ms: 1,
227+
second: 1000,
228+
minute: 60000,
229+
hour: 3600000,
230+
day: 86400000,
231+
};
232+
}
233+
}

0 commit comments

Comments
 (0)