1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.units;
17
18 import java.text.ParseException;
19 import java.util.Locale;
20
21
22
23
24 public class DistanceFormatter extends MeasureFormatter<Distance, DistanceUnit> {
25
26
27
28
29 public static final String MILLIMETER = "mm";
30
31
32
33
34 public static final String CENTIMETER = "cm";
35
36
37
38
39 public static final String METER = "m";
40
41
42
43
44 public static final String KILOMETER = "Km";
45
46
47
48
49 public static final String INCH = "in";
50
51
52
53
54 public static final String FOOT = "ft";
55
56
57
58
59 public static final String YARD = "yd";
60
61
62
63
64 public static final String MILE = "mi";
65
66
67
68
69 public DistanceFormatter() {
70 super();
71 }
72
73
74
75
76
77
78
79 public DistanceFormatter(final Locale locale) {
80 super(locale);
81 }
82
83
84
85
86
87
88
89 public DistanceFormatter(final DistanceFormatter formatter) {
90 this(formatter.getLocale());
91 }
92
93
94
95
96
97
98
99 @Override
100 public boolean equals(final Object obj) {
101 final var equals = super.equals(obj);
102 return (obj instanceof DistanceFormatter) && equals;
103 }
104
105
106
107
108
109
110
111
112 @Override
113 public int hashCode() {
114 return super.hashCode();
115 }
116
117
118
119
120
121
122
123
124
125 @Override
126 public UnitSystem getUnitSystem(final String source) {
127 final var unit = findUnit(source);
128 return unit != null ? DistanceUnit.getUnitSystem(unit) : null;
129 }
130
131
132
133
134
135
136
137
138
139 @Override
140 public Distance parse(final String source) throws ParseException, UnknownUnitException {
141 return internalParse(source, new Distance());
142 }
143
144
145
146
147
148
149
150
151 @Override
152 public DistanceUnit findUnit(final String source) {
153 if (source.contains(MILLIMETER + " ") || source.endsWith(MILLIMETER)) {
154 return DistanceUnit.MILLIMETER;
155 }
156 if (source.contains(CENTIMETER + " ") || source.endsWith(CENTIMETER)) {
157 return DistanceUnit.CENTIMETER;
158 }
159 if (source.contains(KILOMETER + " ") || source.endsWith(KILOMETER)) {
160 return DistanceUnit.KILOMETER;
161 }
162 if (source.contains(INCH + " ") || source.endsWith(INCH)) {
163 return DistanceUnit.INCH;
164 }
165 if (source.contains(FOOT + " ") || source.endsWith(FOOT)) {
166 return DistanceUnit.FOOT;
167 }
168 if (source.contains(YARD + " ") || source.endsWith(YARD)) {
169 return DistanceUnit.YARD;
170 }
171 if (source.contains(MILE + " ") || source.endsWith(MILE)) {
172 return DistanceUnit.MILE;
173 }
174
175 if (source.contains(METER + " ") || source.endsWith(METER)) {
176 return DistanceUnit.METER;
177 }
178 return null;
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192
193 @Override
194 public String formatAndConvert(
195 final Number value, final DistanceUnit unit,
196 final UnitSystem system) {
197 if (system == UnitSystem.IMPERIAL) {
198 return formatAndConvertImperial(value, unit);
199 } else {
200 return formatAndConvertMetric(value, unit);
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 public String formatAndConvertMetric(final Number value, final DistanceUnit unit) {
216 final var v = value.doubleValue();
217
218 final var millimeters = DistanceConverter.convert(v, unit, DistanceUnit.MILLIMETER);
219 if (Math.abs(millimeters) < (DistanceConverter.METERS_PER_CENTIMETER
220 / DistanceConverter.METERS_PER_MILLIMETER)) {
221 return format(millimeters, DistanceUnit.MILLIMETER);
222 }
223
224 final var centimeters = DistanceConverter.convert(v, unit, DistanceUnit.CENTIMETER);
225 if (Math.abs(centimeters) < (1.0 / DistanceConverter.METERS_PER_CENTIMETER)) {
226 return format(centimeters, DistanceUnit.CENTIMETER);
227 }
228
229 final var meters = DistanceConverter.convert(v, unit, DistanceUnit.METER);
230 if (Math.abs(meters) < DistanceConverter.METERS_PER_KILOMETER) {
231 return format(meters, DistanceUnit.METER);
232 }
233
234 final var kilometers = DistanceConverter.convert(v, unit, DistanceUnit.KILOMETER);
235 return format(kilometers, DistanceUnit.KILOMETER);
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249 public String formatAndConvertImperial(final Number value, final DistanceUnit unit) {
250 final var v = value.doubleValue();
251
252 final var inches = DistanceConverter.convert(v, unit, DistanceUnit.INCH);
253 if (Math.abs(inches) < (DistanceConverter.METERS_PER_FOOT / DistanceConverter.METERS_PER_INCH)) {
254 return format(inches, DistanceUnit.INCH);
255 }
256
257 final var feet = DistanceConverter.convert(v, unit, DistanceUnit.FOOT);
258 if (Math.abs(feet) < (DistanceConverter.METERS_PER_YARD / DistanceConverter.METERS_PER_FOOT)) {
259 return format(feet, DistanceUnit.FOOT);
260 }
261
262 final var yards = DistanceConverter.convert(v, unit, DistanceUnit.YARD);
263 if (Math.abs(yards) < (DistanceConverter.METERS_PER_MILE / DistanceConverter.METERS_PER_YARD)) {
264 return format(yards, DistanceUnit.YARD);
265 }
266
267 final var miles = DistanceConverter.convert(v, unit, DistanceUnit.MILE);
268 return format(miles, DistanceUnit.MILE);
269 }
270
271
272
273
274
275
276
277 @Override
278 public String getUnitSymbol(final DistanceUnit unit) {
279 return switch (unit) {
280 case MILLIMETER -> MILLIMETER;
281 case CENTIMETER -> CENTIMETER;
282 case KILOMETER -> KILOMETER;
283 case INCH -> INCH;
284 case FOOT -> FOOT;
285 case YARD -> YARD;
286 case MILE -> MILE;
287 default -> METER;
288 };
289 }
290 }