View Javadoc
1   /*
2    * Copyright (C) 2020 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.units;
17  
18  import java.math.BigDecimal;
19  
20  /**
21   * Does temperature conversions to different units.
22   * To prevent loss of accuracy, conversion should only be done as a final step
23   * before displaying temperature measurements.
24   */
25  public class TemperatureConverter {
26  
27      /**
28       * Absolute zero temperature expressed in Kelvins (K).
29       */
30      public static final double ABSOLUTE_ZERO = -273.15;
31  
32      /**
33       * Constructor.
34       * Prevents instantiation of helper class.
35       */
36      private TemperatureConverter() {
37      }
38  
39      /**
40       * Converts a temperature to provided output temperature unit.
41       *
42       * @param input  input temperature to be converted.
43       * @param output output temperature where result will be stored and containing
44       *               output unit.
45       */
46      public static void convert(final Temperature input, final Temperature output) {
47          convert(input, output.getUnit(), output);
48      }
49  
50      /**
51       * Converts a temperature to requested output unit.
52       *
53       * @param input      input temperature to be converted.
54       * @param outputUnit requested output unit.
55       * @return converted temperature.
56       */
57      public static Temperature convertAndReturnNew(final Temperature input, final TemperatureUnit outputUnit) {
58          final var result = new Temperature();
59          convert(input, outputUnit, result);
60          return result;
61      }
62  
63      /**
64       * Converts and updates a temperature to requested output unit.
65       *
66       * @param temperature input temperature to be converted and updated.
67       * @param outputUnit  requested output unit.
68       */
69      public static void convert(final Temperature temperature, final TemperatureUnit outputUnit) {
70          convert(temperature, outputUnit, temperature);
71      }
72  
73      /**
74       * Converts a temperature to requested output unit.
75       *
76       * @param input      input temperature to be converted.
77       * @param outputUnit requested output unit.
78       * @param result     temperature unit where result will be stored.
79       */
80      public static void convert(final Temperature input, final TemperatureUnit outputUnit, final Temperature result) {
81          final var value = convert(input.getValue(), input.getUnit(), outputUnit);
82          result.setValue(value);
83          result.setUnit(outputUnit);
84      }
85  
86      /**
87       * Converts a temperature value from input unit to provided output unit.
88       *
89       * @param input      temperature value.
90       * @param inputUnit  input temperature unit.
91       * @param outputUnit output temperature unit.
92       * @return converted temperature value.
93       */
94      public static Number convert(
95              final Number input, final TemperatureUnit inputUnit, final TemperatureUnit outputUnit) {
96          return BigDecimal.valueOf(convert(input.doubleValue(), inputUnit, outputUnit));
97      }
98  
99      /**
100      * Converts a temperature value from input unit to provided output unit.
101      *
102      * @param input      temperature value.
103      * @param inputUnit  input temperature unit.
104      * @param outputUnit output temperature unit.
105      * @return converted temperature value.
106      */
107     public static double convert(
108             final double input, final TemperatureUnit inputUnit, final TemperatureUnit outputUnit) {
109 
110         // convert to celsius
111         final var celsius = switch (inputUnit) {
112             case FAHRENHEIT -> fahrenheitToCelsius(input);
113             case KELVIN -> kelvinToCelsius(input);
114             default -> input;
115         };
116 
117         // convert from celsius to required output unit
118         return switch (outputUnit) {
119             case FAHRENHEIT -> celsiusToFahrenheit(celsius);
120             case KELVIN -> celsiusToKelvin(celsius);
121             default -> celsius;
122         };
123     }
124 
125     /**
126      * Converts provided Kelvin value to Celsius.
127      *
128      * @param kelvin kelvin value.
129      * @return some amount of temperature converted to Celsius.
130      */
131     public static double kelvinToCelsius(final double kelvin) {
132         return kelvin + ABSOLUTE_ZERO;
133     }
134 
135     /**
136      * Converts provided Celsius value to Kelvin.
137      *
138      * @param celsius celsius value.
139      * @return some amount of temperature converted to Kelvin.
140      */
141     public static double celsiusToKelvin(final double celsius) {
142         return celsius - ABSOLUTE_ZERO;
143     }
144 
145     /**
146      * Converts provided Celsius value to Fahrenheit.
147      *
148      * @param celsius celsius value.
149      * @return some amount of temperature converted to Fahrenheit.
150      */
151     public static double celsiusToFahrenheit(final double celsius) {
152         return celsius * 9.0 / 5.0 + 32.0;
153     }
154 
155     /**
156      * Converts provided Fahrenheit value to Celsius.
157      *
158      * @param fahrenheit fahrenheit value.
159      * @return some amount of temperature converted to Celsius.
160      */
161     public static double fahrenheitToCelsius(final double fahrenheit) {
162         return (fahrenheit - 32.0) * 5.0 / 9.0;
163     }
164 }