1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const ABSOLUTE = ["celsius", "kelvin", "fahrenheit"];
const ALIAS = ["c", "k", "f"];
const UNITS = [...ABSOLUTE, ...ALIAS];
const NUMBER_REGEX = "-?\\d+(?:\\.\\d+)?\\s*";
const UNIT_REGEX = "\\w+";
// NOTE: This regex need to be localized upon supporting multi locales
// since it supports en-US input format only.
const QUERY_REGEX = new RegExp(
`^(${NUMBER_REGEX})(${UNIT_REGEX})(?:\\s+in\\s+|\\s+to\\s+|\\s*=\\s*)(${UNIT_REGEX})`,
"i"
);
const DECIMAL_PRECISION = 10;
/**
* This module converts temperature unit.
*/
export class UnitConverterTemperature {
/**
* Convert the given search string.
*
* @param {string} searchString
* The string to be converted
* @returns {string} conversion result.
*/
convert(searchString) {
const regexResult = QUERY_REGEX.exec(searchString);
if (!regexResult) {
return null;
}
const target = findUnits(regexResult[2], regexResult[3]);
if (!target) {
return null;
}
const { inputUnit, outputUnit } = target;
const inputNumber = Number(regexResult[1]);
const inputChar = inputUnit.charAt(0);
const outputChar = outputUnit.charAt(0);
let outputNumber;
if (inputChar === outputChar) {
outputNumber = inputNumber;
} else {
outputNumber = this[`${inputChar}2${outputChar}`](inputNumber);
}
outputNumber = parseFloat(outputNumber.toPrecision(DECIMAL_PRECISION));
try {
return new Intl.NumberFormat("en-US", {
style: "unit",
unit: outputUnit,
maximumFractionDigits: DECIMAL_PRECISION,
}).format(outputNumber);
} catch (e) {}
return `${outputNumber} ${outputUnit}`;
}
c2k(t) {
return t + 273.15;
}
c2f(t) {
return t * 1.8 + 32;
}
k2c(t) {
return t - 273.15;
}
k2f(t) {
return this.c2f(this.k2c(t));
}
f2c(t) {
return (t - 32) / 1.8;
}
f2k(t) {
return this.c2k(this.f2c(t));
}
}
/**
* Returns the suitable units for the given two values.
* If could not found suitable unit, returns null.
*
* @param {string} inputUnit
* A set of units to convert, mapped to the `inputUnit` value on the return
* @param {string} outputUnit
* A set of units to convert, mapped to the `outputUnit` value on the return
* @returns {{ inputUnit: string, outputUnit: string }} The suitable units.
*/
function findUnits(inputUnit, outputUnit) {
inputUnit = inputUnit.toLowerCase();
outputUnit = outputUnit.toLowerCase();
if (!UNITS.includes(inputUnit) || !UNITS.includes(outputUnit)) {
return null;
}
return {
inputUnit: toAbsoluteUnit(inputUnit),
outputUnit: toAbsoluteUnit(outputUnit),
};
}
function toAbsoluteUnit(unit) {
if (unit.length !== 1) {
return unit;
}
return ABSOLUTE.find(a => a.startsWith(unit));
}
|