Source

TemperatureUnit.js

/*
 * TemperatureUnit.js - Unit conversions for temperature measurements
 *
 * Copyright © 2014-2015, 2018 JEDLSoft
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
!depends
Measurement.js
*/

var Measurement = require("./Measurement.js");

/**
 * @class
 * Create a new Temperature measurement instance.
 *
 * @constructor
 * @extends Measurement
 * @param {Object} options Options controlling the construction of this instance
 * @param {string} options.unit
 * @param {number|string|undefined} options.amount * 
 */
var TemperatureUnit = function (options) {
    this.unit = "celsius";
    this.amount = 0;

    this.ratios = TemperatureUnit.ratios;
    this.aliases = TemperatureUnit.aliases;
    this.aliasesLower = TemperatureUnit.aliasesLower;
    this.systems = TemperatureUnit.systems;

    this.parent.call(this, options);
};

TemperatureUnit.prototype = new Measurement();
TemperatureUnit.prototype.parent = Measurement;
TemperatureUnit.prototype.constructor = TemperatureUnit;

TemperatureUnit.ratios = {
    /*            index, C            K            F   */
    "celsius":    [ 1,   1,           1,           9/5 ],
    "kelvin":     [ 2,   1,           1,           9/5 ],
    "fahrenheit": [ 3,   5/9,         5/9,         1   ]
};

/**
 * Return the type of this measurement. Examples are "mass",
 * "length", "speed", etc. Measurements can only be converted
 * to measurements of the same type.<p>
 *
 * The type of the units is determined automatically from the
 * units. For example, the unit "grams" is type "mass". Use the
 * static call {@link Measurement.getAvailableUnits}
 * to find out what units this version of ilib supports.
 *
 * @return {string} the name of the type of this measurement
 */
TemperatureUnit.prototype.getMeasure = function() {
    return "temperature";
};

/**
 * Return a new instance of this type of measurement.
 *
 * @param {Object} params parameters to the constructor
 * @return {Measurement} a measurement subclass instance
 */
TemperatureUnit.prototype.newUnit = function(params) {
    return new TemperatureUnit(params);
};

TemperatureUnit.systems = {
    "metric": [
        "celsius",
        "kelvin"
    ],
    "uscustomary": [
        "fahrenheit"
    ],
    "imperial": [
        "fahrenheit"
    ],
    "conversions": {
        "metric": {
            "uscustomary": {
                "celsius": "fahrenheit",
                "kelvin": "fahrenheit"
            },
            "imperial": {
                "celsius": "fahrenheit",
                "kelvin": "fahrenheit"
            }
        },
        "uscustomary": {
            "metric": {
                "fahrenheit": "celsius"
            }
        },
        "imperial": {
            "metric": {
                "fahrenheit": "celsius"
            }
        }
    }
};

TemperatureUnit.aliases = {
    "Celsius": "celsius",
    "C": "celsius",
    "Centegrade": "celsius",
    "Centigrade": "celsius",
    "Fahrenheit": "fahrenheit",
    "F": "fahrenheit",
    "K": "kelvin",
    "Kelvin": "kelvin",
    "°F": "fahrenheit",
    "℉": "fahrenheit",
    "℃": "celsius",
    "°C": "celsius"
};

(function() {
    TemperatureUnit.aliasesLower = {};
    for (var a in TemperatureUnit.aliases) {
        TemperatureUnit.aliasesLower[a.toLowerCase()] = TemperatureUnit.aliases[a];
    }
})();

/**
 * Return a new measurement instance that is converted to a new
 * measurement unit. Measurements can only be converted
 * to measurements of the same type.<p>
 *
 * @param {string} to The name of the units to convert to
 * @return {number|undefined} the converted measurement
 * or undefined if the requested units are for a different
 * measurement type
 */
TemperatureUnit.prototype.convert = function(to) {
    if (!to || typeof(TemperatureUnit.ratios[this.normalizeUnits(to)]) === 'undefined') {
        return undefined;
    }
    return TemperatureUnit.convert(to, this.unit, this.amount);
};

/**
 * Convert a temperature to another measure.
 * @static
 * @param to {string} unit to convert to
 * @param from {string} unit to convert from
 * @param temperature {number} amount to be convert
 * @returns {number|undefined} the converted amount
 */
TemperatureUnit.convert = function(to, from, temperature) {
    var result = 0;
    from = Measurement.getUnitIdCaseInsensitive(TemperatureUnit, from) || from;
    to = Measurement.getUnitIdCaseInsensitive(TemperatureUnit, to) || to;
    if (from === to) {
        return temperature;
    } else if (from === "celsius") {
        if (to === "fahrenheit") {
            result = ((temperature * 9 / 5) + 32);
        } else if (to === "kelvin") {
            result = (temperature + 273.15);
        }
    } else if (from === "fahrenheit") {
        if (to === "celsius") {
            result = ((5 / 9 * (temperature - 32)));
        } else if (to === "kelvin") {
            result = ((temperature + 459.67) * 5 / 9);
        }
    } else if (from === "kelvin") {
        if (to === "celsius") {
            result = (temperature - 273.15);
        } else if (to === "fahrenheit") {
            result = ((temperature * 9 / 5) - 459.67);
        }
    }

    return result;
};

/**
 * Scale the measurement unit to an acceptable level. The scaling
 * happens so that the integer part of the amount is as small as
 * possible without being below zero. This will result in the
 * largest units that can represent this measurement without
 * fractions. Measurements can only be scaled to other measurements
 * of the same type.
 *
 * @param {string=} measurementsystem system to use (uscustomary|imperial|metric),
 * or undefined if the system can be inferred from the current measure
 * @return {Measurement} a new instance that is scaled to the
 * right level
 */
TemperatureUnit.prototype.scale = function(measurementsystem) {
    // no scaling for temp units
    return this;
 };

/**
 * @private
 * @static
 */
TemperatureUnit.getMeasures = function () {
    return ["celsius", "kelvin", "fahrenheit"];
};

//register with the factory method
Measurement._constructors["temperature"] = TemperatureUnit;

module.exports = TemperatureUnit;