|
| 1 | +import { IntlShape } from "react-intl"; |
| 2 | + |
| 3 | +function roundToOneDecimalPlace(number: number): number { |
| 4 | + return Math.round(number * 10) / 10; |
| 5 | +} |
| 6 | + |
1 | 7 | export function humanizeDistanceStringImperial( |
2 | 8 | meters: number, |
3 | | - abbreviate?: boolean |
| 9 | + abbreviate?: boolean, |
| 10 | + intl?: IntlShape |
4 | 11 | ): string { |
5 | 12 | const feet = meters * 3.28084; |
6 | | - if (feet < 528) |
7 | | - return Math.round(feet) + (abbreviate === true ? " ft" : " feet"); |
8 | | - return Math.round(feet / 528) / 10 + (abbreviate === true ? " mi" : " miles"); |
| 13 | + |
| 14 | + let unit = "mile"; |
| 15 | + let unitIfNoIntl = abbreviate ? "mi" : "miles"; |
| 16 | + let value = roundToOneDecimalPlace(feet / 5280); |
| 17 | + |
| 18 | + if (feet < 528) { |
| 19 | + unit = "foot"; |
| 20 | + unitIfNoIntl = abbreviate ? "ft" : "feet"; |
| 21 | + value = Math.round(feet); |
| 22 | + } |
| 23 | + |
| 24 | + return intl |
| 25 | + ? intl.formatNumber(value, { |
| 26 | + style: "unit", |
| 27 | + unit, |
| 28 | + unitDisplay: abbreviate ? "short" : "long" |
| 29 | + }) |
| 30 | + : `${value} ${unitIfNoIntl}`; |
9 | 31 | } |
10 | 32 |
|
11 | | -export function humanizeDistanceStringMetric(meters: number): string { |
| 33 | +export function humanizeDistanceStringMetric( |
| 34 | + meters: number, |
| 35 | + intl?: IntlShape |
| 36 | +): string { |
12 | 37 | const km = meters / 1000; |
13 | | - if (km > 100) { |
14 | | - // 100 km => 999999999 km |
15 | | - return `${km.toFixed(0)} km`; |
16 | | - } |
| 38 | + let unit = "meter"; |
| 39 | + let shortUnit = "m"; |
| 40 | + let value = Math.round(meters); |
| 41 | + |
17 | 42 | if (km > 1) { |
18 | | - // 1.1 km => 99.9 km |
19 | | - return `${km.toFixed(1)} km`; |
| 43 | + unit = "kilometer"; |
| 44 | + shortUnit = "km"; |
| 45 | + value = |
| 46 | + km > 100 |
| 47 | + ? // 100 km and over |
| 48 | + Math.round(km) |
| 49 | + : // 1.1 km => 99.9 km |
| 50 | + roundToOneDecimalPlace(km); |
20 | 51 | } |
21 | | - // 1m => 999m |
22 | | - return `${meters.toFixed(0)} m`; |
| 52 | + |
| 53 | + return intl |
| 54 | + ? intl.formatNumber(value, { |
| 55 | + style: "unit", |
| 56 | + unit, |
| 57 | + unitDisplay: "short" |
| 58 | + }) |
| 59 | + : `${value} ${shortUnit}`; |
23 | 60 | } |
24 | 61 |
|
25 | 62 | export function humanizeDistanceString( |
26 | 63 | meters: number, |
27 | | - outputMetricUnits = false |
| 64 | + outputMetricUnits = false, |
| 65 | + intl?: IntlShape |
28 | 66 | ): string { |
29 | 67 | return outputMetricUnits |
30 | | - ? humanizeDistanceStringMetric(meters) |
31 | | - : humanizeDistanceStringImperial(meters); |
| 68 | + ? humanizeDistanceStringMetric(meters, intl) |
| 69 | + : humanizeDistanceStringImperial(meters, null, intl); |
32 | 70 | } |
0 commit comments