1 /*
  2  * TimeUnit.js - Unit conversions for time measurements
  3  *
  4  * Copyright © 2014-2015, 2018 JEDLSoft
  5  *
  6  * Licensed under the Apache License, Version 2.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  *
 10  *     http://www.apache.org/licenses/LICENSE-2.0
 11  *
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an "AS IS" BASIS,
 14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  *
 16  * See the License for the specific language governing permissions and
 17  * limitations under the License.
 18  */
 19 
 20 /*
 21 !depends
 22 Measurement.js
 23 */
 24 
 25 var Measurement = require("./Measurement.js");
 26 
 27 /**
 28  * @class
 29  * Create a new time measurement instance.
 30  *
 31  * @constructor
 32  * @extends Measurement
 33  * @param options {{unit:string,amount:number|string|undefined}} Options controlling
 34  * the construction of this instance
 35  */
 36 var TimeUnit = function (options) {
 37     this.unit = "second";
 38     this.amount = 0;
 39 
 40     this.ratios = TimeUnit.ratios;
 41     this.aliases = TimeUnit.aliases;
 42     this.aliasesLower = TimeUnit.aliasesLower;
 43     this.systems = TimeUnit.systems;
 44 
 45     this.parent.call(this, options);
 46 };
 47 
 48 TimeUnit.prototype = new Measurement();
 49 TimeUnit.prototype.parent = Measurement;
 50 TimeUnit.prototype.constructor = TimeUnit;
 51 
 52 TimeUnit.ratios = {
 53     /*              index  nsec        msec        mlsec       sec        min          hour          day           week         month        year         decade        century      millenium */
 54     "nanosecond":   [ 1,   1,          0.001,      1e-6,       1e-9,      1.6667e-11,  2.7778e-13,   1.1574e-14,   1.6534e-15,  3.8027e-16,  3.1689e-17,  3.1689e-18,   3.1689e-19,  3.1689e-20],
 55     "microsecond":  [ 2,   1000,       1,          0.001,      1e-6,      1.6667e-8,   2.7778e-10,   1.1574e-11,   1.6534e-12,  3.8027e-13,  3.1689e-14,  3.1689e-15,   3.1689e-16,  3.1689e-17],
 56     "millisecond":  [ 3,   1e+6,       1000,       1,          0.001,     1.6667e-5,   2.7778e-7,    1.1574e-8,    1.6534e-9,   3.8027e-10,  3.1689e-11,  3.1689e-12,   3.1689e-13,  3.1689e-14],
 57     "second":       [ 4,   1e+9,       1e+6,       1000,       1,         0.0166667,   0.000277778,  1.1574e-5,    1.6534e-6,   3.8027e-7,   3.1689e-8,   3.1689e-9,    3.1689e-10,  3.1689e-11],
 58     "minute":       [ 5,   6e+10,      6e+7,       60000,      60,        1,           0.0166667,    0.000694444,  9.9206e-5,   2.2816e-5,   1.9013e-6,   1.9013e-7,    1.9013e-8,   1.9013e-9 ],
 59     "hour":         [ 6,   3.6e+12,    3.6e+9,     3.6e+6,     3600,      60,          1,            0.0416667,    0.00595238,  0.00136895,  0.00011408,  1.1408e-5,    1.1408e-6,   1.1408e-7 ],
 60     "day":          [ 7,   8.64e+13,   8.64e+10,   8.64e+7,    86400,     1440,        24,           1,            0.142857,    0.0328549,   0.00273791,  0.000273791,  2.7379e-5,   2.7379e-6 ],
 61     "week":         [ 8,   6.048e+14,  6.048e+11,  6.048e+8,   604800,    10080,       168,          7,            1,           0.229984,    0.0191654,   0.00191654,   0.000191654, 1.91654e-5],
 62     "month":        [ 9,   2.63e+15,   2.63e+12,   2.63e+9,    2.63e+6,   43829.1,     730.484,      30.4368,      4.34812,     1,           0.0833333,   0.00833333,   0.000833333, 8.33333e-5],
 63     "year":         [ 10,  3.156e+16,  3.156e+13,  3.156e+10,  3.156e+7,  525949,      8765.81,      365.242,      52.1775,     12,          1,           0.1,          0.01,        0.001     ],
 64     "decade":       [ 11,  3.156e+17,  3.156e+14,  3.156e+11,  3.156e+8,  5.259e+6,    87658.1,      3652.42,      521.775,     120,         10,          1,            0.1,         0.01      ],
 65     "century":      [ 12,  3.156e+18,  3.156e+18,  3.156e+12,  3.156e+9,  5.259e+7,    876581,       36524.2,      5217.75,     1200,        100,         10,           1,           0.1       ],
 66     "millenium":    [ 13,  3.156e+19,  3.156e+19,  3.156e+13,  3.156e+10, 5.259e+8,    8765810,      365242,       52177.5,     12000,       1000,        100,          10,          1         ]
 67 };
 68 
 69 /**
 70  * Return the type of this measurement. Examples are "mass",
 71  * "length", "speed", etc. Measurements can only be converted
 72  * to measurements of the same type.<p>
 73  *
 74  * The type of the units is determined automatically from the
 75  * units. For example, the unit "grams" is type "mass". Use the
 76  * static call {@link Measurement.getAvailableUnits}
 77  * to find out what units this version of ilib supports.
 78  *
 79  * @return {string} the name of the type of this measurement
 80  */
 81 TimeUnit.prototype.getMeasure = function() {
 82     return "time";
 83 };
 84 
 85 /**
 86  * Return a new instance of this type of measurement.
 87  *
 88  * @param {Object} params parameters to the constructor
 89  * @return {Measurement} a measurement subclass instance
 90  */
 91 TimeUnit.prototype.newUnit = function(params) {
 92     return new TimeUnit(params);
 93 };
 94 
 95 
 96 TimeUnit.systems = {
 97     "metric": [
 98         "nanosecond",
 99         "microsecond",
100         "millisecond",
101         "second",
102         "minute",
103         "hour",
104         "day",
105         "week",
106         "month",
107         "year",
108         "decade",
109         "century"
110     ],
111     "uscustomary": [
112         "nanosecond",
113         "microsecond",
114         "millisecond",
115         "second",
116         "minute",
117         "hour",
118         "day",
119         "week",
120         "month",
121         "year",
122         "decade",
123         "century"
124     ],
125     "imperial": [
126         "nanosecond",
127         "microsecond",
128         "millisecond",
129         "second",
130         "minute",
131         "hour",
132         "day",
133         "week",
134         "month",
135         "year",
136         "decade",
137         "century"
138     ],
139     "conversions": {
140         "metric": {},
141         "uscustomary": {},
142         "imperial": {}
143     }
144 };
145 
146 TimeUnit.aliases = {
147     "ns": "nanosecond",
148     "NS": "nanosecond",
149     "nS": "nanosecond",
150     "Ns": "nanosecond",
151     "Nanosecond": "nanosecond",
152     "Nanoseconds": "nanosecond",
153     "nanosecond": "nanosecond",
154     "nanoseconds": "nanosecond",
155     "NanoSecond": "nanosecond",
156     "NanoSeconds": "nanosecond",
157     "μs": "microsecond",
158     "μS": "microsecond",
159     "microsecond": "microsecond",
160     "microseconds": "microsecond",
161     "Microsecond": "microsecond",
162     "Microseconds": "microsecond",
163     "MicroSecond": "microsecond",
164     "MicroSeconds": "microsecond",
165     "ms": "millisecond",
166     "MS": "millisecond",
167     "mS": "millisecond",
168     "Ms": "millisecond",
169     "millisecond": "millisecond",
170     "milliseconds": "millisecond",
171     "Millisecond": "millisecond",
172     "Milliseconds": "millisecond",
173     "MilliSecond": "millisecond",
174     "MilliSeconds": "millisecond",
175     "s": "second",
176     "S": "second",
177     "sec": "second",
178     "second": "second",
179     "seconds": "second",
180     "Second": "second",
181     "Seconds": "second",
182     "min": "minute",
183     "Min": "minute",
184     "minute": "minute",
185     "minutes": "minute",
186     "Minute": "minute",
187     "Minutes": "minute",
188     "h": "hour",
189     "H": "hour",
190     "hr": "hour",
191     "Hr": "hour",
192     "hR": "hour",
193     "HR": "hour",
194     "hour": "hour",
195     "hours": "hour",
196     "Hour": "hour",
197     "Hours": "hour",
198     "Hrs": "hour",
199     "hrs": "hour",
200     "day": "day",
201     "days": "day",
202     "Day": "day",
203     "Days": "day",
204     "week": "week",
205     "weeks": "week",
206     "Week": "week",
207     "Weeks": "week",
208     "month": "month",
209     "Month": "month",
210     "months": "month",
211     "Months": "month",
212     "year": "year",
213     "years": "year",
214     "Year": "year",
215     "Years": "year",
216     "yr": "year",
217     "Yr": "year",
218     "yrs": "year",
219     "Yrs": "year",
220     "decade": "decade",
221     "decades": "decade",
222     "Decade": "decade",
223     "Decades": "decade",
224     "century": "century",
225     "centuries": "century",
226     "Century": "century",
227     "Centuries": "century",
228     "millenium": "millenium",
229     "milleniums": "millenium",
230     "millenia": "millenium",
231     "mill.": "millenium",
232     "milm": "millenium"
233 };
234 
235 (function() {
236     TimeUnit.aliasesLower = {};
237     for (var a in TimeUnit.aliases) {
238         TimeUnit.aliasesLower[a.toLowerCase()] = TimeUnit.aliases[a];
239     }
240 })();
241 
242 /**
243  * Convert a time to another measure.
244  * @static
245  * @param to {string} unit to convert to
246  * @param from {string} unit to convert from
247  * @param time {number} amount to be convert
248  * @returns {number|undefined} the converted amount
249  */
250 TimeUnit.convert = function(to, from, time) {
251     from = Measurement.getUnitIdCaseInsensitive(TimeUnit, from) || from;
252     to = Measurement.getUnitIdCaseInsensitive(TimeUnit, to) || to;
253     var fromRow = TimeUnit.ratios[from];
254     var toRow = TimeUnit.ratios[to];
255     if (typeof(from) === 'undefined' || typeof(to) === 'undefined') {
256         return undefined;
257     }
258     return time * fromRow[toRow[0]];
259 };
260 
261 /**
262  * @private
263  * @static
264  */
265 TimeUnit.getMeasures = function () {
266     return Object.keys(TimeUnit.ratios);
267 };
268 
269 //register with the factory method
270 Measurement._constructors["time"] = TimeUnit;
271 
272 module.exports = TimeUnit;
273