1 package com.irurueta.units;
2
3 import java.text.ParseException;
4 import java.util.Locale;
5
6 /**
7 * Formats and parses temperature value and unit.
8 */
9 public class TemperatureFormatter extends MeasureFormatter<Temperature, TemperatureUnit> {
10
11 /**
12 * Celsius symbol.
13 */
14 public static final String CELSIUS = "ºC";
15
16 /**
17 * Fahrenheit symbol.
18 */
19 public static final String FAHRENHEIT = "ºF";
20
21 /**
22 * Kelvin symbol.
23 */
24 public static final String KELVIN = "K";
25
26 /**
27 * Constructor.
28 */
29 public TemperatureFormatter() {
30 super();
31 }
32
33 /**
34 * Constructor with locale.
35 *
36 * @param locale locale.
37 * @throws IllegalArgumentException if locale is null.
38 */
39 public TemperatureFormatter(final Locale locale) {
40 super(locale);
41 }
42
43 /**
44 * Copy constructor.
45 *
46 * @param formatter input instance to copy from.
47 * @throws NullPointerException if provided formatter is null.
48 */
49 public TemperatureFormatter(final TemperatureFormatter formatter) {
50 this(formatter.getLocale());
51 }
52
53 /**
54 * Determines if two temperature formatters are equal by comparing all of their
55 * internal parameters.
56 *
57 * @param obj another object to compare.
58 * @return true if provided object is assumed to be equal to this instance.
59 */
60 @Override
61 public boolean equals(final Object obj) {
62 final var equals = super.equals(obj);
63 return (obj instanceof TemperatureFormatter) && equals;
64 }
65
66 /**
67 * Hash code generated for this instance.
68 * Hash codes can be internally used by some collections to coarsely compare
69 * objects. This implementation only calls parent implementation to avoid
70 * static analyzer warning.
71 *
72 * @return hash code.
73 */
74 @Override
75 public int hashCode() {
76 return super.hashCode();
77 }
78
79 /**
80 * Gets unit system for detected unit into provided string representation
81 * of a measurement.
82 *
83 * @param source a measurement string representation to be checked.
84 * @return a unit system (either metric or imperial) or null if unit
85 * cannot be determined.
86 */
87 @Override
88 public UnitSystem getUnitSystem(final String source) {
89 final var unit = findUnit(source);
90 return unit != null ? TemperatureUnit.getUnitSystem(unit) : null;
91 }
92
93 /**
94 * Parses provided string and tries to determine a temperature value and unit.
95 *
96 * @param source a string to be parsed.
97 * @return a temperature containing a value and unit.
98 * @throws ParseException if provided string cannot be parsed.
99 * @throws UnknownUnitException if unit cannot be determined.
100 */
101 @Override
102 public Temperature parse(final String source) throws ParseException, UnknownUnitException {
103 return internalParse(source, new Temperature());
104 }
105
106 /**
107 * Attempts to determine a temperature unit within a measurement string
108 * representation.
109 *
110 * @param source a measurement string representation.
111 * @return a temperature unit, or null if none can be determined.
112 */
113 @Override
114 public TemperatureUnit findUnit(final String source) {
115 if (source.contains(CELSIUS + " ") || source.endsWith(CELSIUS)) {
116 return TemperatureUnit.CELSIUS;
117 }
118 if (source.contains(FAHRENHEIT + " ") || source.endsWith(FAHRENHEIT)) {
119 return TemperatureUnit.FAHRENHEIT;
120 }
121 if (source.contains(KELVIN + " ") || source.endsWith(KELVIN)) {
122 return TemperatureUnit.KELVIN;
123 }
124 return null;
125 }
126
127 /**
128 * Formats and converts provided temperature value and unit using provided
129 * unit system.
130 * If provided value is too large for provided unit, this method will
131 * convert it to a more appropriate unit using provided unit system (either
132 * metric or imperial).
133 * <p>
134 * This implementation just formats provided value using provided unit,
135 * ignoring provided unit system.
136 *
137 * @param value a temperature value.
138 * @param unit a temperature unit.
139 * @param system system unit to convert temperature to.
140 * @return a string representation of temperature value and unit.
141 */
142 @Override
143 public String formatAndConvert(final Number value, final TemperatureUnit unit, final UnitSystem system) {
144 return format(value, unit);
145 }
146
147 /**
148 * Returns unit string representation.
149 *
150 * @param unit a temperature unit.
151 * @return its string representation.
152 */
153 @Override
154 public String getUnitSymbol(final TemperatureUnit unit) {
155 return switch (unit) {
156 case FAHRENHEIT -> FAHRENHEIT;
157 case CELSIUS -> CELSIUS;
158 default -> KELVIN;
159 };
160 }
161 }