├── .gitattributes
├── .github
└── workflows
│ └── ci.yaml
├── .gitignore
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── README.md
├── composer.json
├── scripts
├── lint
├── shell
└── test
├── source
├── AbstractPhysicalQuantity.php
├── Exception
│ ├── AbstractPhysicalQuantityException.php
│ ├── DuplicateUnitNameOrAlias.php
│ ├── NonNumericValue.php
│ ├── NonStringUnitName.php
│ ├── PhysicalQuantityMismatch.php
│ └── UnknownUnitOfMeasure.php
├── HasSIUnitsTrait.php
├── PhysicalQuantity
│ ├── Acceleration.php
│ ├── Angle.php
│ ├── Area.php
│ ├── ElectricCurrent.php
│ ├── Energy.php
│ ├── Length.php
│ ├── LuminousIntensity.php
│ ├── Mass.php
│ ├── Power.php
│ ├── Pressure.php
│ ├── Quantity.php
│ ├── SolidAngle.php
│ ├── Temperature.php
│ ├── Time.php
│ ├── Velocity.php
│ └── Volume.php
├── PhysicalQuantityInterface.php
├── UnitOfMeasure.php
└── UnitOfMeasureInterface.php
└── tests
├── AbstractPhysicalQuantityTest.php
├── DemonstrationTests.php
├── Fixtures
└── PhysicalQuantity
│ ├── Wigginess.php
│ ├── Wonkicity.php
│ └── Woogosity.php
├── PhysicalQuantity
├── AbstractPhysicalQuantityTestCase.php
├── AccelerationTest.php
├── AngleTest.php
├── AreaTest.php
├── ElectricCurrentTest.php
├── EnergyTest.php
├── LengthTest.php
├── LuminousIntensityTest.php
├── MassTest.php
├── PowerTest.php
├── PressureTest.php
├── QuantityTest.php
├── SolidAngleTest.php
├── TemperatureTest.php
├── TimeTest.php
├── VelocityTest.php
└── VolumeTest.php
├── UnitOfMeasureTest.php
├── phpcs.xml
└── phpunit.xml.dist
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text eol=lf
3 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | # .github/workflows/code_checks.yaml
2 | name: Code_Checks
3 |
4 | on: ["push", "pull_request"]
5 |
6 | jobs:
7 | tests:
8 | runs-on: ubuntu-latest
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | php: ['7.4']
13 | stability: [ prefer-stable ]
14 | experimental: [false]
15 | include:
16 | - php: '7.4'
17 | stability: prefer-lowest
18 | - php: '8.0'
19 | - php: '8.1'
20 | - php: '8.2'
21 | - php: '8.3'
22 | - php: '8.4'
23 |
24 | name: PHP ${{ matrix.php }} - ${{ matrix.stability }} tests
25 | steps:
26 | # basically git clone
27 | - uses: actions/checkout@v4
28 |
29 | - name: Cache dependencies
30 | uses: actions/cache@v3
31 | with:
32 | path: ~/.composer/cache/files
33 | key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
34 |
35 | # use PHP of specific version
36 | - uses: shivammathur/setup-php@v2
37 | with:
38 | php-version: ${{ matrix.php }}
39 | extensions: pcov
40 | coverage: pcov
41 |
42 | - name: Install dependencies
43 | run: |
44 | composer install --verbose --prefer-dist --no-interaction -o
45 |
46 | - name: Execute tests
47 | run: composer run-script test
48 |
49 | cs:
50 | runs-on: ubuntu-latest
51 | steps:
52 | - uses: actions/checkout@v4
53 | - uses: shivammathur/setup-php@v2
54 | with:
55 | php-version: 8.2
56 | coverage: none # disable xdebug, pcov
57 | - run: composer install --no-progress
58 | - run: composer run-script lint
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Editors and IDEs
2 | /.idea/
3 | *.sublime-workspace
4 | *.sublime-project
5 |
6 | # Windows image file caches
7 | Thumbs.db
8 |
9 | # Mac folder view config
10 | .DS_Store
11 | Desktop.ini
12 |
13 | # Python compiled files
14 | *.py[co]
15 |
16 | # PHP Composer files
17 | /composer.phar
18 | /composer.lock
19 | /vendor/
20 |
21 | # Sass
22 | ## From https://github.com/github/gitignore
23 | ### SASS Ignores - "Sassy CSS" http://sass-lang.com/
24 | *.sass-cache
25 |
26 | .phpunit.result.cache
27 | tests/clover.xml
28 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## v2.2.0 (April 30th, 2025)
2 | - Drop support of PHP < 7.4
3 | - Add `isUnitDefined()`, `listAllUnits()`, `getOriginalValue()`, and `getOriginalUnit()` methods to the Physical Quantity parent class
4 | - Add new Power Physical Quantity
5 | - Add Imperial Gallons to the Volume quantity
6 | - Move to Github Actions, away from Travis CI
7 | - Use Docker containers instead of Vagrant/VBox instances for dev environments
8 | - Add local dev scripts for `lint`, `test`, and `shell`, in `./scripts/`
9 |
10 | ## v2.1.0 (July 24th, 2016)
11 | - Added getUnitDefinitions() method to PhysicalQuantity classes, to get a raw list of UnitofMeasure objects defined on that quantity
12 | - Added UPPERCASE templating support for autogenerated metric units to support names like MEGA_METERS, for example.
13 | - New Quantity physical quantity, with `mole` as the standard unit, to represent the Amount of Substance SI base quantity.
14 | - New SolidAngle physical quantity, with `steradian` as the standard unit, to represent the solid angle quantity
15 | - Additional aliases for Area units
16 | - Additional units for time: decade, century, and millenium
17 | - Additional units for volume: teaspoon, tablespoon, gallon, quart, fluid ounce, and pint
18 |
19 |
20 | ## v2.0.1 (December 12th, 2015)
21 | - Migrated package from triplepoint/php-units-of-measure to php-units-of-measure/php-units-of-measure.
22 | - New physical quantity: Energy
23 | - New units of measure:
24 | - Area: are and decare
25 | - Length: nautical mile, mil, AU
26 | - Mass: stone, also slightly changed definitions of lb and oz
27 | - Time: yr, and jyr
28 | - Velocity: km/h, ft/s, mph, knot
29 | - Automated CI testing now includes HHVM and PHP 7
30 | - Removed the heavy vagrant git submodule, it was a silly thing.
31 | - Expanded the Readme for better contribution and installation instructions.
32 |
33 | ## v2.0.0 (March 14th, 2015)
34 | - Registered units of measure are now properties of PhysicalQuantity classes, and not individual instances of those classes. As such, registering a new unit with a given PhysicalQuantity will make that unit immediately available to all inntances of that class.
35 | - PhysicalQuantity classes no longer define their units in their constructor, and instead have a new initialize() static method
36 | - The previously-existing registerUnitOfMeasure() method on physical quantity objects has been replaced with a new static addUnit() method
37 | - The HasSoUnitsTrait method addMissingSIPrefixedUnits is now static
38 | - Added the toNativeUnit() method, to return values in their native unit of measure
39 | - Added the isEquivalentQuantity() method, to support future situations where it's not obvious whether two physical quantities represent the same quantity type
40 | - getSupportedUnits() is no longer available on physical quantities
41 | - The PhysicalQuantity parent class is now named AbstractPhysicalQuantity
42 | - Add a new DemonstrationTests test file, to demonstrate and test typical use cases
43 | - All library exceptions extend from AbstractPhysicalQuantityException, making catching easier
44 | - Added an interface for PhysicalQuantities, to support future work where not all physical quantity classes necessarily have the same parent
45 |
46 | ## v1.3.3 (March 15th, 2015)
47 | - Loosened Composer requirement on PHP version to >=5.3.0 (was previously 5.3.5).
48 |
49 | ## v1.3.1 (August 23rd, 2014)
50 | - Added information in the README about the new SI prefix units generation
51 |
52 | ## v1.3.0 (August 23rd, 2014)
53 | - Add support for automatically generating metric-prefixed units from a single base unit
54 | - Throw an exception on registering units of measure with names or aliases that collide with existing units on that quantity
55 | - Disallow values that aren't numerical and unit names that aren't strings (ie, type checking)
56 | - Add new method getSupportedUnits() to Physical Quantities
57 | - Add new method getAliases() to Units of Measure
58 | - Add arcminute and arcsecond as angle units
59 | - Add all SI prefix units to meters, kilograms, seconds, amps, kelvin, candela, pascal, bar, radians, degrees, and arcseconds
60 |
61 | ## v1.2.0 (August 16th, 2014)
62 | - Drop support for PHP 5.3
63 | - Moved to PSR-4 namespace convention
64 | - Drop support for an array of names passed in the constructor as a way to specify aliases for UnitOfMeasure objects; addAlias() now required.
65 | - Add UnitOfMeasure::nativeUnitFactory() and UnitOfMeasure::linearUnitFactory() convenience factory methods
66 | - Add optional spelling for 'metres' and 'litres'
67 | - Add Vagrant-based testing virtual machine, for convenience
68 |
69 | ## v1.1.2 (February 9th, 2014)
70 | - New units of measure on Area: hectares, international acres
71 | - New units of measure on Temperature: Rankin, Delisle, Newton, Réaumur, Rømer
72 | - Improved unit test coverage
73 |
74 | ## v1.1.1 (July 8th, 2013)
75 | - New physical quantity: Angle
76 | - Additional units of measure on Time
77 |
78 | ## v1.1.0 (May 7th, 2013)
79 | - Add add() and subtract() methods to physical quantities
80 | - toString() on quantities now shows the original unit, as expected
81 |
82 | ## v1.0.0 (May 7th, 2013)
83 | Initial Commit
84 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:7.4-cli
2 |
3 | RUN apt-get update && apt-get install -y --no-install-recommends \
4 | git \
5 | curl \
6 | unzip \
7 | && rm -rf /var/lib/apt/lists/*
8 |
9 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin && ln -s /usr/local/bin/composer.phar /usr/local/bin/composer
10 |
11 | RUN git config --global --add safe.directory /project
12 |
13 | WORKDIR /project
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2012 Jonathan Hanson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is furnished
10 | to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP Units of Measure
2 | master: [](https://travis-ci.org/PhpUnitsOfMeasure/php-units-of-measure)
3 |
4 | ## Introduction
5 | This is a PHP library for representing and converting physical units of measure. The utility of this library is in encapsulating physical quantities in such a way that you don't have to keep track of which unit they're represented in. For instance:
6 |
7 | ``` php
8 | use PhpUnitsOfMeasure\PhysicalQuantity\Length;
9 |
10 | $height = new Length(6.16, 'feet');
11 | echo $height->toUnit('m');
12 |
13 | // would print 1.87757, which is 6.16 feet in meters.
14 | ```
15 |
16 | Having this abstraction allows you to create interfaces that accept physical quantities without requiring them to be in a particular unit. For example, this function assumes the height is a float of a particular unit (presumably feet), and is therefore undesirably tied to a specific unit of measure:
17 |
18 | ``` php
19 | // Tied to a specific unit of measure
20 | function isTooTallToRideThisTrain( $height )
21 | {
22 | return $height > 5;
23 | }
24 |
25 | // Calling the function requires that you first convert whatever quantity
26 | // you have into the expected units:
27 | isTooTallToRideThisTrain(2 / 0.3048);
28 | ```
29 |
30 | Whereas this version using this library allows for height to be provided in whatever unit is convenient:
31 |
32 | ``` php
33 | use PhpUnitsOfMeasure\PhysicalQuantity\Length;
34 |
35 | // Free to operate on lengths in any unit of measure
36 | function isTooTallToRideThisTrain( Length $height )
37 | {
38 | return $height->toUnit('ft') > 5;
39 | }
40 |
41 | // Calling the function now allows any unit to be used:
42 | isTooTallToRideThisTrain( new Length(2, 'm') );
43 | ```
44 |
45 | ## Installation
46 | This library is best included in your projects via Composer. See the [Composer website](https://getcomposer.org/) for more details, and see the [Packagist.org site for this library](https://packagist.org/packages/php-units-of-measure/php-units-of-measure).
47 |
48 | If you'd prefer to manually include this library as a dependency in your project, then it is recommended that you use a [PSR-4](https://www.php-fig.org/psr/psr-4/) compliant PHP autoloader. The mapping between this project's root namespace and its base directory is:
49 | - vendor namespace 'PhpUnitsOfMeasure\' maps to the library's base directory 'source/'
50 |
51 | See the documentation of your autoloader for further instructions.
52 |
53 | ### Project Tags and Versions
54 | This project follows the guidelines set out in [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). In general, versions are of the form 'X.Y.Z', and increments to X denote backward-incompatible major changes.
55 |
56 | It is recommended that if your project includes this project as a dependency and you are using an automated dependency management tool such as [Composer](https://getcomposer.org/), then you should 'pin' the major version (X) and allow only variations in 'Y' (minor changes) and 'Z' (bugfixes). See the documentation of your dependency manager for more details.
57 |
58 |
59 | ## Use
60 | ### Conversion
61 | As in the examples above, the basic usage of this library is in representing physical quantities and converting between typical units of measure. For example:
62 |
63 | ``` php
64 | use PhpUnitsOfMeasure\PhysicalQuantity\Mass;
65 |
66 | $quantity = new Mass(6, 'lbs');
67 | echo $quantity->toUnit('g');
68 | ```
69 | It's also possible to implicity cast a quantity to a string, which will display its original value:
70 |
71 | ``` php
72 | use PhpUnitsOfMeasure\PhysicalQuantity\Mass;
73 |
74 | $quantity = new Mass(6, 'pounds');
75 | echo $quantity; // '6 lbs'
76 | ```
77 |
78 | ### Arithmetic Operators
79 | There's also support for addition and subtraction. The values of the physical quantity objects are immutable, and so these arithmetic methods return new quantity objects representing the results:
80 |
81 | ``` php
82 | use PhpUnitsOfMeasure\PhysicalQuantity\Volume;
83 |
84 | $first = new Volume(6, 'liters');
85 | $second = new Volume(6, 'cups');
86 |
87 | $sum = $first->add($second);
88 | echo $sum; // 7.4195292 l
89 |
90 | $difference = $first->subtract($second);
91 | echo $difference; // 4.5804708 l
92 | ```
93 |
94 | ### Adding new Units of Measure to Existing Quantities
95 | Ocassionally, you will need to add a new unit of measure to a pre-existing quantity.
96 |
97 | For example, let's say in a project you need a new measure of length, called "cubits". You have two options: you can permanently add the new unit of measure to a new child class of the `\PhpUnitsOfMeasure\PhysicalQuantity\Length` class (or add it directly to that class and submit a pull request to get it added upstream, if appropriate), or you can add the unit temporarily at run time, inside your calling code.
98 |
99 | #### Adding a New Unit of Measure at Runtime
100 | To add a new unit of measure to an existing quantity at run time, you'd do this:
101 |
102 | ``` php
103 | use PhpUnitsOfMeasure\PhysicalQuantity\Length;
104 | use PhpUnitsOfMeasure\PhysicalQuantity\UnitOfMeasure;
105 |
106 | // It's ok to create objects with cubits before the new unit is registered, since
107 | // the conversion doesn't happen until an output method is called
108 | $length = new Length(14, 'cubits');
109 |
110 | // Build a new Unit of Measure object which represents the new unit, and which
111 | // knows how to convert between the new unit and the quantity's native unit
112 | // (in this case, meters).
113 | $cubit = new UnitOfMeasure(
114 |
115 | // This is the official name of this unit - typically it's the standard
116 | // abbreviation
117 | 'cb',
118 |
119 | // The second parameter is a function that converts from the native unit
120 | // to this unit
121 | function ($valueInNativeUnit) {
122 | return $valueInNativeUnit / 0.4572;
123 | },
124 |
125 | // The third parameter is a function that converts from this unit to the
126 | // native unit
127 | function ($valueInThisUnit) {
128 | return $valueInThisUnit * 0.4572;
129 | }
130 | );
131 |
132 | // Any alias names for this unit can be added here, to make it easier to use
133 | // variations
134 | $cubit->addAlias('cubit');
135 | $cubit->addAlias('cubits');
136 |
137 | // Register the new unit of measure with the quantity class
138 | Length::addUnit($cubit);
139 |
140 | // Now that the unit is registered, you can cast the measurement to any other
141 | // measure of length
142 | echo $length->toUnit('feet'); // '21'
143 | ```
144 |
145 | ##### Shorthand Factory Methods
146 | Note that when creating instances of `UnitOfMeasure`, there are a couple of convenience static factory methods. The first lets you instantiate units of measure which have linear scaling factors from the native unit. That is, the conversion function fits into the form `'Value in the native unit of measure' = 'Value in this unit of measure' * F`, where `F` is the scaling factor.
147 |
148 | ``` php
149 | $megameter = UnitOfMeasure::linearUnitFactory('Mm', 1e6);
150 | $megameter->addAlias('Megameter');
151 | $megameter->addAlias('Megametre');
152 | Length::addUnit($megameter);
153 | ```
154 |
155 | The other convenience method is a special case of the above scaling factor factory method where the scaling factor is set to exactly 1, and serves as a convenient way of generating the native unit of measure. All physical quantities must have one and only one native unit, so this method will probably only be called once per Physical Quantity class:
156 |
157 | ``` php
158 | $meter = UnitOfMeasure::nativeUnitFactory('m');
159 | $meter->addAlias('meter');
160 | $meter->addAlias('metre');
161 | Length::addUnit($meter);
162 | ```
163 |
164 | ##### Automatically Generating Metric Units
165 | For units that use the metric system, there's a convenience trait available for classes which implement`PhysicalQuantityInterface` which will automatically generate the full continuum of metric units from a single unit. For instance:
166 |
167 | ``` php
168 | namespace PhpUnitsOfMeasure\PhysicalQuantity;
169 |
170 | use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
171 | use PhpUnitsOfMeasure\UnitOfMeasure;
172 | use PhpUnitsOfMeasure\HasSIUnitsTrait;
173 |
174 | class Mass extends AbstractPhysicalQuantity
175 | {
176 | use HasSIUnitsTrait;
177 |
178 | protected static $unitDefinitions;
179 |
180 | protected static function initialize()
181 | {
182 | // Kilogram
183 | $kilogram = UnitOfMeasure::nativeUnitFactory('kg');
184 | $kilogram->addAlias('kilogram');
185 | $kilogram->addAlias('kilograms');
186 | static::addUnit($kilogram);
187 |
188 | static::addMissingSIPrefixedUnits(
189 | $kilogram,
190 | 1e-3,
191 | '%pg',
192 | [
193 | '%Pgram',
194 | '%Pgrams',
195 | ]
196 | );
197 | }
198 | }
199 | ```
200 |
201 | Here we're generating the native unit for mass, kilogram, adding it to the quantity as usual, and then using it to generate the spectrum of SI units by calling the `addMissingSIPrefixedUnits()` static method provided by the `HasSIUnitsTrait` trait.
202 |
203 | Of note, the second parameter (1e-3) is denoting that while kilograms are the native unit for Mass, there's a factor of 1/1000 between the kilogram and the base metric unit of mass: the gram. For units such as seconds or meters where the native unit for the physical quantity is also the base unit for the metric prefix system, this factor would be 1.
204 |
205 | The 3rd and 4th parameters contain templates for the units' names and alternate aliases, respectively. The replacement strings '%p' and '%P' are used to denote the abbreviated and long-form metric prefixes. For instance, '%pg' would generate the series `..., 'mg', 'cg', 'dg', 'g', ...`, while the template '%Pgram' would generate the series `..., 'milligram', 'centigram', 'decigram', 'gram', ...` .
206 |
207 | #### Permanently Adding a New Unit of Measure to a Physical Quantity
208 | The examples above for adding new units of measure to physical quantities allow you to register new units for the duration of the PHP execution, but are lost once execution terminates; it would be necessary to repeat this process every time you created a new program with `Length` measurements and wanted to use cubits.
209 |
210 | A new unit of measure can be permanently added to a Physical Quantity class by essentially the same process as the one-time examples, only it would be done inside the initialize() method of the quantity class. For example:
211 |
212 | ``` php
213 | namespace PhpUnitsOfMeasure\PhysicalQuantity;
214 |
215 | use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
216 | use PhpUnitsOfMeasure\UnitOfMeasure;
217 |
218 | class Length extends AbstractPhysicalQuantity
219 | {
220 | protected static $unitDefinitions;
221 |
222 | protected static function initialize()
223 | {
224 | // ...
225 | // ...
226 | // Here's all the pre-existing unit definitions for Length
227 | // ...
228 | // ...
229 |
230 | // Cubit
231 | $cubit = UnitOfMeasure::linearUnitFactory('cb', 0.4572);
232 | $cubit->addAlias('cubit');
233 | $cubit->addAlias('cubits');
234 | static::addUnit($cubit);
235 | }
236 | }
237 | ```
238 |
239 | Now any program which uses `Length` will start with the cubits unit already built in. Note that here we used the more concise linear unit factory method, but the result is equivalent to the expanded form calling the `UnitOfMeasure` constructor, as used above. Also, notice that the `static` keyword was used instead of the class name, though either would be acceptable in this case.
240 |
241 | ### Adding New Physical Quantities
242 | [Physical quantities](https://en.wikipedia.org/wiki/Physical_quantity) are categories of measurable values, like mass, length, force, etc.
243 |
244 | For physical quantities that are not already present in this library, it will be necessary to write a class to support a new one. All physical quantities implement the `\PhpUnitsOfMeasure\PhysicalQuantityInterface` interface, typically extend the `\PhpUnitsOfMeasure\AbstractPhysicalQuantity` class, and typically have only an `initialize()` method which creates the quantity's units of measure. See above for typical examples of physical quantity classes and of how to add new units to a quantity class.
245 |
246 | Note that every physical quantity has a chosen "native unit" which is typically the SI standard. The main point for this unit is that all of the quantity's other units of measure will convert to and from this chosen native unit. It's important to be aware of a quantity's native unit when writing conversions for new units of measure.
247 |
248 | ### Adding new Aliases to Existing Units
249 | It may come up that the desired unit of measure exists for a given physical quantity, but there's a missing alias for the unit. For example, if you thought 'footses' was an obviously lacking alias for the `Length` unit 'ft', you could temporarily add the alias like this:
250 |
251 | ``` php
252 | use PhpUnitsOfMeasure\PhysicalQuantity\Length;
253 |
254 | // It's ok to use footses here, since the conversion doesn't happen
255 | // until later
256 | $length = new Length(4, 'footses');
257 |
258 | // Fetch the unit of measure object that represents the 'ft' unit
259 | $footUnit = Length::getUnit('ft');
260 |
261 | // Any alias names for this unit can be added here, to make it easier
262 | // to use variations
263 | $footUnit->addAlias('footses');
264 |
265 | // Now that the unit has been modified with its new alias, you can cast
266 | // the measurement to any other measure of length
267 | echo $length->toUnit('m'); // '1.2192'
268 | ```
269 |
270 | And of course, if you need to add the alias permanently, you can do so in the initialize() method of the quantity's class, as shown above.
271 |
272 | ## Testing and Contributing
273 | Pull requests are welcome, especially regarding new units of measure or new physical quantities. However, please note that there are many sources for conversion factors, and not all are careful to respect known precision.
274 |
275 | In the United States, the standards body for measurement is NIST, and they've published [NIST Special Publication 1038 "The International System of Units (SI) - Conversion factors for General Use"](http://www.nist.gov/pml/wmd/metric/upload/SP1038.pdf). This guide contains the approved conversion factors between various units and the base SI units.
276 |
277 | Also note that any new physical quantities should have the appropriate SI unit chosen for their native unit of measure.
278 |
279 | ### Pull Requests and Merging
280 | The workflow for this repository goes as follows:
281 | - To develop new contributions, fork or branch from the `master` branch of the main repository
282 | - Pull requests and contribution merges are always made to the `master` branch of the main repository
283 | - From time to time, commits of `master` are tagged and a new version is released
284 | - At present, there is no support for maintaining bug-fix branches of older project versions. This is something we can revisit if a need arises.
285 |
286 | End users of this repository should only use tagged commits in production. Users interested in the current 'soon-to-be-released' code may use `master`, with the understanding that it may change unexpectedly. All other existing branches (if any) should be considered 'feature' branches in development, and not yet ready for use.
287 |
288 | ### Local Testing Environment
289 | There's a `Dockerfile` and a set of helper scripts in `scripts/` suitable for running the necessary unit tests. With Docker installed, do:
290 |
291 | ``` shell
292 | # Execute the lint checks
293 | ./script/lint
294 |
295 | # Execute the unit tests
296 | ./script/test
297 | ```
298 |
299 | In addition, `./script/shell` will get you a bash shell in a temporary container. Note that the hosts directory is mounted into the container, and changes to files inside the container will persist.
300 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-units-of-measure/php-units-of-measure",
3 | "description": "A PHP library for converting between standard units of measure.",
4 | "keywords": [
5 | "measurements",
6 | "data",
7 | "conversion"
8 | ],
9 | "homepage": "https://github.com/PhpUnitsOfMeasure/php-units-of-measure",
10 | "license": "MIT",
11 | "authors": [
12 | {
13 | "name": "Jonathan Hanson",
14 | "role": "Developer"
15 | }
16 | ],
17 | "support": {
18 | "issues": "https://github.com/PhpUnitsOfMeasure/php-units-of-measure/issues",
19 | "source": "https://github.com/PhpUnitsOfMeasure/php-units-of-measure"
20 | },
21 | "require": {
22 | "php": ">=7.4"
23 | },
24 | "require-dev": {
25 | "phpunit/phpunit": "^9.5",
26 | "squizlabs/php_codesniffer": "^3.7"
27 | },
28 | "replace": {
29 | "triplepoint/php-units-of-measure": "*"
30 | },
31 | "autoload": {
32 | "psr-4": {
33 | "PhpUnitsOfMeasure\\": "source/"
34 | }
35 | },
36 | "autoload-dev": {
37 | "psr-4": {
38 | "PhpUnitsOfMeasureTest\\": "tests/"
39 | }
40 | },
41 | "scripts": {
42 | "test": "phpunit -c ./tests/phpunit.xml.dist ./tests",
43 | "lint": "phpcs --encoding=utf-8 --extensions=php --standard=./tests/phpcs.xml -nsp ./"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/scripts/lint:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | docker build -t "php-units-of-measure:dev" .
5 | docker run -it --rm -v `pwd`:/project "php-units-of-measure:dev" composer run-script lint
6 |
--------------------------------------------------------------------------------
/scripts/shell:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | docker build -t "php-units-of-measure:dev" .
5 | docker run -it --rm -v `pwd`:/project "php-units-of-measure:dev" bash
6 |
--------------------------------------------------------------------------------
/scripts/test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | docker build -t "php-units-of-measure:dev" .
5 | docker run -it --rm -v `pwd`:/project "php-units-of-measure:dev" composer run-script test
6 |
--------------------------------------------------------------------------------
/source/AbstractPhysicalQuantity.php:
--------------------------------------------------------------------------------
1 | implode(', ', array_merge([$unit->getName()], $unit->getAliases()))
44 | ]);
45 | }
46 |
47 | static::$unitDefinitions[] = $unit;
48 | }
49 |
50 | /**
51 | * Get the unit of measure that matches the given name by either name or alias.
52 | *
53 | * @param string $unit A name or alias by which the unit is known.
54 | *
55 | * @throws Exception\UnknownUnitOfMeasure when an unknown unit of measure is given
56 | *
57 | * @return UnitOfMeasureInterface
58 | */
59 | public static function getUnit($unit)
60 | {
61 | // If this class hasn't been initialized yet, do so now
62 | if (!is_array(static::$unitDefinitions)) {
63 | static::$unitDefinitions = [];
64 | static::initialize();
65 | }
66 |
67 | $key = static::buildUnitCacheKey($unit);
68 | if (isset(self::$unitCache[$key])) {
69 | return self::$unitCache[$key];
70 | }
71 |
72 | foreach (static::$unitDefinitions as $unitOfMeasure) {
73 | if ($unit === $unitOfMeasure->getName() || $unitOfMeasure->isAliasOf($unit)) {
74 | return self::$unitCache[$key] = $unitOfMeasure;
75 | }
76 | }
77 |
78 | throw new Exception\UnknownUnitOfMeasure([':unit' => $unit]);
79 | }
80 |
81 | /**
82 | * Given a unit of measure, determine if its name or any of its aliases conflict
83 | * with the set of already-known unit names and aliases.
84 | *
85 | * @param UnitOfMeasureInterface $unit The unit in question
86 | *
87 | * @return boolean true if there is a conflict, false if there is not
88 | */
89 | protected static function unitNameOrAliasesAlreadyRegistered(UnitOfMeasureInterface $unit)
90 | {
91 | // If this class hasn't been initialized yet, do so now
92 | if (!is_array(static::$unitDefinitions)) {
93 | static::$unitDefinitions = [];
94 | static::initialize();
95 | }
96 |
97 | $currentUnitNamesAndAliases = [];
98 | foreach (static::$unitDefinitions as $unitOfMeasure) {
99 | $currentUnitNamesAndAliases[] = $unitOfMeasure->getName();
100 | $currentUnitNamesAndAliases = array_merge($currentUnitNamesAndAliases, $unitOfMeasure->getAliases());
101 | }
102 |
103 | $newUnitNamesAndAliases = array_merge([$unit->getName()], $unit->getAliases());
104 |
105 | return count(array_intersect($currentUnitNamesAndAliases, $newUnitNamesAndAliases)) > 0;
106 | }
107 |
108 | /**
109 | * Initialize the static properties of this quantity class, such as the set of
110 | * default units of measure.
111 | */
112 | protected static function initialize()
113 | {
114 | }
115 |
116 |
117 | /**
118 | * The scalar value, in the original unit of measure.
119 | *
120 | * @var float
121 | */
122 | protected $originalValue;
123 |
124 | /**
125 | * The original unit of measure's string representation.
126 | *
127 | * @var string
128 | */
129 | protected $originalUnit;
130 |
131 | /**
132 | * Store the value and its original unit.
133 | *
134 | * @param float $value The scalar value of the measurement
135 | * @param string $unit The unit of measure in which this value is provided
136 | *
137 | * @throws Exception\NonNumericValue If the value is not numeric
138 | * @throws Exception\NonStringUnitName If the unit is not a string
139 | */
140 | public function __construct($value, $unit)
141 | {
142 | if (!is_numeric($value)) {
143 | throw new Exception\NonNumericValue([':value' => $value]);
144 | }
145 |
146 | if (!is_string($unit)) {
147 | throw new Exception\NonStringUnitName([':name' => $unit]);
148 | }
149 |
150 | $this->originalValue = $value;
151 | $this->originalUnit = $unit;
152 | }
153 |
154 | /**
155 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::toUnit
156 | */
157 | public function toUnit($toUnit)
158 | {
159 | return $this->toUnitOfMeasure(static::getUnit($toUnit));
160 | }
161 |
162 | /**
163 | * Convert this quantity to the given unit of measure.
164 | *
165 | * @param UnitOfMeasureInterface $unit The object representing the target unit of measure.
166 | *
167 | * @return float This quantity's value in the given unit of measure.
168 | */
169 | private function toUnitOfMeasure(UnitOfMeasureInterface $unit)
170 | {
171 | $thisValueInNativeUnit = $this->toNativeUnit();
172 | return $unit->convertValueFromNativeUnitOfMeasure($thisValueInNativeUnit);
173 | }
174 |
175 | /**
176 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::toNativeUnit
177 | */
178 | public function toNativeUnit()
179 | {
180 | return static::getUnit($this->originalUnit)
181 | ->convertValueToNativeUnitOfMeasure($this->originalValue);
182 | }
183 |
184 | /**
185 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::__toString
186 | */
187 | public function __toString()
188 | {
189 | return trim($this->originalValue . ' ' . static::getUnit($this->originalUnit)->getName());
190 | }
191 |
192 | /**
193 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::add
194 | */
195 | public function add(PhysicalQuantityInterface $quantity)
196 | {
197 | if (!$this->isEquivalentQuantity($quantity)) {
198 | throw new Exception\PhysicalQuantityMismatch([
199 | ':lhs' => (string) $this,
200 | ':rhs' => (string) $quantity
201 | ]);
202 | }
203 |
204 | $quantityValueInThisOriginalUnit = $quantity->toUnitOfMeasure(static::getUnit($this->originalUnit));
205 | $newValue = $this->originalValue + $quantityValueInThisOriginalUnit;
206 |
207 | return new static($newValue, static::getUnit($this->originalUnit)->getName());
208 | }
209 |
210 | /**
211 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::subtract
212 | */
213 | public function subtract(PhysicalQuantityInterface $quantity)
214 | {
215 | if (!$this->isEquivalentQuantity($quantity)) {
216 | throw new Exception\PhysicalQuantityMismatch([
217 | ':lhs' => (string) $this,
218 | ':rhs' => (string) $quantity
219 | ]);
220 | }
221 |
222 | $quantityValueInThisOriginalUnit = $quantity->toUnitOfMeasure(static::getUnit($this->originalUnit));
223 | $newValue = $this->originalValue - $quantityValueInThisOriginalUnit;
224 |
225 | return new static($newValue, static::getUnit($this->originalUnit)->getName());
226 | }
227 |
228 | /**
229 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::isEquivalentQuantity
230 | */
231 | public function isEquivalentQuantity(PhysicalQuantityInterface $testQuantity)
232 | {
233 | return get_class($this) === get_class($testQuantity);
234 | }
235 |
236 | /**
237 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::isUnitDefined
238 | */
239 | public static function isUnitDefined($name)
240 | {
241 | $units = static::getUnitDefinitions();
242 | foreach ($units as $unit) {
243 | if ($name === $unit->getName() || $unit->isAliasOf($name)) {
244 | return true;
245 | }
246 | }
247 | return false;
248 | }
249 |
250 | /**
251 | * @see \PhpUnitsOfMeasure\PhysicalQuantityInterface::listAllUnits
252 | */
253 | public static function listAllUnits()
254 | {
255 | $return = [];
256 | $units = static::getUnitDefinitions();
257 | foreach ($units as $unit) {
258 | $return[$unit->getName()] = $unit->getAliases();
259 | }
260 | return $return;
261 | }
262 |
263 | /**
264 | * Get the unit definition array
265 | * @return Array $unitDefinitions
266 | */
267 | public static function getUnitDefinitions()
268 | {
269 | if (!is_array(static::$unitDefinitions)) {
270 | static::$unitDefinitions = [];
271 | static::initialize();
272 | }
273 |
274 | return static::$unitDefinitions;
275 | }
276 |
277 | /**
278 | * @return float
279 | */
280 | public function getOriginalValue()
281 | {
282 | return $this->originalValue;
283 | }
284 |
285 | /**
286 | * @return string
287 | */
288 | public function getOriginalUnit()
289 | {
290 | return $this->originalUnit;
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
/source/Exception/AbstractPhysicalQuantityException.php:
--------------------------------------------------------------------------------
1 | error, $parameters);
24 | parent::__construct($message);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/source/Exception/DuplicateUnitNameOrAlias.php:
--------------------------------------------------------------------------------
1 | 'Y',
52 | 'long_prefix' => 'yotta',
53 | 'factor' => 1e24
54 | ],
55 | [
56 | 'abbr_prefix' => 'Z',
57 | 'long_prefix' => 'zetta',
58 | 'factor' => 1e21
59 | ],
60 | [
61 | 'abbr_prefix' => 'E',
62 | 'long_prefix' => 'exa',
63 | 'factor' => 1e18
64 | ],
65 | [
66 | 'abbr_prefix' => 'P',
67 | 'long_prefix' => 'peta',
68 | 'factor' => 1e15
69 | ],
70 | [
71 | 'abbr_prefix' => 'T',
72 | 'long_prefix' => 'tera',
73 | 'factor' => 1e12
74 | ],
75 | [
76 | 'abbr_prefix' => 'G',
77 | 'long_prefix' => 'giga',
78 | 'factor' => 1e9
79 | ],
80 | [
81 | 'abbr_prefix' => 'M',
82 | 'long_prefix' => 'mega',
83 | 'factor' => 1e6
84 | ],
85 | [
86 | 'abbr_prefix' => 'k',
87 | 'long_prefix' => 'kilo',
88 | 'factor' => 1e3
89 | ],
90 | [
91 | 'abbr_prefix' => 'h',
92 | 'long_prefix' => 'hecto',
93 | 'factor' => 1e2
94 | ],
95 | [
96 | 'abbr_prefix' => 'da',
97 | 'long_prefix' => 'deca',
98 | 'factor' => 1e1
99 | ],
100 | [
101 | 'abbr_prefix' => '',
102 | 'long_prefix' => '',
103 | 'factor' => 1
104 | ],
105 | [
106 | 'abbr_prefix' => 'd',
107 | 'long_prefix' => 'deci',
108 | 'factor' => 1e-1
109 | ],
110 | [
111 | 'abbr_prefix' => 'c',
112 | 'long_prefix' => 'centi',
113 | 'factor' => 1e-2
114 | ],
115 | [
116 | 'abbr_prefix' => 'm',
117 | 'long_prefix' => 'milli',
118 | 'factor' => 1e-3
119 | ],
120 | [
121 | 'abbr_prefix' => 'µ',
122 | 'long_prefix' => 'micro',
123 | 'factor' => 1e-6
124 | ],
125 | [
126 | 'abbr_prefix' => 'n',
127 | 'long_prefix' => 'nano',
128 | 'factor' => 1e-9
129 | ],
130 | [
131 | 'abbr_prefix' => 'p',
132 | 'long_prefix' => 'pico',
133 | 'factor' => 1e-12
134 | ],
135 | [
136 | 'abbr_prefix' => 'f',
137 | 'long_prefix' => 'femto',
138 | 'factor' => 1e-15
139 | ],
140 | [
141 | 'abbr_prefix' => 'a',
142 | 'long_prefix' => 'atto',
143 | 'factor' => 1e-18
144 | ],
145 | [
146 | 'abbr_prefix' => 'z',
147 | 'long_prefix' => 'zepto',
148 | 'factor' => 1e-21
149 | ],
150 | [
151 | 'abbr_prefix' => 'y',
152 | 'long_prefix' => 'yocto',
153 | 'factor' => 1e-24
154 | ],
155 | ];
156 |
157 | // Determine the conversion factor from the no-prefix SI unit to the physical quantity's native unit
158 | $noPrefixToNativeUnitFactor = $siUnit->convertValueToNativeUnitOfMeasure(1) * $toBaseSiUnitFactor;
159 |
160 | // For each of the standard SI prefixes, attempt to register a new unit of measure
161 | foreach ($siPrefixes as $prefixDefinition) {
162 | // Build a function for resolving a pattern into a unit name
163 | $parsePattern = function ($pattern) use ($prefixDefinition) {
164 | return strtr(
165 | $pattern,
166 | [
167 | '%p' => $prefixDefinition['abbr_prefix'],
168 | '%P' => $prefixDefinition['long_prefix'],
169 | '%U' => strtoupper($prefixDefinition['long_prefix'])
170 | ]
171 | );
172 | };
173 |
174 | // Generate the base name of the new unit
175 | $name = $parsePattern($namePattern);
176 |
177 | // Determine the factor that converts the new unit into the physical quantity's
178 | // native unit of measure.
179 | $toNativeUnitFactor = $noPrefixToNativeUnitFactor * $prefixDefinition['factor'];
180 |
181 | // Instantiate the new unit of measure
182 | $newUnit = UnitOfMeasure::linearUnitFactory($name, $toNativeUnitFactor);
183 |
184 | // Generate the aliases of the new unit
185 | foreach ($aliasPatterns as $aliasPattern) {
186 | $newUnitAlias = $parsePattern($aliasPattern);
187 | $newUnit->addAlias($newUnitAlias);
188 | }
189 |
190 | // If the unit doesn't conflict with any of the already-existing units, register it
191 | if (!static::unitNameOrAliasesAlreadyRegistered($newUnit)) {
192 | static::addUnit($newUnit);
193 | }
194 | }
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Acceleration.php:
--------------------------------------------------------------------------------
1 | addAlias('m/s²');
16 | $meterpersecondsquared->addAlias('meter per second squared');
17 | $meterpersecondsquared->addAlias('meters per second squared');
18 | $meterpersecondsquared->addAlias('metre per second squared');
19 | $meterpersecondsquared->addAlias('metres per second squared');
20 | static::addUnit($meterpersecondsquared);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Angle.php:
--------------------------------------------------------------------------------
1 | addAlias('radian');
19 | $radian->addAlias('radians');
20 | static::addUnit($radian);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $radian,
24 | 1,
25 | '%prad',
26 | [
27 | '%Pradian',
28 | '%Pradians',
29 | ]
30 | );
31 |
32 | // Degrees
33 | $degree = UnitOfMeasure::linearUnitFactory('deg', M_PI / 180);
34 | $degree->addAlias('°');
35 | $degree->addAlias('degree');
36 | $degree->addAlias('degrees');
37 | static::addUnit($degree);
38 |
39 | static::addMissingSIPrefixedUnits(
40 | $degree,
41 | 1,
42 | '%pdeg',
43 | [
44 | '%Pdegree',
45 | '%Pdegrees',
46 | ]
47 | );
48 |
49 | // Arcminute
50 | $arcminute = UnitOfMeasure::linearUnitFactory('arcmin', M_PI / 180 / 60);
51 | $arcminute->addAlias('′');
52 | $arcminute->addAlias('arcminute');
53 | $arcminute->addAlias('arcminutes');
54 | $arcminute->addAlias('amin');
55 | $arcminute->addAlias('am');
56 | $arcminute->addAlias('MOA');
57 | static::addUnit($arcminute);
58 |
59 | // Arcsecond
60 | $arcsecond = UnitOfMeasure::linearUnitFactory('arcsec', M_PI / 180 / 3600);
61 | $arcsecond->addAlias('″');
62 | $arcminute->addAlias('arcsecond');
63 | $arcminute->addAlias('arcseconds');
64 | $arcsecond->addAlias('asec');
65 | $arcsecond->addAlias('as');
66 | static::addUnit($arcsecond);
67 |
68 | static::addMissingSIPrefixedUnits(
69 | $arcsecond,
70 | 1,
71 | '%Parcsec',
72 | [
73 | '%Parcsecond',
74 | '%Parcseconds',
75 | '%pasec',
76 | '%pas',
77 | ]
78 | );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Area.php:
--------------------------------------------------------------------------------
1 | addAlias('m²');
16 | $metersquared->addAlias('meter squared');
17 | $metersquared->addAlias('square meter');
18 | $metersquared->addAlias('square meters');
19 | $metersquared->addAlias('meters squared');
20 | $metersquared->addAlias('metre squared');
21 | $metersquared->addAlias('metres squared');
22 | static::addUnit($metersquared);
23 |
24 | // Millimeter squared
25 | $newUnit = UnitOfMeasure::linearUnitFactory('mm^2', 1e-6);
26 | $newUnit->addAlias('mm²');
27 | $newUnit->addAlias('millimeter squared');
28 | $newUnit->addAlias('square millimeter');
29 | $newUnit->addAlias('square millimeters');
30 | $newUnit->addAlias('millimeters squared');
31 | $newUnit->addAlias('millimetre squared');
32 | $newUnit->addAlias('millimetres squared');
33 | static::addUnit($newUnit);
34 |
35 | // Centimeter squared
36 | $newUnit = UnitOfMeasure::linearUnitFactory('cm^2', 1e-4);
37 | $newUnit->addAlias('cm²');
38 | $newUnit->addAlias('centimeter squared');
39 | $newUnit->addAlias('square centimeter');
40 | $newUnit->addAlias('square centimeters');
41 | $newUnit->addAlias('centimeters squared');
42 | $newUnit->addAlias('centimetre squared');
43 | $newUnit->addAlias('centimetres squared');
44 | static::addUnit($newUnit);
45 |
46 | // Decimeter squared
47 | $newUnit = UnitOfMeasure::linearUnitFactory('dm^2', 1e-2);
48 | $newUnit->addAlias('dm²');
49 | $newUnit->addAlias('decimeter squared');
50 | $newUnit->addAlias('square decimeters');
51 | $newUnit->addAlias('square decimeter');
52 | $newUnit->addAlias('decimeters squared');
53 | $newUnit->addAlias('decimetre squared');
54 | $newUnit->addAlias('decimetres squared');
55 | static::addUnit($newUnit);
56 |
57 | // Kilometer squared
58 | $newUnit = UnitOfMeasure::linearUnitFactory('km^2', 1e6);
59 | $newUnit->addAlias('km²');
60 | $newUnit->addAlias('kilometer squared');
61 | $newUnit->addAlias('kilometers squared');
62 | $newUnit->addAlias('square kilometer');
63 | $newUnit->addAlias('square kilometers');
64 | $newUnit->addAlias('kilometre squared');
65 | $newUnit->addAlias('kilometres squared');
66 | static::addUnit($newUnit);
67 |
68 | // Foot squared
69 | $newUnit = UnitOfMeasure::linearUnitFactory('ft^2', 9.290304e-2);
70 | $newUnit->addAlias('ft²');
71 | $newUnit->addAlias('foot squared');
72 | $newUnit->addAlias('square foot');
73 | $newUnit->addAlias('square feet');
74 | $newUnit->addAlias('feet squared');
75 | static::addUnit($newUnit);
76 |
77 | // Inch squared
78 | $newUnit = UnitOfMeasure::linearUnitFactory('in^2', 6.4516e-4);
79 | $newUnit->addAlias('in²');
80 | $newUnit->addAlias('inch squared');
81 | $newUnit->addAlias('square inch');
82 | $newUnit->addAlias('square inches');
83 | $newUnit->addAlias('inches squared');
84 | static::addUnit($newUnit);
85 |
86 | // Mile squared
87 | $newUnit = UnitOfMeasure::linearUnitFactory('mi^2', 2.589988e6);
88 | $newUnit->addAlias('mi²');
89 | $newUnit->addAlias('mile squared');
90 | $newUnit->addAlias('miles squared');
91 | $newUnit->addAlias('square mile');
92 | $newUnit->addAlias('square miles');
93 | static::addUnit($newUnit);
94 |
95 | // Yard squared
96 | $newUnit = UnitOfMeasure::linearUnitFactory('yd^2', 8.361274e-1);
97 | $newUnit->addAlias('yd²');
98 | $newUnit->addAlias('yard squared');
99 | $newUnit->addAlias('yards squared');
100 | $newUnit->addAlias('square yard');
101 | $newUnit->addAlias('square yards');
102 | static::addUnit($newUnit);
103 |
104 | // Are
105 | $newUnit = UnitOfMeasure::linearUnitFactory('a', 100);
106 | $newUnit->addAlias('are');
107 | $newUnit->addAlias('ares');
108 | static::addUnit($newUnit);
109 |
110 | // Decare
111 | $newUnit = UnitOfMeasure::linearUnitFactory('daa', 1000);
112 | $newUnit->addAlias('decare');
113 | $newUnit->addAlias('decares');
114 | static::addUnit($newUnit);
115 |
116 | // Hectare
117 | $newUnit = UnitOfMeasure::linearUnitFactory('ha', 10000);
118 | $newUnit->addAlias('hectare');
119 | $newUnit->addAlias('hectares');
120 | static::addUnit($newUnit);
121 |
122 | // International Acre
123 | $newUnit = UnitOfMeasure::linearUnitFactory('ac', 4046.8564224);
124 | $newUnit->addAlias('acre');
125 | $newUnit->addAlias('acres');
126 | static::addUnit($newUnit);
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/ElectricCurrent.php:
--------------------------------------------------------------------------------
1 | addAlias('amp');
19 | $ampere->addAlias('amps');
20 | $ampere->addAlias('ampere');
21 | $ampere->addAlias('amperes');
22 | static::addUnit($ampere);
23 |
24 | static::addMissingSIPrefixedUnits(
25 | $ampere,
26 | 1,
27 | '%pA',
28 | [
29 | '%Pamp',
30 | '%Pamps',
31 | '%Pampere',
32 | '%Pamperes'
33 | ]
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Energy.php:
--------------------------------------------------------------------------------
1 | addAlias('joule');
19 | $joule->addAlias('joules');
20 | static::addUnit($joule);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $joule,
24 | 1,
25 | '%pJ',
26 | [
27 | '%Pjoule',
28 | '%Pjoules',
29 | ]
30 | );
31 |
32 | // Watt hour
33 | $wattHour = UnitOfMeasure::linearUnitFactory('Wh', 3600);
34 | $wattHour->addAlias('watt hour');
35 | $wattHour->addAlias('watt hours');
36 | static::addUnit($wattHour);
37 |
38 | static::addMissingSIPrefixedUnits(
39 | $wattHour,
40 | 1,
41 | '%pWh',
42 | [
43 | '%Pwatt hour',
44 | '%Pwatt hours',
45 | ]
46 | );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Length.php:
--------------------------------------------------------------------------------
1 | addAlias('meter');
19 | $meter->addAlias('meters');
20 | $meter->addAlias('metre');
21 | $meter->addAlias('metres');
22 | static::addUnit($meter);
23 |
24 | static::addMissingSIPrefixedUnits(
25 | $meter,
26 | 1,
27 | '%pm',
28 | [
29 | '%Pmeter',
30 | '%Pmeters',
31 | '%Pmetre',
32 | '%Pmetres'
33 | ]
34 | );
35 |
36 | // Foot
37 | $newUnit = UnitOfMeasure::linearUnitFactory('ft', 0.3048);
38 | $newUnit->addAlias('foot');
39 | $newUnit->addAlias('feet');
40 | static::addUnit($newUnit);
41 |
42 | // Inch
43 | $newUnit = UnitOfMeasure::linearUnitFactory('in', 0.0254);
44 | $newUnit->addAlias('inch');
45 | $newUnit->addAlias('inches');
46 | static::addUnit($newUnit);
47 |
48 | // Mile
49 | $newUnit = UnitOfMeasure::linearUnitFactory('mi', 1609.344);
50 | $newUnit->addAlias('mile');
51 | $newUnit->addAlias('miles');
52 | static::addUnit($newUnit);
53 |
54 | // Yard
55 | $newUnit = UnitOfMeasure::linearUnitFactory('yd', 0.9144);
56 | $newUnit->addAlias('yard');
57 | $newUnit->addAlias('yards');
58 | static::addUnit($newUnit);
59 |
60 | // Nautical mile
61 | $newUnit = UnitOfMeasure::linearUnitFactory('M', 1852);
62 | $newUnit->addAlias('nautical mile');
63 | $newUnit->addAlias('nautical miles');
64 | $newUnit->addAlias('nmi');
65 | $newUnit->addAlias('NM');
66 | static::addUnit($newUnit);
67 |
68 | // Scandinavian mil
69 | $newUnit = UnitOfMeasure::linearUnitFactory('mil', 10000);
70 | static::addUnit($newUnit);
71 |
72 | // Astronomical Unit
73 | $newUnit = UnitOfMeasure::linearUnitFactory('AU', 149597870700);
74 | $newUnit->addAlias('au');
75 | $newUnit->addAlias('astronomical unit');
76 | $newUnit->addAlias('astronomical units');
77 | static::addUnit($newUnit);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/LuminousIntensity.php:
--------------------------------------------------------------------------------
1 | addAlias('candela');
19 | static::addUnit($candela);
20 |
21 | static::addMissingSIPrefixedUnits(
22 | $candela,
23 | 1,
24 | '%pcd',
25 | [
26 | '%Pcandela',
27 | ]
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Mass.php:
--------------------------------------------------------------------------------
1 | addAlias('kilogram');
19 | $kilogram->addAlias('kilograms');
20 | static::addUnit($kilogram);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $kilogram,
24 | 1e-3,
25 | '%pg',
26 | [
27 | '%Pgram',
28 | '%Pgrams',
29 | ]
30 | );
31 |
32 | // Tonne (metric)
33 | $newUnit = UnitOfMeasure::linearUnitFactory('t', 1e3);
34 | $newUnit->addAlias('ton');
35 | $newUnit->addAlias('tons');
36 | $newUnit->addAlias('tonne');
37 | $newUnit->addAlias('tonnes');
38 | static::addUnit($newUnit);
39 |
40 | // Pound
41 | $newUnit = UnitOfMeasure::linearUnitFactory('lb', 4.5359237e-1);
42 | $newUnit->addAlias('lbs');
43 | $newUnit->addAlias('pound');
44 | $newUnit->addAlias('pounds');
45 | static::addUnit($newUnit);
46 |
47 | // Ounce
48 | $newUnit = UnitOfMeasure::linearUnitFactory('oz', 4.5359237e-1 / 16);
49 | $newUnit->addAlias('ounce');
50 | $newUnit->addAlias('ounces');
51 | static::addUnit($newUnit);
52 |
53 | // Stone
54 | $newUnit = UnitOfMeasure::linearUnitFactory('st', 4.5359237e-1 * 14);
55 | $newUnit->addAlias('stone');
56 | $newUnit->addAlias('stones');
57 | static::addUnit($newUnit);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Power.php:
--------------------------------------------------------------------------------
1 | addAlias('watt');
19 | $watt->addAlias('watts');
20 | static::addUnit($watt);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $watt,
24 | 1,
25 | '%pW',
26 | [
27 | '%Pwatt',
28 | '%Pwatts',
29 | ]
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Pressure.php:
--------------------------------------------------------------------------------
1 | addAlias('pascal');
19 | static::addUnit($pascal);
20 |
21 | static::addMissingSIPrefixedUnits(
22 | $pascal,
23 | 1,
24 | '%pPa',
25 | [
26 | '%Ppascal',
27 | ]
28 | );
29 |
30 | // Atmosphere
31 | $newUnit = UnitOfMeasure::linearUnitFactory('atm', 101325);
32 | $newUnit->addAlias('atmosphere');
33 | $newUnit->addAlias('atmospheres');
34 | static::addUnit($newUnit);
35 |
36 | // Bar
37 | $bar = UnitOfMeasure::linearUnitFactory('bar', 1e5);
38 | static::addUnit($bar);
39 |
40 | static::addMissingSIPrefixedUnits(
41 | $bar,
42 | 1,
43 | '%pbar'
44 | );
45 |
46 | // Inch of Mercury
47 | $newUnit = UnitOfMeasure::linearUnitFactory('inHg', 3.386389e3);
48 | $newUnit->addAlias('inches of mercury');
49 | static::addUnit($newUnit);
50 |
51 | // Millimeter of Mercury
52 | $newUnit = UnitOfMeasure::linearUnitFactory('mmHg', 133.3224);
53 | $newUnit->addAlias('millimeters of mercury');
54 | $newUnit->addAlias('millimetres of mercury');
55 | $newUnit->addAlias('torr');
56 | static::addUnit($newUnit);
57 |
58 | // Pound per Square Inch
59 | $newUnit = UnitOfMeasure::linearUnitFactory('psi', 6.894757e3);
60 | $newUnit->addAlias('pounds per square inch');
61 | static::addUnit($newUnit);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Quantity.php:
--------------------------------------------------------------------------------
1 | addAlias('mole');
19 | $mole->addAlias('moles');
20 | static::addUnit($mole);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $mole,
24 | 1,
25 | '%pmol',
26 | [
27 | '%Pmole',
28 | '%Pmoles',
29 | ]
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/SolidAngle.php:
--------------------------------------------------------------------------------
1 | addAlias('steradian');
19 | $steradian->addAlias('steradians');
20 | static::addUnit($steradian);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $steradian,
24 | 1,
25 | '%psr',
26 | [
27 | '%Psteradian',
28 | '%Psteradians',
29 | ]
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Temperature.php:
--------------------------------------------------------------------------------
1 | addAlias('°K');
19 | $kelvin->addAlias('kelvin');
20 | static::addUnit($kelvin);
21 |
22 | static::addMissingSIPrefixedUnits(
23 | $kelvin,
24 | 1,
25 | '%pK',
26 | [
27 | '%Pkelvin',
28 | ]
29 | );
30 |
31 | // Degree Celsius
32 | $newUnit = new UnitOfMeasure(
33 | '°C',
34 | function ($x) {
35 | return $x - 273.15;
36 | },
37 | function ($x) {
38 | return $x + 273.15;
39 | }
40 | );
41 | $newUnit->addAlias('C');
42 | $newUnit->addAlias('celsius');
43 | static::addUnit($newUnit);
44 |
45 | // Degree Fahrenheit
46 | $newUnit = new UnitOfMeasure(
47 | '°F',
48 | function ($x) {
49 | return ($x * 9 / 5) - 459.67;
50 | },
51 | function ($x) {
52 | return ($x + 459.67) * 5/9;
53 | }
54 | );
55 | $newUnit->addAlias('F');
56 | $newUnit->addAlias('fahrenheit');
57 | static::addUnit($newUnit);
58 |
59 | // Degree Rankine
60 | $newUnit = UnitOfMeasure::linearUnitFactory('°R', 5/9);
61 | $newUnit->addAlias('R');
62 | $newUnit->addAlias('rankine');
63 | static::addUnit($newUnit);
64 |
65 | // Degree Delisle
66 | $newUnit = new UnitOfMeasure(
67 | '°De',
68 | function ($x) {
69 | return (373.15 - $x) * 3/2;
70 | },
71 | function ($x) {
72 | return 373.15 - $x * 2/3;
73 | }
74 | );
75 | $newUnit->addAlias('De');
76 | $newUnit->addAlias('delisle');
77 | static::addUnit($newUnit);
78 |
79 | // Degree Newton
80 | $newUnit = new UnitOfMeasure(
81 | '°N',
82 | function ($x) {
83 | return ($x - 273.15) * 33/100;
84 | },
85 | function ($x) {
86 | return $x * 100/33 + 273.15;
87 | }
88 | );
89 | $newUnit->addAlias('N');
90 | $newUnit->addAlias('newton');
91 | static::addUnit($newUnit);
92 |
93 | // Degree Réaumur
94 | $newUnit = new UnitOfMeasure(
95 | '°Ré',
96 | function ($x) {
97 | return ($x - 273.15) * 4/5;
98 | },
99 | function ($x) {
100 | return $x * 5/4 + 273.15;
101 | }
102 | );
103 | $newUnit->addAlias('°Re');
104 | $newUnit->addAlias('Ré');
105 | $newUnit->addAlias('Re');
106 | $newUnit->addAlias('réaumur');
107 | $newUnit->addAlias('reaumur');
108 | static::addUnit($newUnit);
109 |
110 | // Degree Rømer
111 | $newUnit = new UnitOfMeasure(
112 | '°Rø',
113 | function ($x) {
114 | return ($x - 273.15) * 21/40 + 7.5;
115 | },
116 | function ($x) {
117 | return ($x - 7.5) * 40/21 + 273.15;
118 | }
119 | );
120 | $newUnit->addAlias('°Ro');
121 | $newUnit->addAlias('Rø');
122 | $newUnit->addAlias('Ro');
123 | $newUnit->addAlias('rømer');
124 | $newUnit->addAlias('romer');
125 | static::addUnit($newUnit);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Time.php:
--------------------------------------------------------------------------------
1 | addAlias('sec');
19 | $second->addAlias('secs');
20 | $second->addAlias('second');
21 | $second->addAlias('seconds');
22 | static::addUnit($second);
23 |
24 | static::addMissingSIPrefixedUnits(
25 | $second,
26 | 1,
27 | '%ps',
28 | [
29 | '%Psec',
30 | '%Psecs',
31 | '%Psecond',
32 | '%Pseconds'
33 | ]
34 | );
35 |
36 | // Minutes
37 | $newUnit = UnitOfMeasure::linearUnitFactory('m', 60);
38 | $newUnit->addAlias('min');
39 | $newUnit->addAlias('mins');
40 | $newUnit->addAlias('minute');
41 | $newUnit->addAlias('minutes');
42 | static::addUnit($newUnit);
43 |
44 | // Hours
45 | $newUnit = UnitOfMeasure::linearUnitFactory('h', 3600);
46 | $newUnit->addAlias('hr');
47 | $newUnit->addAlias('hrs');
48 | $newUnit->addAlias('hour');
49 | $newUnit->addAlias('hours');
50 | static::addUnit($newUnit);
51 |
52 | // Days
53 | $newUnit = UnitOfMeasure::linearUnitFactory('d', 86400);
54 | $newUnit->addAlias('day');
55 | $newUnit->addAlias('days');
56 | static::addUnit($newUnit);
57 |
58 | // Weeks, understood as 7 days
59 | $newUnit = UnitOfMeasure::linearUnitFactory('w', 604800);
60 | $newUnit->addAlias('wk');
61 | $newUnit->addAlias('wks');
62 | $newUnit->addAlias('week');
63 | $newUnit->addAlias('weeks');
64 | static::addUnit($newUnit);
65 |
66 | // Gregorian year, understood as 365.2425 days
67 | $newUnit = UnitOfMeasure::linearUnitFactory('yr', 31556952);
68 | $newUnit->addAlias('year');
69 | $newUnit->addAlias('years');
70 | $newUnit->addAlias('gregorian year');
71 | $newUnit->addAlias('gregorian years');
72 | static::addUnit($newUnit);
73 |
74 | // Decade
75 | $newUnit = UnitOfMeasure::linearUnitFactory('decade', 315569520);
76 | $newUnit->addAlias('decades');
77 | static::addUnit($newUnit);
78 |
79 | // Century
80 | $newUnit = UnitOfMeasure::linearUnitFactory('century', 3155695200);
81 | $newUnit->addAlias('centuries');
82 | static::addUnit($newUnit);
83 |
84 | // Millennium
85 | $newUnit = UnitOfMeasure::linearUnitFactory('millennium', 31556952000);
86 | $newUnit->addAlias('millennia');
87 | static::addUnit($newUnit);
88 |
89 | // Julian year, understood as 365.25 days
90 | $newUnit = UnitOfMeasure::linearUnitFactory('jyr', 31557600);
91 | $newUnit->addAlias('julian year');
92 | $newUnit->addAlias('julian years');
93 | static::addUnit($newUnit);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Velocity.php:
--------------------------------------------------------------------------------
1 | addAlias('meters/sec');
16 | $meterpersecond->addAlias('meters per second');
17 | $meterpersecond->addAlias('meter per second');
18 | $meterpersecond->addAlias('metres per second');
19 | $meterpersecond->addAlias('metre per second');
20 | static::addUnit($meterpersecond);
21 |
22 | // kilometers per hour
23 | $newUnit = UnitOfMeasure::linearUnitFactory('km/h', 0.277778);
24 | $newUnit->addAlias('km/hour');
25 | $newUnit->addAlias('kilometer per hour');
26 | $newUnit->addAlias('kilometers per hour');
27 | $newUnit->addAlias('kilometre per hour');
28 | $newUnit->addAlias('kilometres per hour');
29 | static::addUnit($newUnit);
30 |
31 | // feet per second
32 | $newUnit = UnitOfMeasure::linearUnitFactory('ft/s', 0.3048);
33 | $newUnit->addAlias('feet/sec');
34 | $newUnit->addAlias('feet per second');
35 | static::addUnit($newUnit);
36 |
37 | // miles per hour
38 | $newUnit = UnitOfMeasure::linearUnitFactory('mph', 0.44704);
39 | $newUnit->addAlias('miles/hour');
40 | $newUnit->addAlias('miles per hour');
41 | static::addUnit($newUnit);
42 |
43 | // knot
44 | $newUnit = UnitOfMeasure::linearUnitFactory('knot', 0.514444);
45 | $newUnit->addAlias('knots');
46 | static::addUnit($newUnit);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/source/PhysicalQuantity/Volume.php:
--------------------------------------------------------------------------------
1 | addAlias('m³');
16 | $cubicmeter->addAlias('cubic meter');
17 | $cubicmeter->addAlias('cubic meters');
18 | $cubicmeter->addAlias('cubic metre');
19 | $cubicmeter->addAlias('cubic metres');
20 | static::addUnit($cubicmeter);
21 |
22 | // Cubic millimeter
23 | $newUnit = UnitOfMeasure::linearUnitFactory('mm^3', 1e-9);
24 | $newUnit->addAlias('mm³');
25 | $newUnit->addAlias('cubic millimeter');
26 | $newUnit->addAlias('cubic millimeters');
27 | $newUnit->addAlias('cubic millimetre');
28 | $newUnit->addAlias('cubic millimetres');
29 | static::addUnit($newUnit);
30 |
31 | // Cubic centimeter
32 | $newUnit = UnitOfMeasure::linearUnitFactory('cm^3', 1e-6);
33 | $newUnit->addAlias('cm³');
34 | $newUnit->addAlias('cubic centimeter');
35 | $newUnit->addAlias('cubic centimeters');
36 | $newUnit->addAlias('cubic centimetre');
37 | $newUnit->addAlias('cubic centimetres');
38 | static::addUnit($newUnit);
39 |
40 | // Cubic decimeter
41 | $newUnit = UnitOfMeasure::linearUnitFactory('dm^3', 1e-3);
42 | $newUnit->addAlias('dm³');
43 | $newUnit->addAlias('cubic decimeter');
44 | $newUnit->addAlias('cubic decimeters');
45 | $newUnit->addAlias('cubic decimetre');
46 | $newUnit->addAlias('cubic decimetres');
47 | static::addUnit($newUnit);
48 |
49 | // Cubic kilometer
50 | $newUnit = UnitOfMeasure::linearUnitFactory('km^3', 1e9);
51 | $newUnit->addAlias('km³');
52 | $newUnit->addAlias('cubic kilometer');
53 | $newUnit->addAlias('cubic kilometers');
54 | $newUnit->addAlias('cubic kilometre');
55 | $newUnit->addAlias('cubic kilometres');
56 | static::addUnit($newUnit);
57 |
58 | // Cubic foot
59 | $newUnit = UnitOfMeasure::linearUnitFactory('ft^3', 2.831685e-2);
60 | $newUnit->addAlias('ft³');
61 | $newUnit->addAlias('cubic foot');
62 | $newUnit->addAlias('cubic feet');
63 | static::addUnit($newUnit);
64 |
65 | // Cubic inch
66 | $newUnit = UnitOfMeasure::linearUnitFactory('in^3', 1.638706e-5);
67 | $newUnit->addAlias('in³');
68 | $newUnit->addAlias('cubic inch');
69 | $newUnit->addAlias('cubic inches');
70 | static::addUnit($newUnit);
71 |
72 | // Cubic yard
73 | $newUnit = UnitOfMeasure::linearUnitFactory('yd^3', 7.645549e-1);
74 | $newUnit->addAlias('yd³');
75 | $newUnit->addAlias('cubic yard');
76 | $newUnit->addAlias('cubic yards');
77 | static::addUnit($newUnit);
78 |
79 | // Milliliters
80 | $newUnit = UnitOfMeasure::linearUnitFactory('ml', 1e-6);
81 | $newUnit->addAlias('milliliter');
82 | $newUnit->addAlias('milliliters');
83 | $newUnit->addAlias('millilitre');
84 | $newUnit->addAlias('millilitres');
85 | static::addUnit($newUnit);
86 |
87 | // Centiliters
88 | $newUnit = UnitOfMeasure::linearUnitFactory('cl', 1e-5);
89 | $newUnit->addAlias('centiliter');
90 | $newUnit->addAlias('centiliters');
91 | $newUnit->addAlias('centilitre');
92 | $newUnit->addAlias('centilitres');
93 | static::addUnit($newUnit);
94 |
95 | // Deciliter
96 | $newUnit = UnitOfMeasure::linearUnitFactory('dl', 1e-4);
97 | $newUnit->addAlias('deciliter');
98 | $newUnit->addAlias('deciliters');
99 | $newUnit->addAlias('decilitre');
100 | $newUnit->addAlias('decilitres');
101 | static::addUnit($newUnit);
102 |
103 | // Liter
104 | $newUnit = UnitOfMeasure::linearUnitFactory('l', 1e-3);
105 | $newUnit->addAlias('liter');
106 | $newUnit->addAlias('liters');
107 | $newUnit->addAlias('litre');
108 | $newUnit->addAlias('litres');
109 | static::addUnit($newUnit);
110 |
111 | // Decaliter
112 | $newUnit = UnitOfMeasure::linearUnitFactory('dal', 1e-2);
113 | $newUnit->addAlias('decaliter');
114 | $newUnit->addAlias('decaliters');
115 | $newUnit->addAlias('decalitre');
116 | $newUnit->addAlias('decalitres');
117 | static::addUnit($newUnit);
118 |
119 | // Hectoliter
120 | $newUnit = UnitOfMeasure::linearUnitFactory('hl', 1e-1);
121 | $newUnit->addAlias('hectoliter');
122 | $newUnit->addAlias('hectoliters');
123 | $newUnit->addAlias('hectolitre');
124 | $newUnit->addAlias('hectolitres');
125 | static::addUnit($newUnit);
126 |
127 | // Cup
128 | $newUnit = UnitOfMeasure::linearUnitFactory('cup', 2.365882e-4);
129 | $newUnit->addAlias('cup');
130 | $newUnit->addAlias('cups');
131 | static::addUnit($newUnit);
132 |
133 | // teaspoon
134 | $newUnit = UnitOfMeasure::linearUnitFactory('tsp', 0.00000492892);
135 | $newUnit->addAlias('teaspoon');
136 | $newUnit->addAlias('teaspoons');
137 | static::addUnit($newUnit);
138 |
139 | // tablespoon
140 | $newUnit = UnitOfMeasure::linearUnitFactory('tbsp', 0.00001478676);
141 | $newUnit->addAlias('tablespoon');
142 | $newUnit->addAlias('tablespoons');
143 | static::addUnit($newUnit);
144 |
145 | // Gallon
146 | $newUnit = UnitOfMeasure::linearUnitFactory('gal', 3.7854118e-3);
147 | $newUnit->addAlias('gallon');
148 | $newUnit->addAlias('gallons');
149 | $newUnit->addAlias('us gal');
150 | static::addUnit($newUnit);
151 |
152 | // Imperial Gallon
153 | $newUnit = UnitOfMeasure::linearUnitFactory('imp gal', 4.54609e-3);
154 | $newUnit->addAlias('imperial gallon');
155 | $newUnit->addAlias('imperial gal');
156 | $newUnit->addAlias('imp gallon');
157 | $newUnit->addAlias('impg');
158 | static::addUnit($newUnit);
159 |
160 | // Quart
161 | $newUnit = UnitOfMeasure::linearUnitFactory('qt', 9.4635295e-4);
162 | $newUnit->addAlias('quart');
163 | $newUnit->addAlias('quarts');
164 | $newUnit->addAlias('qts');
165 | $newUnit->addAlias('liq qt');
166 | static::addUnit($newUnit);
167 | // Fluid Ounce
168 | $newUnit = UnitOfMeasure::linearUnitFactory('fl oz', 2.957353e-5);
169 | $newUnit->addAlias('fluid ounce');
170 | $newUnit->addAlias('fluid ounces');
171 | $newUnit->addAlias('fluid oz');
172 | $newUnit->addAlias('fl. oz.');
173 | $newUnit->addAlias('oz. fl.');
174 | static::addUnit($newUnit);
175 | // Pint
176 | $newUnit = UnitOfMeasure::linearUnitFactory('pt', 4.73176475e-4);
177 | $newUnit->addAlias('pint');
178 | $newUnit->addAlias('pints');
179 | $newUnit->addAlias('liq pt');
180 | static::addUnit($newUnit);
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/source/PhysicalQuantityInterface.php:
--------------------------------------------------------------------------------
1 | $name]);
99 | }
100 |
101 | $this->name = $name;
102 | $this->fromNativeUnit = $fromNativeUnit;
103 | $this->toNativeUnit = $toNativeUnit;
104 | }
105 |
106 | /**
107 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::getName
108 | */
109 | public function getName()
110 | {
111 | return $this->name;
112 | }
113 |
114 | /**
115 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::addAlias
116 | */
117 | public function addAlias($alias)
118 | {
119 | if (!is_string($alias)) {
120 | throw new Exception\NonStringUnitName([':name' => $alias]);
121 | }
122 |
123 | $this->aliases[] = $alias;
124 | }
125 |
126 | /**
127 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::getAliases
128 | */
129 | public function getAliases()
130 | {
131 | return $this->aliases;
132 | }
133 |
134 | /**
135 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::isAliasOf
136 | */
137 | public function isAliasOf($unit)
138 | {
139 | if (!is_string($unit)) {
140 | throw new Exception\NonStringUnitName([':name' => $unit]);
141 | }
142 |
143 | return in_array($unit, $this->aliases);
144 | }
145 |
146 | /**
147 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::convertValueFromNativeUnitOfMeasure
148 | */
149 | public function convertValueFromNativeUnitOfMeasure($value)
150 | {
151 | if (!is_numeric($value)) {
152 | throw new Exception\NonNumericValue([':value' => $value]);
153 | }
154 |
155 | $callable = $this->fromNativeUnit;
156 | return $callable($value);
157 | }
158 |
159 | /**
160 | * @see \PhpUnitsOfMeasure\UnitOfMeasureInterface::convertValueToNativeUnitOfMeasure
161 | */
162 | public function convertValueToNativeUnitOfMeasure($value)
163 | {
164 | if (!is_numeric($value)) {
165 | throw new Exception\NonNumericValue([':value' => $value]);
166 | }
167 |
168 | $callable = $this->toNativeUnit;
169 | return $callable($value);
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/source/UnitOfMeasureInterface.php:
--------------------------------------------------------------------------------
1 | getMockBuilder(UnitOfMeasureInterface::class)
24 | ->getMock();
25 | $newUnit->method('getName')
26 | ->willReturn($name);
27 | $newUnit->method('getAliases')
28 | ->willReturn($aliases);
29 | $newUnit->method('isAliasOf')
30 | ->will($this->returnCallback(
31 | function ($value) use ($aliases) {
32 | return in_array($value, $aliases);
33 | }
34 | ));
35 |
36 | return $newUnit;
37 | }
38 |
39 | /**
40 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::addUnit
41 | */
42 | public function testAddUnit(): void
43 | {
44 | $newUnit = $this->getTestUnitOfMeasure('noconflict', ['definitelynoconflict']);
45 |
46 | Wonkicity::addUnit($newUnit);
47 | }
48 |
49 | /**
50 | * @dataProvider exceptionProducingUnitsProvider
51 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::addUnit
52 | */
53 | public function testAddUnitFailsOnNameCollision($unitName, $unitAliases): void
54 | {
55 | $this->expectException(\PhpUnitsOfMeasure\Exception\DuplicateUnitNameOrAlias::class);
56 | $newUnit = $this->getTestUnitOfMeasure($unitName, $unitAliases);
57 |
58 | Wonkicity::addUnit($newUnit);
59 | }
60 |
61 | /**
62 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::getUnit
63 | */
64 | public function testGetUnit(): void
65 | {
66 | $unit = Wonkicity::getUnit('u');
67 |
68 | $this->assertSame('u', $unit->getName());
69 | }
70 |
71 | /**
72 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::getUnit
73 | */
74 | public function testGetUnitFailsOnUnknownUnit(): void
75 | {
76 | $this->expectException(\PhpUnitsOfMeasure\Exception\UnknownUnitOfMeasure::class);
77 | Wonkicity::getUnit('someUnknownUnit');
78 | }
79 |
80 | /**
81 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::__construct
82 | */
83 | public function testInstantiateNewUnit(): void
84 | {
85 | $value = new Wonkicity(1.234, 'quatloos');
86 | }
87 |
88 | /**
89 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::__construct
90 | */
91 | public function testInstantiateNewUnitNonNumericValue(): void
92 | {
93 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonNumericValue::class);
94 | $value = new Wonkicity('string', 'quatloos');
95 | }
96 |
97 | /**
98 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::__construct
99 | */
100 | public function testInstantiateNewUnitNonStringUnit(): void
101 | {
102 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonStringUnitName::class);
103 | $value = new Wonkicity(1.234, 42);
104 | }
105 |
106 | /**
107 | * @dataProvider quantityConversionsProvider
108 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::toUnit
109 | */
110 | public function testConvertToUnknownUnitThrowsException(
111 | AbstractPhysicalQuantity $value,
112 | $arbitraryUnit,
113 | $valueInArbitraryUnit
114 | ): void {
115 | $this->expectException(\PhpUnitsOfMeasure\Exception\UnknownUnitOfMeasure::class);
116 | $value->toUnit('someUnknownUnit');
117 | }
118 |
119 | /**
120 | * @dataProvider quantityConversionsProvider
121 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::toNativeUnit
122 | */
123 | public function testUnitConvertsToArbitraryUnit(
124 | AbstractPhysicalQuantity $value,
125 | $arbitraryUnit,
126 | $valueInArbitraryUnit
127 | ): void {
128 | $this->assertSame($valueInArbitraryUnit, $value->toUnit($arbitraryUnit));
129 | }
130 |
131 | /**
132 | * @dataProvider toStringProvider
133 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::__toString
134 | */
135 | public function testToString(AbstractPhysicalQuantity $value, $string): void
136 | {
137 | $this->assertSame($string, (string) $value);
138 | }
139 |
140 | /**
141 | * @dataProvider quantityConversionsProvider
142 | */
143 | public function testSerialize(
144 | AbstractPhysicalQuantity $value,
145 | $arbitraryUnit,
146 | $valueInArbitraryUnit
147 | ): void {
148 | serialize($value);
149 | }
150 |
151 | /**
152 | * @dataProvider quantityConversionsProvider
153 | */
154 | public function testUnserialize(
155 | AbstractPhysicalQuantity $value,
156 | $arbitraryUnit,
157 | $valueInArbitraryUnit
158 | ): void {
159 | $unserializedValue = unserialize(serialize($value));
160 |
161 | $this->assertSame($valueInArbitraryUnit, $unserializedValue->toUnit($arbitraryUnit));
162 | }
163 |
164 | /**
165 | * @dataProvider arithmeticProvider
166 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::add
167 | */
168 | public function testAdd(
169 | $shouldThrowException,
170 | AbstractPhysicalQuantity $firstValue,
171 | AbstractPhysicalQuantity $secondValue,
172 | $sumString,
173 | $diffString
174 | ): void {
175 | if ($shouldThrowException) {
176 | $this->expectException(PhysicalQuantityMismatch::class);
177 | }
178 |
179 | $sum = $firstValue->add($secondValue);
180 |
181 | if (!$shouldThrowException) {
182 | $this->assertSame($sumString, (string) $sum);
183 | }
184 | }
185 |
186 | /**
187 | * @dataProvider arithmeticProvider
188 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::subtract
189 | */
190 | public function testSubtract(
191 | $shouldThrowException,
192 | AbstractPhysicalQuantity $firstValue,
193 | AbstractPhysicalQuantity $secondValue,
194 | $sumString,
195 | $diffString
196 | ): void {
197 | if ($shouldThrowException) {
198 | $this->expectException(PhysicalQuantityMismatch::class);
199 | }
200 |
201 | $difference = $firstValue->subtract($secondValue);
202 |
203 | if (!$shouldThrowException) {
204 | $this->assertSame($diffString, (string) $difference);
205 | }
206 | }
207 |
208 | /**
209 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::getUnitDefinitions
210 | */
211 | public function testGetAllUnits(): void
212 | {
213 | $array = Wonkicity::getUnitDefinitions();
214 |
215 | $this->assertIsArray($array);
216 |
217 | $expected = array(Wonkicity::getUnit('u'), Wonkicity::getUnit('v'));
218 | $this->assertEquals($array, $expected);
219 | }
220 |
221 | /**
222 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::isUnitDefined
223 | */
224 | public function testIsUnitDefined(): void
225 | {
226 | $newUnit = $this->getTestUnitOfMeasure('noconflict', ['definitelynoconflict_1', 'definitelynoconflict_2']);
227 | Wonkicity::addUnit($newUnit);
228 |
229 | $someExistingUnits = ['u', 'uvees', 'v', 'vorp', 'noconflict', 'definitelynoconflict_1', 'definitelynoconflict_2'];
230 | $unexistingUnits = ['kg', 'l', 'definitelynoconflict_'];
231 |
232 | foreach ($someExistingUnits as $someExistingUnit) {
233 | $this->assertTrue(Wonkicity::isUnitDefined($someExistingUnit), "$someExistingUnit is not defined");
234 | }
235 | foreach ($unexistingUnits as $unexistingUnit) {
236 | $this->assertFalse(Wonkicity::isUnitDefined($unexistingUnit), "$unexistingUnit is not defined");
237 | }
238 | }
239 |
240 | /**
241 | * @covers \PhpUnitsOfMeasure\AbstractPhysicalQuantity::listAllUnits
242 | */
243 | public function testListAllUnits(): void
244 | {
245 | $newUnit = $this->getTestUnitOfMeasure('noconflict', ['definitelynoconflict_1', 'definitelynoconflict_2']);
246 | Wonkicity::addUnit($newUnit);
247 |
248 | $allUnits = Wonkicity::listAllUnits();
249 | $expected = [];
250 | $expected['u'] = ['uvee', 'uvees'];
251 | $expected['v'] = ['vorp', 'vorps'];
252 | $expected['noconflict'] = ['definitelynoconflict_1', 'definitelynoconflict_2'];
253 | $this->assertEquals($allUnits, $expected);
254 | }
255 |
256 | public function testGetOriginalValue()
257 | {
258 | $value = 2;
259 | $unit = 'u';
260 | $physicalQuantity = new Wonkicity($value, $unit);
261 | $this->assertEquals($value, $physicalQuantity->getOriginalValue());
262 | $this->assertEquals($unit, $physicalQuantity->getOriginalUnit());
263 | }
264 |
265 | /**
266 | * Attempting to register these units should throw a DuplicateUnitNameOrAlias.
267 | * 1) The name of the new unit to test
268 | * 2) The set of aliases for the new unit to test
269 | */
270 | public function exceptionProducingUnitsProvider(): array
271 | {
272 | return [
273 | ['u', []], // new name / existing name collision
274 | ['noconflict', ['u']], // new alias / existing name collision
275 | ['uvee', []], // new name / existing alias collision
276 | ['noconflict', ['uvee']], // new alias / existing alias collision
277 | ];
278 | }
279 |
280 | /**
281 | * Provide some conversion testing data
282 | * 1) the object from which to start
283 | * 2) The unit name to which to convert
284 | * 3) The expected resulting value of the conversion
285 | */
286 | public function quantityConversionsProvider(): array
287 | {
288 | return [
289 | [new Wonkicity(2, 'u'), 'u', 2],
290 | [new Wonkicity(2, 'u'), 'vorps', 2/3.5],
291 | [new Wonkicity(2, 'vorps'), 'u', 2*3.5],
292 | [new Wonkicity(2, 'vorps'), 'vorps', 2.0],
293 | [new Woogosity(2, 'p'), 'lupees', 2*4.5],
294 | [new Woogosity(2, 'p'), 'millilupees', 2*4.5*1000],
295 | ];
296 | }
297 |
298 | /**
299 | * Provide some string conversion testing data
300 | * 1) The object which will be cast to a string
301 | * 2) the expected resulting string from the conversion
302 | */
303 | public function toStringProvider(): array
304 | {
305 | return [
306 | [new Wonkicity(2, 'u'), '2 u'],
307 | [new Wonkicity(2, 'uvee'), '2 u'],
308 | [new Wonkicity(2, 'v'), '2 v'],
309 | [new Wonkicity(2, 'vorps'), '2 v'],
310 | [new Woogosity(2, 'plurps'), '2 p'],
311 | [new Woogosity(2, 'millilupees'), '2 ml'],
312 | ];
313 | }
314 |
315 | /**
316 | * Provide some arithmetic relations for testing
317 | * 1) Boolean - whether or not the operation shoul error out due to a type mismatch (PhysicalQuantityMismatch exception)
318 | * 2) The left-hand-side operand
319 | * 3) The right-hand-side operand
320 | * 4) The string-cast result of a sum operation with the two operands (ignored for errors)
321 | * 5) The string-cast result of a subtraction operation with the two operands (ignored for errors)
322 | */
323 | public function arithmeticProvider(): array
324 | {
325 | return [
326 | [false, new Wonkicity(2, 'u'), new Wonkicity(2.5, 'u'), '4.5 u', '-0.5 u'],
327 | [true, new Wonkicity(2, 'u'), new Woogosity(2, 'l'), '', ''],
328 | ];
329 | }
330 | }
331 |
--------------------------------------------------------------------------------
/tests/DemonstrationTests.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(Wigginess::class, $a);
42 |
43 | $a = new Wigginess(2.123, 'sopees');
44 | $this->assertInstanceOf(Wigginess::class, $a);
45 |
46 | $a = new Wigginess(2.6, 's');
47 | $this->assertInstanceOf(Wigginess::class, $a);
48 |
49 | $a = new Wigginess(1, 'tumpet');
50 | $this->assertInstanceOf(Wigginess::class, $a);
51 |
52 | $a = new Wigginess(2.123, 'tumpets');
53 | $this->assertInstanceOf(Wigginess::class, $a);
54 |
55 | $a = new Wigginess(2.6, 't');
56 | $this->assertInstanceOf(Wigginess::class, $a);
57 | }
58 |
59 | public function testStringConversionForQuantities(): void
60 | {
61 | // Casting physical quantity objects to strings will
62 | // produce a reasonable string describing the quantity.
63 | $a = new Wigginess(21.123, 'sopees');
64 | $this->assertSame('21.123 s', (string) $a);
65 |
66 | $a = new Wigginess(21.123, 'tumpets');
67 | $this->assertSame('21.123 t', (string) $a);
68 | }
69 |
70 | public function testUnitConversionForQuantities(): void
71 | {
72 | // Creating equivalent quantities from existing
73 | // quantities in different units of measure is done
74 | // with the toUnit() method. Note that the method
75 | // returns a new object, and does not modify the
76 | // unit of the object on which it is called.
77 | //
78 | // (In imaginary Testworld, 2.5 sopees is 1 tumpet.
79 | // See the Wigginess.php example class for details
80 | // on how these units are defined.)
81 | $a = new Wigginess(21, 'sopees');
82 | $this->assertSame(21, $a->toUnit('sopee'));
83 | $this->assertSame(21/2.5, $a->toUnit('tumpets'));
84 | $this->assertSame(21/2.5, $a->toUnit('t'));
85 | }
86 |
87 | public function testCreatingNewUnitsForQuantities(): void
88 | {
89 | // New units of measure can be defined and registered
90 | // with physical quantities on the fly.
91 |
92 | // Here, we create three new units, demonstrating the 3
93 | // different methods for instantiating them. These units
94 | // will exist in addition to the units that come 'out of
95 | // the box' for the given quantity, once they're registered
96 | // with the static addUnit().
97 |
98 | // The linear unit factory is useful for defining new
99 | // units that are a simple scaling factor conversion
100 | // to the quantity's native unit of measure.
101 | // In this case there are 4.5 bbbb's in the native unit of measure.
102 | $unitA = UnitOfMeasure::linearUnitFactory('bbbb', 4.5);
103 | Wigginess::addUnit($unitA);
104 |
105 | // Using the native unit factory method is equivalent to a
106 | // linear unit with a factor of 1. It's convenient for creating
107 | // a unit to represent the native unit of measure.
108 | $unitB = UnitOfMeasure::nativeUnitFactory('aaaa');
109 | Wigginess::addUnit($unitB);
110 |
111 | // The long form constructor is necessary for units
112 | // that don't have simple scaling factor functions for
113 | // their conversions. For this unit we'll also add 2 more
114 | // aliases (dddd and eeee) that serve as equivalent names
115 | // for the unit's real name (cccc).
116 | $unitC = new UnitOfMeasure(
117 | 'cccc',
118 | function ($valueInNativeUnit) {
119 | return $valueInNativeUnit - 100;
120 | },
121 | function ($valueInThisUnit) {
122 | return $valueInThisUnit + 100;
123 | }
124 | );
125 | $unitC->addAlias('dddd');
126 | $unitC->addAlias('eeee');
127 | Wigginess::addUnit($unitC);
128 |
129 |
130 | // Here we can see that the units defined above
131 | // convert as expected with the built-in units.
132 | $a = new Wigginess(21, 'sopees');
133 | $this->assertSame(21, $a->toUnit('aaaa'));
134 | $this->assertSame(21/4.5, $a->toUnit('bbbb'));
135 | $this->assertSame(21-100, $a->toUnit('cccc'));
136 | $this->assertSame(21-100, $a->toUnit('dddd'));
137 | $this->assertSame(21-100, $a->toUnit('eeee'));
138 |
139 | $b = new Wigginess(21, 'tumpets');
140 | $this->assertSame(21*2.5, $b->toUnit('aaaa'));
141 | $this->assertSame(21/4.5*2.5, $b->toUnit('bbbb'));
142 | $this->assertSame((21*2.5)-100, $b->toUnit('cccc'));
143 | $this->assertSame((21*2.5)-100, $b->toUnit('dddd'));
144 | $this->assertSame((21*2.5)-100, $b->toUnit('eeee'));
145 | }
146 |
147 | public function testAutomaticSIUnitsForQuantities(): void
148 | {
149 | // SI units have a standard prefix naming convention to easily
150 | // provide powers-of-ten versions of a standard unit. For instance,
151 | // for the physical quantity length, the meter is the standard SI
152 | // unit, and 1000 meters is a kilometer, 1/1000th of a meter is a
153 | // millimeter, and so on.
154 | //
155 | // The Woogosity class has the HasSIUnitsTrait trait, and can
156 | // automatically generate new units for a given unit, for all
157 | // the standard SI prefixes. See the Woogosity.php class file
158 | // for an example of how this is done.
159 | $a = new Woogosity(21, 'plurp');
160 |
161 | $this->assertInstanceOf(Woogosity::class, $a);
162 | $this->assertSame(21*4.5 * 1e3, $a->toUnit('millilupees'));
163 | $this->assertSame(21*4.5 * 1e3, $a->toUnit('ml'));
164 | $this->assertSame(21*4.5 / 1e6, $a->toUnit('megalupees'));
165 | $this->assertSame(21*4.5 / 1e6, $a->toUnit('Ml'));
166 | }
167 |
168 | public function testAddQuantities(): void
169 | {
170 | // Two quantities of equivalent value can be summed
171 | // by calling the add method.
172 | $a = new Wigginess(3, 'sopee');
173 | $b = new Wigginess(2, 'tumpet');
174 | $c = $a->add($b);
175 |
176 | $this->assertInstanceOf(Wigginess::class, $c);
177 | $this->assertSame(3 + (2*2.5), $c->toUnit('sopee'));
178 | }
179 |
180 | public function testSubtractQuantities(): void
181 | {
182 | // Similar to the add method, subtract called on the
183 | // left-hand-side operand object will subtract the
184 | // parameter quantity and produce a new value.
185 | $a = new Wigginess(3, 'sopee');
186 | $b = new Wigginess(2, 'tumpet');
187 | $c = $a->subtract($b);
188 |
189 | $this->assertInstanceOf(Wigginess::class, $c);
190 | $this->assertSame(3 - (2*2.5), $c->toUnit('sopee'));
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/tests/Fixtures/PhysicalQuantity/Wigginess.php:
--------------------------------------------------------------------------------
1 | addAlias('sopee');
16 | $native->addAlias('sopees');
17 | static::addUnit($native);
18 |
19 | $unit = UnitOfMeasure::linearUnitFactory('t', 2.5);
20 | $unit->addAlias('tumpet');
21 | $unit->addAlias('tumpets');
22 | static::addUnit($unit);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Fixtures/PhysicalQuantity/Wonkicity.php:
--------------------------------------------------------------------------------
1 | addAlias('uvee');
16 | $native->addAlias('uvees');
17 | static::addUnit($native);
18 |
19 | $unit = UnitOfMeasure::linearUnitFactory('v', 3.5);
20 | $unit->addAlias('vorp');
21 | $unit->addAlias('vorps');
22 | static::addUnit($unit);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Fixtures/PhysicalQuantity/Woogosity.php:
--------------------------------------------------------------------------------
1 | addAlias('lupee');
19 | $native->addAlias('lupees');
20 | static::addUnit($native);
21 | static::addMissingSIPrefixedUnits(
22 | $native,
23 | 1,
24 | '%pl',
25 | [
26 | '%Plupee',
27 | '%Plupees',
28 | ]
29 | );
30 |
31 | $unit = UnitOfMeasure::linearUnitFactory('p', 4.5);
32 | $unit->addAlias('plurp');
33 | $unit->addAlias('plurps');
34 | static::addUnit($unit);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/AbstractPhysicalQuantityTestCase.php:
--------------------------------------------------------------------------------
1 | instantiateTestQuantity();
21 | }
22 |
23 | /**
24 | * Convert to each of the known supported units, verifying that no
25 | * exceptions are thrown.
26 | */
27 | public function testSupportedUnits(): void
28 | {
29 | $quantity = $this->instantiateTestQuantity();
30 |
31 | foreach ($this->supportedUnitsWithAliases as $unit) {
32 | $quantity->toUnit($unit);
33 | }
34 | }
35 |
36 | /**
37 | * Build a test object of the target physical quantity.
38 | */
39 | abstract protected function instantiateTestQuantity(): PhysicalQuantityInterface;
40 | }
41 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/AccelerationTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(360, $angle->toUnit('deg'));
262 | }
263 |
264 | public function testToRadians(): void
265 | {
266 | $angle = new Angle(720, 'degree');
267 | $this->assertEquals(M_PI * 4, $angle->toUnit('rad'));
268 | }
269 | }
270 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/AreaTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(30000, $area->toUnit("m^2"));
75 | }
76 |
77 | /**
78 | * There aren't lots of super nice conversions between ac -> m^2,
79 | * so we'll check that it's close.
80 | */
81 | public function testToAcres(): void
82 | {
83 | $area = new Area(13, 'ac');
84 |
85 | $area = round($area->toUnit("m^2"), 6);
86 |
87 | $this->assertEquals(52609.133491, $area);
88 | }
89 |
90 | public function testToAre(): void
91 | {
92 | $area = new Area(100, 'm^2');
93 | $this->assertEquals(1, $area->toUnit('are'));
94 | }
95 |
96 | public function testToDecare(): void
97 | {
98 | $area = new Area(1000, 'm^2');
99 | $this->assertEquals(1, $area->toUnit('decare'));
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/ElectricCurrentTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(1, $quantity->toUnit('kWh'));
71 | }
72 |
73 | public function testToWattHour(): void
74 | {
75 | $quantity = new Energy(1, 'kWh');
76 | $this->assertEquals(1000, $quantity->toUnit('Wh'));
77 | }
78 |
79 | public function testToMegaJoule(): void
80 | {
81 | $quantity = new Energy(1, 'kWh');
82 | $this->assertEquals(3.6, $quantity->toUnit('megajoule'));
83 | }
84 |
85 | public function testToJoule(): void
86 | {
87 | $quantity = new Energy(1, 'Wh');
88 | $this->assertEquals(3600, $quantity->toUnit('joule'));
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/LengthTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(5000, $quantity->toUnit('mm'));
148 | }
149 |
150 | public function testToMegameters(): void
151 | {
152 | $quantity = new Length(5, 'm');
153 | $this->assertEquals(5/1e6, $quantity->toUnit('Mm'));
154 | }
155 |
156 | public function testToInches(): void
157 | {
158 | $quantity = new Length(2, 'ft');
159 | $this->assertEquals(24, round($quantity->toUnit('in')));
160 | }
161 |
162 | public function testToNauticalMiles(): void
163 | {
164 | $quantity = new Length(3704, 'm');
165 | $this->assertEquals(2, $quantity->toUnit('nmi'));
166 | }
167 |
168 | public function testToScandinavianMil(): void
169 | {
170 | $quantity = new Length(20000, 'm');
171 | $this->assertEquals(2, $quantity->toUnit('mil'));
172 | }
173 |
174 | public function testToAstronomicalUnit(): void
175 | {
176 | $quantity = new Length(150000000, 'km');
177 | $this->assertEquals(1.0026880683402668, $quantity->toUnit('AU'));
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/LuminousIntensityTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(5000, $quantity->toUnit('g'));
100 | }
101 |
102 | public function testToMilligrams(): void
103 | {
104 | $quantity = new Mass(5, 'kg');
105 | $this->assertEquals(5*1e6, $quantity->toUnit('mg'));
106 | }
107 |
108 | public function testToPounds(): void
109 | {
110 | $quantity = new Mass(16, 'oz');
111 | $this->assertEquals(1, $quantity->toUnit('pound'));
112 | }
113 |
114 | public function testToStones(): void
115 | {
116 | $quantity = new Mass(14, 'pound');
117 | $this->assertEquals(1, $quantity->toUnit('st'));
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/PowerTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(1, $quantity->toUnit('kW'));
46 | }
47 |
48 | public function testToWatt(): void
49 | {
50 | $quantity = new Power(1, 'kW');
51 | $this->assertEquals(1000, $quantity->toUnit('W'));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/PressureTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(300, $angle->toUnit('seconds'));
153 | }
154 |
155 | public function testToMinutes(): void
156 | {
157 | $angle = new Time(360, 'sec');
158 | $this->assertEquals(6, $angle->toUnit('min'));
159 | }
160 |
161 | public function testToHours(): void
162 | {
163 | $angle = new Time(120, 'mins');
164 | $this->assertEquals(2, $angle->toUnit('hrs'));
165 | }
166 |
167 | public function testToDays(): void
168 | {
169 | $angle = new Time(72, 'hours');
170 | $this->assertEquals(3, $angle->toUnit('days'));
171 | }
172 |
173 | public function testToWeeks(): void
174 | {
175 | $angle = new Time(14, 'd');
176 | $this->assertEquals(2, $angle->toUnit('week'));
177 | }
178 |
179 | public function testToGregorianYears(): void
180 | {
181 | $angle = new Time(365.2425, 'd');
182 | $this->assertEquals(1, $angle->toUnit('yr'));
183 | }
184 |
185 | public function testToJulianYears(): void
186 | {
187 | $angle = new Time(365.25, 'd');
188 | $this->assertEquals(1, $angle->toUnit('jyr'));
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/VelocityTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(0.277778, $speed->toUnit('m/s'));
42 | }
43 |
44 | public function testToFeetPerSecond(): void
45 | {
46 | $speed = new Velocity(2, 'm/s');
47 | $this->assertEquals(6.561679790026246, $speed->toUnit('ft/s'));
48 | }
49 |
50 | public function testToKmPerHour(): void
51 | {
52 | $speed = new Velocity(2, 'mph');
53 | $this->assertEquals(3.2186854250516594, $speed->toUnit('km/h'));
54 | }
55 |
56 | public function testToKnot(): void
57 | {
58 | $speed = new Velocity(2, 'm/s');
59 | $this->assertEquals(3.8876923435786983, $speed->toUnit('knot'));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/PhysicalQuantity/VolumeTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('quatloos', $uom->getName());
27 | }
28 |
29 | /**
30 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::__construct
31 | */
32 | public function testConstructWithNonStringName(): void
33 | {
34 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonStringUnitName::class);
35 | $uom = new UnitOfMeasure(
36 | 42,
37 | function ($valueInNativeUnit) {
38 | return $valueInNativeUnit;
39 | },
40 | function ($valueInThisUnit) {
41 | return $valueInThisUnit;
42 | }
43 | );
44 | }
45 |
46 | /**
47 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::addAlias
48 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::getAliases
49 | */
50 | public function testGetAliases(): void
51 | {
52 | $uom = new UnitOfMeasure(
53 | 'quatloos',
54 | function ($valueInNativeUnit) {
55 | return $valueInNativeUnit;
56 | },
57 | function ($valueInThisUnit) {
58 | return $valueInThisUnit;
59 | }
60 | );
61 |
62 | $uom->addAlias('ooltauqs');
63 | $uom->addAlias('schmoos');
64 |
65 | $this->assertEquals(
66 | ['ooltauqs', 'schmoos'],
67 | $uom->getAliases()
68 | );
69 | }
70 |
71 | /**
72 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::addAlias
73 | */
74 | public function testAddAliasWithNonStringAlias(): void
75 | {
76 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonStringUnitName::class);
77 | $uom = new UnitOfMeasure(
78 | 'quatloos',
79 | function ($valueInNativeUnit) {
80 | return $valueInNativeUnit;
81 | },
82 | function ($valueInThisUnit) {
83 | return $valueInThisUnit;
84 | }
85 | );
86 |
87 | $uom->addAlias(42);
88 | }
89 |
90 | /**
91 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::isAliasOf
92 | */
93 | public function testIsAliasOf(): void
94 | {
95 | $uom = new UnitOfMeasure(
96 | 'quatloos',
97 | function ($valueInNativeUnit) {
98 | return $valueInNativeUnit;
99 | },
100 | function ($valueInThisUnit) {
101 | return $valueInThisUnit;
102 | }
103 | );
104 |
105 | $uom->addAlias('ooltauqs');
106 |
107 | $this->assertTrue($uom->isAliasOf('ooltauqs'));
108 | }
109 |
110 | /**
111 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::isAliasOf
112 | */
113 | public function testIsNotAliasOf(): void
114 | {
115 | $uom = new UnitOfMeasure(
116 | 'quatloos',
117 | function ($valueInNativeUnit) {
118 | return $valueInNativeUnit;
119 | },
120 | function ($valueInThisUnit) {
121 | return $valueInThisUnit;
122 | }
123 | );
124 |
125 | $uom->addAlias('ooltauqs');
126 |
127 | $this->assertFalse($uom->isAliasOf('wampii'));
128 | }
129 |
130 | /**
131 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::isAliasOf
132 | *
133 | */
134 | public function testIsAliasOfWithNonStringAlias(): void
135 | {
136 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonStringUnitName::class);
137 | $uom = new UnitOfMeasure(
138 | 'quatloos',
139 | function ($valueInNativeUnit) {
140 | return $valueInNativeUnit;
141 | },
142 | function ($valueInThisUnit) {
143 | return $valueInThisUnit;
144 | }
145 | );
146 |
147 | $uom->addAlias('ooltauqs');
148 |
149 | $this->assertFalse($uom->isAliasOf(42));
150 | }
151 |
152 | /**
153 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::convertValueFromNativeUnitOfMeasure
154 | */
155 | public function testConvertValueFromNativeUnitOfMeasure(): void
156 | {
157 | $uom = new UnitOfMeasure(
158 | 'quatloos',
159 | function ($valueInNativeUnit) {
160 | return $valueInNativeUnit * 1.1234;
161 | },
162 | function ($valueInThisUnit) {
163 | return false;
164 | }
165 | );
166 |
167 | $this->assertSame(11.234, $uom->convertValueFromNativeUnitOfMeasure(10));
168 | }
169 |
170 | /**
171 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::convertValueFromNativeUnitOfMeasure
172 | */
173 | public function testConvertValueFromNativeUnitOfMeasureWithNonNumericalValue(): void
174 | {
175 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonNumericValue::class);
176 | $uom = new UnitOfMeasure(
177 | 'quatloos',
178 | function ($valueInNativeUnit) {
179 | return $valueInNativeUnit * 1.1234;
180 | },
181 | function ($valueInThisUnit) {
182 | return false;
183 | }
184 | );
185 |
186 | $this->assertSame(11.234, $uom->convertValueFromNativeUnitOfMeasure('string'));
187 | }
188 |
189 | /**
190 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::convertValueToNativeUnitOfMeasure
191 | */
192 | public function testConvertValueToNativeUnitOfMeasure(): void
193 | {
194 | $uom = new UnitOfMeasure(
195 | 'quatloos',
196 | function ($valueInNativeUnit) {
197 | return false;
198 | },
199 | function ($valueInThisUnit) {
200 | return $valueInThisUnit * 1.1234;
201 | }
202 | );
203 |
204 | $this->assertSame(11.234, $uom->convertValueToNativeUnitOfMeasure(10));
205 | }
206 |
207 | /**
208 | * @covers \PhpUnitsOfMeasure\UnitOfMeasure::convertValueToNativeUnitOfMeasure
209 | */
210 | public function testConvertValueToNativeUnitOfMeasureWithNonNumericalValue(): void
211 | {
212 | $this->expectException(\PhpUnitsOfMeasure\Exception\NonNumericValue::class);
213 | $uom = new UnitOfMeasure(
214 | 'quatloos',
215 | function ($valueInNativeUnit) {
216 | return false;
217 | },
218 | function ($valueInThisUnit) {
219 | return $valueInThisUnit * 1.1234;
220 | }
221 | );
222 |
223 | $this->assertSame(11.234, $uom->convertValueToNativeUnitOfMeasure('string'));
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/tests/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A basic coding standard.
5 |
6 | vendor/*
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./
12 |
13 |
14 |
15 |
16 |
17 | ../source
18 |
19 |
20 | ../vendor
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------