PluginProbe
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin / 6.5.1.7
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin v6.5.1.7
6.5.1.7 6.5.1.6 6.5.1.5 6.5.1.4 6.5.1.3 6.5.1.2 6.5.1.1 6.5.0.9 6.5.0.8 6.5.0.7 6.5.0.6 trunk 3.4.2.40 3.4.2.41 3.4.2.42 3.4.2.43 3.4.2.44 3.4.2.45 3.4.2.46 3.4.2.47 3.4.2.48 3.4.2.49 3.4.2.50 6.3.2 6.3.3.1 All 47 releases
wpdatatables / lib / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Calculation / Engineering / ConvertUOM.php

ConvertUOM.php in wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin 6.5.1.7, at lib/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php

695 lines 35.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering;
4
5 use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6 use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7 use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
8
9 class ConvertUOM
10 {
11 use ArrayEnabled;
12
13 public const CATEGORY_WEIGHT_AND_MASS = 'Weight and Mass';
14 public const CATEGORY_DISTANCE = 'Distance';
15 public const CATEGORY_TIME = 'Time';
16 public const CATEGORY_PRESSURE = 'Pressure';
17 public const CATEGORY_FORCE = 'Force';
18 public const CATEGORY_ENERGY = 'Energy';
19 public const CATEGORY_POWER = 'Power';
20 public const CATEGORY_MAGNETISM = 'Magnetism';
21 public const CATEGORY_TEMPERATURE = 'Temperature';
22 public const CATEGORY_VOLUME = 'Volume and Liquid Measure';
23 public const CATEGORY_AREA = 'Area';
24 public const CATEGORY_INFORMATION = 'Information';
25 public const CATEGORY_SPEED = 'Speed';
26
27 /**
28 * Details of the Units of measure that can be used in CONVERTUOM().
29 *
30 * @var mixed[]
31 */
32 private static $conversionUnits = [
33 // Weight and Mass
34 'g' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Gram', 'AllowPrefix' => true],
35 'sg' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Slug', 'AllowPrefix' => false],
36 'lbm' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => false],
37 'u' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => true],
38 'ozm' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => false],
39 'grain' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Grain', 'AllowPrefix' => false],
40 'cwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U.S. (short) hundredweight', 'AllowPrefix' => false],
41 'shweight' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'U.S. (short) hundredweight', 'AllowPrefix' => false],
42 'uk_cwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false],
43 'lcwt' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false],
44 'hweight' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial hundredweight', 'AllowPrefix' => false],
45 'stone' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Stone', 'AllowPrefix' => false],
46 'ton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Ton', 'AllowPrefix' => false],
47 'uk_ton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false],
48 'LTON' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false],
49 'brton' => ['Group' => self::CATEGORY_WEIGHT_AND_MASS, 'Unit Name' => 'Imperial ton', 'AllowPrefix' => false],
50 // Distance
51 'm' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Meter', 'AllowPrefix' => true],
52 'mi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Statute mile', 'AllowPrefix' => false],
53 'Nmi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Nautical mile', 'AllowPrefix' => false],
54 'in' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Inch', 'AllowPrefix' => false],
55 'ft' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Foot', 'AllowPrefix' => false],
56 'yd' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Yard', 'AllowPrefix' => false],
57 'ang' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Angstrom', 'AllowPrefix' => true],
58 'ell' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Ell', 'AllowPrefix' => false],
59 'ly' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Light Year', 'AllowPrefix' => false],
60 'parsec' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Parsec', 'AllowPrefix' => false],
61 'pc' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Parsec', 'AllowPrefix' => false],
62 'Pica' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => false],
63 'Picapt' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => false],
64 'pica' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'Pica (1/6 in)', 'AllowPrefix' => false],
65 'survey_mi' => ['Group' => self::CATEGORY_DISTANCE, 'Unit Name' => 'U.S survey mile (statute mile)', 'AllowPrefix' => false],
66 // Time
67 'yr' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Year', 'AllowPrefix' => false],
68 'day' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Day', 'AllowPrefix' => false],
69 'd' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Day', 'AllowPrefix' => false],
70 'hr' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Hour', 'AllowPrefix' => false],
71 'mn' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Minute', 'AllowPrefix' => false],
72 'min' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Minute', 'AllowPrefix' => false],
73 'sec' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Second', 'AllowPrefix' => true],
74 's' => ['Group' => self::CATEGORY_TIME, 'Unit Name' => 'Second', 'AllowPrefix' => true],
75 // Pressure
76 'Pa' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Pascal', 'AllowPrefix' => true],
77 'p' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Pascal', 'AllowPrefix' => true],
78 'atm' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true],
79 'at' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true],
80 'mmHg' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => true],
81 'psi' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'PSI', 'AllowPrefix' => true],
82 'Torr' => ['Group' => self::CATEGORY_PRESSURE, 'Unit Name' => 'Torr', 'AllowPrefix' => true],
83 // Force
84 'N' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Newton', 'AllowPrefix' => true],
85 'dyn' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Dyne', 'AllowPrefix' => true],
86 'dy' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Dyne', 'AllowPrefix' => true],
87 'lbf' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Pound force', 'AllowPrefix' => false],
88 'pond' => ['Group' => self::CATEGORY_FORCE, 'Unit Name' => 'Pond', 'AllowPrefix' => true],
89 // Energy
90 'J' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Joule', 'AllowPrefix' => true],
91 'e' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Erg', 'AllowPrefix' => true],
92 'c' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => true],
93 'cal' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'IT calorie', 'AllowPrefix' => true],
94 'eV' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Electron volt', 'AllowPrefix' => true],
95 'ev' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Electron volt', 'AllowPrefix' => true],
96 'HPh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false],
97 'hh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false],
98 'Wh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true],
99 'wh' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true],
100 'flb' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'Foot-pound', 'AllowPrefix' => false],
101 'BTU' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'BTU', 'AllowPrefix' => false],
102 'btu' => ['Group' => self::CATEGORY_ENERGY, 'Unit Name' => 'BTU', 'AllowPrefix' => false],
103 // Power
104 'HP' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Horsepower', 'AllowPrefix' => false],
105 'h' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Horsepower', 'AllowPrefix' => false],
106 'W' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true],
107 'w' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true],
108 'PS' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Pferdestärke', 'AllowPrefix' => false],
109 // Magnetism
110 'T' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Tesla', 'AllowPrefix' => true],
111 'ga' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Gauss', 'AllowPrefix' => true],
112 // Temperature
113 'C' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Celsius', 'AllowPrefix' => false],
114 'cel' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Celsius', 'AllowPrefix' => false],
115 'F' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Fahrenheit', 'AllowPrefix' => false],
116 'fah' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Fahrenheit', 'AllowPrefix' => false],
117 'K' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Kelvin', 'AllowPrefix' => false],
118 'kel' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Kelvin', 'AllowPrefix' => false],
119 'Rank' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Rankine', 'AllowPrefix' => false],
120 'Reau' => ['Group' => self::CATEGORY_TEMPERATURE, 'Unit Name' => 'Degrees Réaumur', 'AllowPrefix' => false],
121 // Volume
122 'l' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true],
123 'L' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true],
124 'lt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Litre', 'AllowPrefix' => true],
125 'tsp' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Teaspoon', 'AllowPrefix' => false],
126 'tspm' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Modern Teaspoon', 'AllowPrefix' => false],
127 'tbs' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Tablespoon', 'AllowPrefix' => false],
128 'oz' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => false],
129 'cup' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cup', 'AllowPrefix' => false],
130 'pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false],
131 'us_pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false],
132 'uk_pt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => false],
133 'qt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Quart', 'AllowPrefix' => false],
134 'uk_qt' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Imperial Quart (UK)', 'AllowPrefix' => false],
135 'gal' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gallon', 'AllowPrefix' => false],
136 'uk_gal' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Imperial Gallon (UK)', 'AllowPrefix' => false],
137 'ang3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Angstrom', 'AllowPrefix' => true],
138 'ang^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Angstrom', 'AllowPrefix' => true],
139 'barrel' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'US Oil Barrel', 'AllowPrefix' => false],
140 'bushel' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'US Bushel', 'AllowPrefix' => false],
141 'in3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Inch', 'AllowPrefix' => false],
142 'in^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Inch', 'AllowPrefix' => false],
143 'ft3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Foot', 'AllowPrefix' => false],
144 'ft^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Foot', 'AllowPrefix' => false],
145 'ly3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Light Year', 'AllowPrefix' => false],
146 'ly^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Light Year', 'AllowPrefix' => false],
147 'm3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Meter', 'AllowPrefix' => true],
148 'm^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Meter', 'AllowPrefix' => true],
149 'mi3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Mile', 'AllowPrefix' => false],
150 'mi^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Mile', 'AllowPrefix' => false],
151 'yd3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Yard', 'AllowPrefix' => false],
152 'yd^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Yard', 'AllowPrefix' => false],
153 'Nmi3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Nautical Mile', 'AllowPrefix' => false],
154 'Nmi^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Nautical Mile', 'AllowPrefix' => false],
155 'Pica3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false],
156 'Pica^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false],
157 'Picapt3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false],
158 'Picapt^3' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Cubic Pica', 'AllowPrefix' => false],
159 'GRT' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gross Registered Ton', 'AllowPrefix' => false],
160 'regton' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Gross Registered Ton', 'AllowPrefix' => false],
161 'MTON' => ['Group' => self::CATEGORY_VOLUME, 'Unit Name' => 'Measurement Ton (Freight Ton)', 'AllowPrefix' => false],
162 // Area
163 'ha' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Hectare', 'AllowPrefix' => true],
164 'uk_acre' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'International Acre', 'AllowPrefix' => false],
165 'us_acre' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'US Survey/Statute Acre', 'AllowPrefix' => false],
166 'ang2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Angstrom', 'AllowPrefix' => true],
167 'ang^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Angstrom', 'AllowPrefix' => true],
168 'ar' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Are', 'AllowPrefix' => true],
169 'ft2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Feet', 'AllowPrefix' => false],
170 'ft^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Feet', 'AllowPrefix' => false],
171 'in2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Inches', 'AllowPrefix' => false],
172 'in^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Inches', 'AllowPrefix' => false],
173 'ly2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Light Years', 'AllowPrefix' => false],
174 'ly^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Light Years', 'AllowPrefix' => false],
175 'm2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Meters', 'AllowPrefix' => true],
176 'm^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Meters', 'AllowPrefix' => true],
177 'Morgen' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Morgen', 'AllowPrefix' => false],
178 'mi2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Miles', 'AllowPrefix' => false],
179 'mi^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Miles', 'AllowPrefix' => false],
180 'Nmi2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Nautical Miles', 'AllowPrefix' => false],
181 'Nmi^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Nautical Miles', 'AllowPrefix' => false],
182 'Pica2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false],
183 'Pica^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false],
184 'Picapt2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false],
185 'Picapt^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Pica', 'AllowPrefix' => false],
186 'yd2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Yards', 'AllowPrefix' => false],
187 'yd^2' => ['Group' => self::CATEGORY_AREA, 'Unit Name' => 'Square Yards', 'AllowPrefix' => false],
188 // Information
189 'byte' => ['Group' => self::CATEGORY_INFORMATION, 'Unit Name' => 'Byte', 'AllowPrefix' => true],
190 'bit' => ['Group' => self::CATEGORY_INFORMATION, 'Unit Name' => 'Bit', 'AllowPrefix' => true],
191 // Speed
192 'm/s' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per second', 'AllowPrefix' => true],
193 'm/sec' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per second', 'AllowPrefix' => true],
194 'm/h' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per hour', 'AllowPrefix' => true],
195 'm/hr' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Meters per hour', 'AllowPrefix' => true],
196 'mph' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Miles per hour', 'AllowPrefix' => false],
197 'admkn' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Admiralty Knot', 'AllowPrefix' => false],
198 'kn' => ['Group' => self::CATEGORY_SPEED, 'Unit Name' => 'Knot', 'AllowPrefix' => false],
199 ];
200
201 /**
202 * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM().
203 *
204 * @var mixed[]
205 */
206 private static $conversionMultipliers = [
207 'Y' => ['multiplier' => 1E24, 'name' => 'yotta'],
208 'Z' => ['multiplier' => 1E21, 'name' => 'zetta'],
209 'E' => ['multiplier' => 1E18, 'name' => 'exa'],
210 'P' => ['multiplier' => 1E15, 'name' => 'peta'],
211 'T' => ['multiplier' => 1E12, 'name' => 'tera'],
212 'G' => ['multiplier' => 1E9, 'name' => 'giga'],
213 'M' => ['multiplier' => 1E6, 'name' => 'mega'],
214 'k' => ['multiplier' => 1E3, 'name' => 'kilo'],
215 'h' => ['multiplier' => 1E2, 'name' => 'hecto'],
216 'e' => ['multiplier' => 1E1, 'name' => 'dekao'],
217 'da' => ['multiplier' => 1E1, 'name' => 'dekao'],
218 'd' => ['multiplier' => 1E-1, 'name' => 'deci'],
219 'c' => ['multiplier' => 1E-2, 'name' => 'centi'],
220 'm' => ['multiplier' => 1E-3, 'name' => 'milli'],
221 'u' => ['multiplier' => 1E-6, 'name' => 'micro'],
222 'n' => ['multiplier' => 1E-9, 'name' => 'nano'],
223 'p' => ['multiplier' => 1E-12, 'name' => 'pico'],
224 'f' => ['multiplier' => 1E-15, 'name' => 'femto'],
225 'a' => ['multiplier' => 1E-18, 'name' => 'atto'],
226 'z' => ['multiplier' => 1E-21, 'name' => 'zepto'],
227 'y' => ['multiplier' => 1E-24, 'name' => 'yocto'],
228 ];
229
230 /**
231 * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM().
232 *
233 * @var mixed[]
234 */
235 private static $binaryConversionMultipliers = [
236 'Yi' => ['multiplier' => 2 ** 80, 'name' => 'yobi'],
237 'Zi' => ['multiplier' => 2 ** 70, 'name' => 'zebi'],
238 'Ei' => ['multiplier' => 2 ** 60, 'name' => 'exbi'],
239 'Pi' => ['multiplier' => 2 ** 50, 'name' => 'pebi'],
240 'Ti' => ['multiplier' => 2 ** 40, 'name' => 'tebi'],
241 'Gi' => ['multiplier' => 2 ** 30, 'name' => 'gibi'],
242 'Mi' => ['multiplier' => 2 ** 20, 'name' => 'mebi'],
243 'ki' => ['multiplier' => 2 ** 10, 'name' => 'kibi'],
244 ];
245
246 /**
247 * Details of the Units of measure conversion factors, organised by group.
248 *
249 * @var mixed[]
250 */
251 private static $unitConversions = [
252 // Conversion uses gram (g) as an intermediate unit
253 self::CATEGORY_WEIGHT_AND_MASS => [
254 'g' => 1.0,
255 'sg' => 6.85217658567918E-05,
256 'lbm' => 2.20462262184878E-03,
257 'u' => 6.02214179421676E+23,
258 'ozm' => 3.52739619495804E-02,
259 'grain' => 1.54323583529414E+01,
260 'cwt' => 2.20462262184878E-05,
261 'shweight' => 2.20462262184878E-05,
262 'uk_cwt' => 1.96841305522212E-05,
263 'lcwt' => 1.96841305522212E-05,
264 'hweight' => 1.96841305522212E-05,
265 'stone' => 1.57473044417770E-04,
266 'ton' => 1.10231131092439E-06,
267 'uk_ton' => 9.84206527611061E-07,
268 'LTON' => 9.84206527611061E-07,
269 'brton' => 9.84206527611061E-07,
270 ],
271 // Conversion uses meter (m) as an intermediate unit
272 self::CATEGORY_DISTANCE => [
273 'm' => 1.0,
274 'mi' => 6.21371192237334E-04,
275 'Nmi' => 5.39956803455724E-04,
276 'in' => 3.93700787401575E+01,
277 'ft' => 3.28083989501312E+00,
278 'yd' => 1.09361329833771E+00,
279 'ang' => 1.0E+10,
280 'ell' => 8.74890638670166E-01,
281 'ly' => 1.05700083402462E-16,
282 'parsec' => 3.24077928966473E-17,
283 'pc' => 3.24077928966473E-17,
284 'Pica' => 2.83464566929134E+03,
285 'Picapt' => 2.83464566929134E+03,
286 'pica' => 2.36220472440945E+02,
287 'survey_mi' => 6.21369949494950E-04,
288 ],
289 // Conversion uses second (s) as an intermediate unit
290 self::CATEGORY_TIME => [
291 'yr' => 3.16880878140289E-08,
292 'day' => 1.15740740740741E-05,
293 'd' => 1.15740740740741E-05,
294 'hr' => 2.77777777777778E-04,
295 'mn' => 1.66666666666667E-02,
296 'min' => 1.66666666666667E-02,
297 'sec' => 1.0,
298 's' => 1.0,
299 ],
300 // Conversion uses Pascal (Pa) as an intermediate unit
301 self::CATEGORY_PRESSURE => [
302 'Pa' => 1.0,
303 'p' => 1.0,
304 'atm' => 9.86923266716013E-06,
305 'at' => 9.86923266716013E-06,
306 'mmHg' => 7.50063755419211E-03,
307 'psi' => 1.45037737730209E-04,
308 'Torr' => 7.50061682704170E-03,
309 ],
310 // Conversion uses Newton (N) as an intermediate unit
311 self::CATEGORY_FORCE => [
312 'N' => 1.0,
313 'dyn' => 1.0E+5,
314 'dy' => 1.0E+5,
315 'lbf' => 2.24808923655339E-01,
316 'pond' => 1.01971621297793E+02,
317 ],
318 // Conversion uses Joule (J) as an intermediate unit
319 self::CATEGORY_ENERGY => [
320 'J' => 1.0,
321 'e' => 9.99999519343231E+06,
322 'c' => 2.39006249473467E-01,
323 'cal' => 2.38846190642017E-01,
324 'eV' => 6.24145700000000E+18,
325 'ev' => 6.24145700000000E+18,
326 'HPh' => 3.72506430801000E-07,
327 'hh' => 3.72506430801000E-07,
328 'Wh' => 2.77777916238711E-04,
329 'wh' => 2.77777916238711E-04,
330 'flb' => 2.37304222192651E+01,
331 'BTU' => 9.47815067349015E-04,
332 'btu' => 9.47815067349015E-04,
333 ],
334 // Conversion uses Horsepower (HP) as an intermediate unit
335 self::CATEGORY_POWER => [
336 'HP' => 1.0,
337 'h' => 1.0,
338 'W' => 7.45699871582270E+02,
339 'w' => 7.45699871582270E+02,
340 'PS' => 1.01386966542400E+00,
341 ],
342 // Conversion uses Tesla (T) as an intermediate unit
343 self::CATEGORY_MAGNETISM => [
344 'T' => 1.0,
345 'ga' => 10000.0,
346 ],
347 // Conversion uses litre (l) as an intermediate unit
348 self::CATEGORY_VOLUME => [
349 'l' => 1.0,
350 'L' => 1.0,
351 'lt' => 1.0,
352 'tsp' => 2.02884136211058E+02,
353 'tspm' => 2.0E+02,
354 'tbs' => 6.76280454036860E+01,
355 'oz' => 3.38140227018430E+01,
356 'cup' => 4.22675283773038E+00,
357 'pt' => 2.11337641886519E+00,
358 'us_pt' => 2.11337641886519E+00,
359 'uk_pt' => 1.75975398639270E+00,
360 'qt' => 1.05668820943259E+00,
361 'uk_qt' => 8.79876993196351E-01,
362 'gal' => 2.64172052358148E-01,
363 'uk_gal' => 2.19969248299088E-01,
364 'ang3' => 1.0E+27,
365 'ang^3' => 1.0E+27,
366 'barrel' => 6.28981077043211E-03,
367 'bushel' => 2.83775932584017E-02,
368 'in3' => 6.10237440947323E+01,
369 'in^3' => 6.10237440947323E+01,
370 'ft3' => 3.53146667214886E-02,
371 'ft^3' => 3.53146667214886E-02,
372 'ly3' => 1.18093498844171E-51,
373 'ly^3' => 1.18093498844171E-51,
374 'm3' => 1.0E-03,
375 'm^3' => 1.0E-03,
376 'mi3' => 2.39912758578928E-13,
377 'mi^3' => 2.39912758578928E-13,
378 'yd3' => 1.30795061931439E-03,
379 'yd^3' => 1.30795061931439E-03,
380 'Nmi3' => 1.57426214685811E-13,
381 'Nmi^3' => 1.57426214685811E-13,
382 'Pica3' => 2.27769904358706E+07,
383 'Pica^3' => 2.27769904358706E+07,
384 'Picapt3' => 2.27769904358706E+07,
385 'Picapt^3' => 2.27769904358706E+07,
386 'GRT' => 3.53146667214886E-04,
387 'regton' => 3.53146667214886E-04,
388 'MTON' => 8.82866668037215E-04,
389 ],
390 // Conversion uses hectare (ha) as an intermediate unit
391 self::CATEGORY_AREA => [
392 'ha' => 1.0,
393 'uk_acre' => 2.47105381467165E+00,
394 'us_acre' => 2.47104393046628E+00,
395 'ang2' => 1.0E+24,
396 'ang^2' => 1.0E+24,
397 'ar' => 1.0E+02,
398 'ft2' => 1.07639104167097E+05,
399 'ft^2' => 1.07639104167097E+05,
400 'in2' => 1.55000310000620E+07,
401 'in^2' => 1.55000310000620E+07,
402 'ly2' => 1.11725076312873E-28,
403 'ly^2' => 1.11725076312873E-28,
404 'm2' => 1.0E+04,
405 'm^2' => 1.0E+04,
406 'Morgen' => 4.0E+00,
407 'mi2' => 3.86102158542446E-03,
408 'mi^2' => 3.86102158542446E-03,
409 'Nmi2' => 2.91553349598123E-03,
410 'Nmi^2' => 2.91553349598123E-03,
411 'Pica2' => 8.03521607043214E+10,
412 'Pica^2' => 8.03521607043214E+10,
413 'Picapt2' => 8.03521607043214E+10,
414 'Picapt^2' => 8.03521607043214E+10,
415 'yd2' => 1.19599004630108E+04,
416 'yd^2' => 1.19599004630108E+04,
417 ],
418 // Conversion uses bit (bit) as an intermediate unit
419 self::CATEGORY_INFORMATION => [
420 'bit' => 1.0,
421 'byte' => 0.125,
422 ],
423 // Conversion uses Meters per Second (m/s) as an intermediate unit
424 self::CATEGORY_SPEED => [
425 'm/s' => 1.0,
426 'm/sec' => 1.0,
427 'm/h' => 3.60E+03,
428 'm/hr' => 3.60E+03,
429 'mph' => 2.23693629205440E+00,
430 'admkn' => 1.94260256941567E+00,
431 'kn' => 1.94384449244060E+00,
432 ],
433 ];
434
435 /**
436 * getConversionGroups
437 * Returns a list of the different conversion groups for UOM conversions.
438 *
439 * @return array
440 */
441 public static function getConversionCategories()
442 {
443 $conversionGroups = [];
444 foreach (self::$conversionUnits as $conversionUnit) {
445 $conversionGroups[] = $conversionUnit['Group'];
446 }
447
448 return array_merge(array_unique($conversionGroups));
449 }
450
451 /**
452 * getConversionGroupUnits
453 * Returns an array of units of measure, for a specified conversion group, or for all groups.
454 *
455 * @param string $category The group whose units of measure you want to retrieve
456 *
457 * @return array
458 */
459 public static function getConversionCategoryUnits($category = null)
460 {
461 $conversionGroups = [];
462 foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) {
463 if (($category === null) || ($conversionGroup['Group'] == $category)) {
464 $conversionGroups[$conversionGroup['Group']][] = $conversionUnit;
465 }
466 }
467
468 return $conversionGroups;
469 }
470
471 /**
472 * getConversionGroupUnitDetails.
473 *
474 * @param string $category The group whose units of measure you want to retrieve
475 *
476 * @return array
477 */
478 public static function getConversionCategoryUnitDetails($category = null)
479 {
480 $conversionGroups = [];
481 foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) {
482 if (($category === null) || ($conversionGroup['Group'] == $category)) {
483 $conversionGroups[$conversionGroup['Group']][] = [
484 'unit' => $conversionUnit,
485 'description' => $conversionGroup['Unit Name'],
486 ];
487 }
488 }
489
490 return $conversionGroups;
491 }
492
493 /**
494 * getConversionMultipliers
495 * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM().
496 *
497 * @return mixed[]
498 */
499 public static function getConversionMultipliers()
500 {
501 return self::$conversionMultipliers;
502 }
503
504 /**
505 * getBinaryConversionMultipliers
506 * Returns an array of the additional Multiplier prefixes that can be used with Information Units of Measure in CONVERTUOM().
507 *
508 * @return mixed[]
509 */
510 public static function getBinaryConversionMultipliers()
511 {
512 return self::$binaryConversionMultipliers;
513 }
514
515 /**
516 * CONVERT.
517 *
518 * Converts a number from one measurement system to another.
519 * For example, CONVERT can translate a table of distances in miles to a table of distances
520 * in kilometers.
521 *
522 * Excel Function:
523 * CONVERT(value,fromUOM,toUOM)
524 *
525 * @param array|float|int|string $value the value in fromUOM to convert
526 * Or can be an array of values
527 * @param array|string $fromUOM the units for value
528 * Or can be an array of values
529 * @param array|string $toUOM the units for the result
530 * Or can be an array of values
531 *
532 * @return array|float|string Result, or a string containing an error
533 * If an array of numbers is passed as an argument, then the returned result will also be an array
534 * with the same dimensions
535 */
536 public static function CONVERT($value, $fromUOM, $toUOM)
537 {
538 if (is_array($value) || is_array($fromUOM) || is_array($toUOM)) {
539 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $fromUOM, $toUOM);
540 }
541
542 if (!is_numeric($value)) {
543 return ExcelError::VALUE();
544 }
545
546 try {
547 [$fromUOM, $fromCategory, $fromMultiplier] = self::getUOMDetails($fromUOM);
548 [$toUOM, $toCategory, $toMultiplier] = self::getUOMDetails($toUOM);
549 } catch (Exception $e) {
550 return ExcelError::NA();
551 }
552
553 if ($fromCategory !== $toCategory) {
554 return ExcelError::NA();
555 }
556
557 // @var float $value
558 $value *= $fromMultiplier;
559
560 if (($fromUOM === $toUOM) && ($fromMultiplier === $toMultiplier)) {
561 // We've already factored $fromMultiplier into the value, so we need
562 // to reverse it again
563 return $value / $fromMultiplier;
564 } elseif ($fromUOM === $toUOM) {
565 return $value / $toMultiplier;
566 } elseif ($fromCategory === self::CATEGORY_TEMPERATURE) {
567 return self::convertTemperature($fromUOM, $toUOM, /** @scrutinizer ignore-type */ $value);
568 }
569
570 $baseValue = $value * (1.0 / self::$unitConversions[$fromCategory][$fromUOM]);
571
572 return ($baseValue * self::$unitConversions[$fromCategory][$toUOM]) / $toMultiplier;
573 }
574
575 private static function getUOMDetails(string $uom): array
576 {
577 if (isset(self::$conversionUnits[$uom])) {
578 $unitCategory = self::$conversionUnits[$uom]['Group'];
579
580 return [$uom, $unitCategory, 1.0];
581 }
582
583 // Check 1-character standard metric multiplier prefixes
584 $multiplierType = substr($uom, 0, 1);
585 $uom = substr($uom, 1);
586 if (isset(self::$conversionUnits[$uom], self::$conversionMultipliers[$multiplierType])) {
587 if (self::$conversionUnits[$uom]['AllowPrefix'] === false) {
588 throw new Exception('Prefix not allowed for UoM');
589 }
590 $unitCategory = self::$conversionUnits[$uom]['Group'];
591
592 return [$uom, $unitCategory, self::$conversionMultipliers[$multiplierType]['multiplier']];
593 }
594
595 $multiplierType .= substr($uom, 0, 1);
596 $uom = substr($uom, 1);
597
598 // Check 2-character standard metric multiplier prefixes
599 if (isset(self::$conversionUnits[$uom], self::$conversionMultipliers[$multiplierType])) {
600 if (self::$conversionUnits[$uom]['AllowPrefix'] === false) {
601 throw new Exception('Prefix not allowed for UoM');
602 }
603 $unitCategory = self::$conversionUnits[$uom]['Group'];
604
605 return [$uom, $unitCategory, self::$conversionMultipliers[$multiplierType]['multiplier']];
606 }
607
608 // Check 2-character binary multiplier prefixes
609 if (isset(self::$conversionUnits[$uom], self::$binaryConversionMultipliers[$multiplierType])) {
610 if (self::$conversionUnits[$uom]['AllowPrefix'] === false) {
611 throw new Exception('Prefix not allowed for UoM');
612 }
613 $unitCategory = self::$conversionUnits[$uom]['Group'];
614 if ($unitCategory !== 'Information') {
615 throw new Exception('Binary Prefix is only allowed for Information UoM');
616 }
617
618 return [$uom, $unitCategory, self::$binaryConversionMultipliers[$multiplierType]['multiplier']];
619 }
620
621 throw new Exception('UoM Not Found');
622 }
623
624 /**
625 * @param float|int $value
626 *
627 * @return float|int
628 */
629 protected static function convertTemperature(string $fromUOM, string $toUOM, $value)
630 {
631 $fromUOM = self::resolveTemperatureSynonyms($fromUOM);
632 $toUOM = self::resolveTemperatureSynonyms($toUOM);
633
634 if ($fromUOM === $toUOM) {
635 return $value;
636 }
637
638 // Convert to Kelvin
639 switch ($fromUOM) {
640 case 'F':
641 $value = ($value - 32) / 1.8 + 273.15;
642
643 break;
644 case 'C':
645 $value += 273.15;
646
647 break;
648 case 'Rank':
649 $value /= 1.8;
650
651 break;
652 case 'Reau':
653 $value = $value * 1.25 + 273.15;
654
655 break;
656 }
657
658 // Convert from Kelvin
659 switch ($toUOM) {
660 case 'F':
661 $value = ($value - 273.15) * 1.8 + 32.00;
662
663 break;
664 case 'C':
665 $value -= 273.15;
666
667 break;
668 case 'Rank':
669 $value *= 1.8;
670
671 break;
672 case 'Reau':
673 $value = ($value - 273.15) * 0.80000;
674
675 break;
676 }
677
678 return $value;
679 }
680
681 private static function resolveTemperatureSynonyms(string $uom): string
682 {
683 switch ($uom) {
684 case 'fah':
685 return 'F';
686 case 'cel':
687 return 'C';
688 case 'kel':
689 return 'K';
690 }
691
692 return $uom;
693 }
694 }
695