Code Monkey home page Code Monkey logo

php-units-of-measure's Introduction

PHP Units of Measure

master: Build Status

Introduction

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:

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

$height = new Length(6.16, 'feet');
echo $height->toUnit('m');

// would print 1.87757, which is 6.16 feet in meters.

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:

// Tied to a specific unit of measure
function isTooTallToRideThisTrain( $height )
{
  return $height > 5;
}

// Calling the function requires that you first convert whatever quantity
// you have into the expected units:
isTooTallToRideThisTrain(2 / 0.3048);

Whereas this version using this library allows for height to be provided in whatever unit is convenient:

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

// Free to operate on lengths in any unit of measure
function isTooTallToRideThisTrain( Length $height )
{
  return $height->toUnit('ft') > 5;
}

// Calling the function now allows any unit to be used:
isTooTallToRideThisTrain( new Length(2, 'm') );

Installation

This library is best included in your projects via Composer. See the Composer website for more details, and see the Packagist.org site for this library.

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 compliant PHP autoloader. The mapping between this project's root namespace and its base directory is:

  • vendor namespace 'PhpUnitsOfMeasure' maps to the library's base directory 'source/'

See the documentation of your autoloader for further instructions.

Project Tags and Versions

This project follows the guidelines set out in Semantic Versioning 2.0.0. In general, versions are of the form 'X.Y.Z', and increments to X denote backward-incompatible major changes.

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, 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.

Use

Conversion

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:

use PhpUnitsOfMeasure\PhysicalQuantity\Mass;

$quantity = new Mass(6, 'lbs');
echo $quantity->toUnit('g');

It's also possible to implicity cast a quantity to a string, which will display its original value:

use PhpUnitsOfMeasure\PhysicalQuantity\Mass;

$quantity = new Mass(6, 'pounds');
echo $quantity; // '6 lbs'

Arithmetic Operators

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:

use PhpUnitsOfMeasure\PhysicalQuantity\Volume;

$first  = new Volume(6, 'liters');
$second = new Volume(6, 'cups');

$sum = $first->add($second);
echo $sum; // 7.4195292 l

$difference = $first->subtract($second);
echo $difference; // 4.5804708 l

Adding new Units of Measure to Existing Quantities

Ocassionally, you will need to add a new unit of measure to a pre-existing quantity.

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.

Adding a New Unit of Measure at Runtime

To add a new unit of measure to an existing quantity at run time, you'd do this:

use PhpUnitsOfMeasure\PhysicalQuantity\Length;
use PhpUnitsOfMeasure\PhysicalQuantity\UnitOfMeasure;

// It's ok to create objects with cubits before the new unit is registered, since
// the conversion doesn't happen until an output method is called
$length = new Length(14, 'cubits');

// Build a new Unit of Measure object which represents the new unit, and which
// knows how to convert between the new unit and the quantity's native unit
// (in this case, meters).
$cubit = new UnitOfMeasure(

    // This is the official name of this unit - typically it's the standard
    // abbreviation
    'cb',

    // The second parameter is a function that converts from the native unit
    // to this unit
    function ($valueInNativeUnit) {
        return $valueInNativeUnit / 0.4572;
    },

    // The third parameter is a function that converts from this unit to the
    // native unit
    function ($valueInThisUnit) {
        return $valueInThisUnit * 0.4572;
    }
);

// Any alias names for this unit can be added here, to make it easier to use
// variations
$cubit->addAlias('cubit');
$cubit->addAlias('cubits');

// Register the new unit of measure with the quantity class
Length::addUnit($cubit);

// Now that the unit is registered, you can cast the measurement to any other
// measure of length
echo $length->toUnit('feet'); // '21'
Shorthand Factory Methods

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.

$megameter = UnitOfMeasure::linearUnitFactory('Mm', 1e6);
$megameter->addAlias('Megameter');
$megameter->addAlias('Megametre');
Length::addUnit($megameter);

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:

$meter = UnitOfMeasure::nativeUnitFactory('m');
$meter->addAlias('meter');
$meter->addAlias('metre');
Length::addUnit($meter);
Automatically Generating Metric Units

For units that use the metric system, there's a convenience trait available for classes which implementPhysicalQuantityInterface which will automatically generate the full continuum of metric units from a single unit. For instance:

namespace PhpUnitsOfMeasure\PhysicalQuantity;

use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
use PhpUnitsOfMeasure\UnitOfMeasure;
use PhpUnitsOfMeasure\HasSIUnitsTrait;

class Mass extends AbstractPhysicalQuantity
{
    use HasSIUnitsTrait;

    protected static $unitDefinitions;

    protected static function initialize()
    {
        // Kilogram
        $kilogram = UnitOfMeasure::nativeUnitFactory('kg');
        $kilogram->addAlias('kilogram');
        $kilogram->addAlias('kilograms');
        static::addUnit($kilogram);

        static::addMissingSIPrefixedUnits(
            $kilogram,
            1e-3,
            '%pg',
            [
                '%Pgram',
                '%Pgrams',
            ]
        );
    }
}

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.

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.

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', ... .

Permanently Adding a New Unit of Measure to a Physical Quantity

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.

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:

namespace PhpUnitsOfMeasure\PhysicalQuantity;

use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
use PhpUnitsOfMeasure\UnitOfMeasure;

class Length extends AbstractPhysicalQuantity
{
    protected static $unitDefinitions;

    protected static function initialize()
    {
        // ...
        // ...
        // Here's all the pre-existing unit definitions for Length
        // ...
        // ...

        // Cubit
        $cubit = UnitOfMeasure::linearUnitFactory('cb', 0.4572);
        $cubit->addAlias('cubit');
        $cubit->addAlias('cubits');
        static::addUnit($cubit);
    }
}

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.

Adding New Physical Quantities

Physical quantities are categories of measurable values, like mass, length, force, etc.

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.

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.

Adding new Aliases to Existing Units

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:

use PhpUnitsOfMeasure\PhysicalQuantity\Length;

// It's ok to use footses here, since the conversion doesn't happen
// until later
$length = new Length(4, 'footses');

// Fetch the unit of measure object that represents the 'ft' unit
$footUnit = Length::getUnit('ft');

// Any alias names for this unit can be added here, to make it easier
// to use variations
$footUnit->addAlias('footses');

// Now that the unit has been modified with its new alias, you can cast
// the measurement to any other measure of length
echo $length->toUnit('m'); // '1.2192'

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.

Testing and Contributing

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.

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". This guide contains the approved conversion factors between various units and the base SI units.

Also note that any new physical quantities should have the appropriate SI unit chosen for their native unit of measure.

Pull Requests and Merging

The workflow for this repository goes as follows:

  • To develop new contributions, fork or branch from the master branch of the main repository
  • Pull requests and contribution merges are always made to the master branch of the main repository
  • From time to time, commits of master are tagged and a new version is released
  • 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.

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.

Local Testing Environment

There's a Vagrant virtual machine configuration included which is suitable for running the necessary unit tests. To bring up the machine, make sure you have Vagrant and Virtualbox installed, and from the project root directory:

vagrant up
vagrant ssh
cd /project

Setting Up for Testing

The virtual machine development environment already has Composer installed. Once you're ssh'ed into the virtual machine, install this project's dev dependencies:

rm -rf vendor
composer.phar update --verbose --prefer-dist

Unit Tests

All the tests associated with this project can be manually run with:

vendor/bin/phpunit -c ./tests/phpunit.xml.dist ./tests

CodeSniffer

Codesniffer verifies that coding standards are being met. Once the project is built with development dependencies, you can run the checks with:

vendor/bin/phpcs --encoding=utf-8 --extensions=php --standard=./tests/phpcs.xml -nsp ./

Continuous Integration

The above tests are automatically run against Github commits with Travis-CI.

php-units-of-measure's People

Contributors

daawesomep avatar h4cc avatar janlanger avatar kticka avatar martinlindhe avatar mauris avatar pierpaolocira avatar scalopus avatar stephenclouse avatar tcql avatar toddnestor avatar triplepoint avatar zomble avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-units-of-measure's Issues

Velocity vs. Speed

Hello. I am working on a little patch for this code, and in it i am extending the "Velocity" class with additional units.

Since it currently only has one unit ("meters per second"), i am guessing noone is actually using it. So might it be possible if we rename it to "Speed" instead?

If ok, I will rename the class to Speed in my branch before sending a pull request

From wikipedia:
"Distinction between speed and velocity Speed describes only how fast an object is moving, whereas velocity gives both how fast and in what direction the object is moving. If a car is said to travel at 60 km/h, its speed has been specified."

Bytes?

What about bytes? It would be very helpful if we can quickly change units in terms of bytes.

bits as well.

Add support for Population

Do you think it is possible to add the support for "Population" (in "Person")?
I don't know if it is interesting, but can be useful to manage dataset containing information about this concept (often in MPerson).
If you are interested I can open a pull request...
Thank you

Missing features

Just started using this but having some issues with features that aren't implemented compared to the front end library I'm using (js-quantities)

  1. No multiplication/division
    js-quantities allows you to multiply a quantity by a numeric factor or another quantity.
  2. toUnit method doesn't return new quantity
    Currently the toUnit method will return the converted quantity as a float rather than a new quantity instance. This feels inconsistent with how adding/subtracting quantities works; if you want to perform further operations you have to manually create the new quantity like so new Length($qty->toUnit('ft'), 'ft')
  3. No methods to access scalar and unit values
    Basically just needs something like scalar() and unit() methods that will return originalValue and originalUnit respectively.
  4. Can't create generic quantities
    For example, from user supplied inputs of either a mass or volume measurement it's not possible to create a quantity without checking what type of unit the measurement is. You can't do new Quantity($scalar, $unit) instead you have to check if its a mass or volume then create the class
$type = isLiquid($unit) ? 'Mass' : 'Volume';
$qty = new $type($scalar, $unit)

I hope these are valid suggestions. At the moment I've patched/added 1, 2, & 3, would they be worth sending in a PR? Maybe the change to toUnit would be better as a separate method for backwards compatibility?

Add support for Power

Do you think it is possible to add the support for "Power" (in Watts, plus SI prefixes))?
If you are interested I can open a pull request...
Thank you

Is it possible to get all supported units?

For example, if I want to give a drop down in user interface where UOM is chosen by user, I have to manually add list of units supported. Is it possible via some API with library? getSupportedUnits()?

Error in AbstractPhysicalQuantityTest::getTestUnitOfMeasure

Hi,
I think there is an error in the abovementioned function (related to the MockBuilder behaviour).

I'm trying to write a new test function, related to the following function declared into the AbstractPhysicalQuantity (see #62)

public static function isUnitDefined($name) {
    	$units = static::getUnitDefinitions();
    	foreach ($units as $unit) {
    		if ($name === $unit->getName() || $unit->isAliasOf($name)) {
    			return true;
    		}
    	}
    	return false;
    }

Following the existing code, I tried to create the related unit test also adding a new unit. This is the only important part of the function to reproduce the error:

public function testIsUnitDefined(){
    	$newUnit = $this->getTestUnitOfMeasure('noconflict', ['definitelynoconflict']);
    	Wonkicity::addUnit($newUnit);
    	$this->assertTrue(Wonkicity::isUnitDefined("noconflict"));    	
    	$this->assertTrue(Wonkicity::isUnitDefined("definitelynoconflict"));    	
    }

The first assert is correct, but not the second one.

I made several test to inestigate on the error... and I saw that if you run (into AbstractPhysicalQuantity) a $unit->getName() or a $unit->getAliases() you will see the expected values.

So the problems seems to be linked to the isAliasOf() method.

I'm running on a PHP 5.5.36 environment.

Hope this helps.

[PhysicalQuantity] Add support for Viscosity (code provided)

As I am unsure how this would be preferred by the community to be supported, instead of a pull request, I've provided the objects here separately.
This is so that Kinematic and Dynamic viscosities can be converted between Poise and Stokes, (taking into account densities).

For details see SI reference on Viscosities: https://en.wikipedia.org/wiki/Viscosity

I've left out SUS, and ISO from the Kinematic definition as they require extra processing that I feel falls outside of the scope of the definitions, but do have conversion for ISO. I was not able to derive an acceptable formula for SUS in relation to the native unit however.

use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
use PhpUnitsOfMeasure\HasSIUnitsTrait;
use PhpUnitsOfMeasure\UnitOfMeasure;

class ViscosityDynamic extends AbstractPhysicalQuantity
{

    use HasSIUnitsTrait;

    protected static $unitDefinitions;

    protected static function initialize()
    {
        //kilogram per meter second
        $kgpms = UnitOfMeasure::nativeUnitFactory('kg/ms');
        $kgpms->addAlias('kilogram per meter second');
        $kgpms->addAlias('kilograms per meter second');
        $kgpms->addAlias('kilograms per meter seconds');
        static::addUnit($kgpms);

        //kilogram per meter hour
        $kgpmh = UnitOfMeasure::linearUnitFactory('kg/mh', 3600);
        $kgpmh->addAlias('kilogram per meter hour');
        $kgpmh->addAlias('kilograms per meter hour');
        $kgpmh->addAlias('kilograms per meter hours');
        static::addUnit($kgpmh);

        //pascal second
        $Pas = UnitOfMeasure::linearUnitFactory('Pa s', 1);
        $Pas->addAlias('pascal second');
        $Pas->addAlias('pascal seconds');
        $Pas->addAlias('Pa-s');
        $Pas->addAlias('N s/m^2');
        $Pas->addAlias('N s/m²');
        $Pas->addAlias('newton second per square meter');
        $Pas->addAlias('newton second per square meters');
        $Pas->addAlias('newton second per square metre');
        $Pas->addAlias('newton second per square metres');
        $Pas->addAlias('P1');
        $Pas->addAlias('poiseuille');
        static::addUnit($Pas);
        static::addMissingSIPrefixedUnits(
            $Pas,
            1,
            '%pPa s',
            [
                '%Ppascal second',
                '%Ppascal seconds',
                '%pPa-s'
            ]
        );

        //poise
        $poise = UnitOfMeasure::linearUnitFactory('P', 0.1);
        $poise->addAlias('poise');
        $poise->addAlias('poises');
        $poise->addAlias('g/cm s');
        $poise->addAlias('gram per centimeter second');
        $poise->addAlias('grams per centimeter second');
        $poise->addAlias('dyn s/cm^2');
        $poise->addAlias('dyn s/cm²');
        $poise->addAlias('dyne second per square centimeter');
        $poise->addAlias('dyne second per square centimetre');
        static::addUnit($poise);
        static::addMissingSIPrefixedUnits(
            $poise,
            1,
            '%pP',
            [
                '%Ppoise',
                '%Ppoises',
            ]
        );
 
       //reyn
        $reyn = UnitOfMeasure::linearUnitFactory('Re', 6894.75729);
        $reyn->addAlias('reyn');
        $reyn->addAlias('reyns');
        static::addUnit($reyn);
    }
}
use PhpUnitsOfMeasure\AbstractPhysicalQuantity;
use PhpUnitsOfMeasure\HasSIUnitsTrait;
use PhpUnitsOfMeasure\UnitOfMeasure;

class ViscosityKinematic extends AbstractPhysicalQuantity
{

    use HasSIUnitsTrait;

    protected static $unitDefinitions;

    protected static function initialize()
    {

        //square meter per second
        $smps = UnitOfMeasure::nativeUnitFactory('m^2/s');
        $smps->addAlias('m²/s');
        $smps->addAlias('square meter per second');
        $smps->addAlias('square meters per second');
        static::addUnit($smps);

        //stokes
        $stokes = UnitOfMeasure::linearUnitFactory('St', 1e-4);
        $stokes->addAlias('stokes');
        $stokes->addAlias('P cm^3/g');
        $stokes->addAlias('P cm³/g');
        $stokes->addAlias('poise cubic centimeter per gram');
        $stokes->addAlias('lentor');
        static::addUnit($stokes);
        static::addMissingSIPrefixedUnits($stokes,
            1,
            '%pSt',
            [
                '%Pstokes',
            ]
        );
     
        //add mm²/s as an alias of centistokes
        $cst = static::getUnit('cSt');
        $cst->addAlias('mm^2/s');
        $cst->addAlias('mm²/s');
        $cst->addAlias('square millimeter per second');
    }
}

Making `static::unitNameOfAliasesAlreadyRegistered` optional depending on environment

Can you think of the best way to make the uniqueness test in AbstractPhysicalQuantity::addUnit:24 optional? Profiling says this is by far the slowest part of the library. It's a great feature for development environment, but there's little reason to incur this penalty in production environment, especially with a proper CI set up.

Same applies for HasSIUnitsTrait::addMissingSIPrefixUnits:191.

Static create method

Thanks for the solid library.

What do you think about a static create method in the AbstractPhysicalQuantity class? Allowing: -

Length::create(6.16, 'feet')->toUnit('m');

It's obviously nothing major, I've just got a few cases where I begrudge having an extra line just to declare the Length object when all I want is a simple conversion.

Unit test coverage

Add more unit test coverage.

This is an on-going catch-all ticket, and will likely be open indefinitely.

php-units-of-measure should replace triplepoint

Hi. We were using triplepoint/php-units-of-measure which we're told is now deprecated so we switched to php-units-of-measure/php-units-of-measure. The problem is that the latter doesn't have a 'replace' directive for the former. As it stands when we pull in the latter it does so but it does not remove the former so we ended up with both and then the autoload building failed as there's two versions of each class.

Here's how I'd expect it to look in your composer.json:

"replace": {
    "triplepoint/php-units-of-measure": "*"
}

We've worked around this by manually calling composer remove triplepoint/php-units-of-measure.
[edit] Typo.

Add more units of measure

There are a lot of units of measure out there. Once the definition of transforms are nailed down (see #1), build out more useful quantities and units.

Some ideas:

  • Area
  • Volume
  • Mass
  • Time
  • Velocity
  • Energy

And I'm sure there's a ton more.

This is an on-going catch-all ticket, and will likely be open indefinitely.

Missing translations

Hi,
nice library.
By me, very usefull will be locatizations of units.
For example:
l => en=litre, de=liter, etc...

Reuse code for standardized metric units

Metric units have a common prefix mechanism for kilo-, mega-, giga-, etc, and then centi, milli-, etc, going smaller.

This raises an interesting idea regarding reuse of code in metric units. There are a lot of units that have base-10 metric conversion factors, and the PhysicalQuantity class for meters (for example) is going to end up having a lot of similar elements to grams, at least as far as conversion within the metric system goes.

Look into a code reuse pattern that brings the standardized kilo, mega, giga, etc conversions to a PhysicalQuantity. Maybe a "Metricifyable" trait?

It just doesn't work

I think there is something messed up with toUnit. Whatever I do, I can't get it to work.

$quantity = new \PhpUnitsOfMeasure\PhysicalQuantity\Mass(6, 'lbs');
$quantity->toUnit('g');
return $quantity;
// returns "6 lb"

or

use \PhpUnitsOfMeasure\PhysicalQuantity\Mass;

$quantity = new Mass(6, 'lbs');
$quantity->toUnit('g');
echo $quantity;
// prints "6 lb"

What am I doing wrong?

Improve documentation

The documentation is sparse, particularly around adding new units to per-existing quantities.

Autoloader?

First, great work on the library, looking forward to putting it to use!

Next, maybe I'm missing it, but where is the autoloader for this library? None of the examples refer to one, and there are many use statements throughout, but no corresponding include or require statements so without a lot of work manually loading all the dependencies, every call fails....without fail.

P.S. We're not using composer.

Use Brick/Math

Brick/Math keeps the focus of php-units-of-measure out of the math bit... It will use the fastest available math module installed whether that's BCMath or GMP or neither.

I'm looking to supply a PR for this. (working on it)

This would require a major version number change ... PHP 7.1 or newer is required
Version 0.5 handles older versions of PHP

Thanks for a great library!

Piece Measure Unit

how would you describe pieces? is it possible with this
i want to describe a piece that is equal to 1. i hope i make sense...

Reduce the PHP requirement for 1.3.x

I know you've moved on to 2.0.0. However I think it would be fair to make a point release to 1.3.x with the PHP requirement reduced to 5.3.2.

The problem is Ubuntu 10.04 (which is still supported) has PHP 5.3.2, which is fine for 1.3.x because the Ubuntu package is kept up to date with all the security patches in PHP 5.3.5 and later.

Km (Kilometer) support

Hi,

just looked a bit trough the code and it seems like there is no default support for km (kilometer/kilometers). 1000m = 1km.

Would you like to implement this?

Add support for derived physical quantities

Here, derived physical quantities are quantities that are defined in terms of other quantities. For example:
Velocity = Length / Time
Area = Length * Length
Acceleration = Length / Time / Time

Currently, derived quantities are treated no differently from "fundamental" quantities, meaning that there's a lot of duplicated effort when managing conversion factors. In addition, there's an opportunity for gaining new units when the fundamental quantity units are extended. For example, if we added "cubit" to the set of units for Length, we could automatically get Cubits/s^2 as a unit for Acceleration.

Figure out how to cleanly represent this relationship between quantities and implement it.

Add arithmetic operation methods

It should be possible to do basic arithmetic operations on quantities. For instance:

$a = new Length(6, 'ft');
$b = new Length(2, 'inches');

$height = $a->add($b);

echo $height->toUnit('m');  // Will print 6'2" in meters.

To start, add($x) and subtract($x) should be sufficient.

The methods should require that the parameter passed to these properties are the same as the class of the object on which the methods are called.

The methods should return a new object that represents the new quantity.

Add support for Torque Units

I need Torque Units in a project I'm working with.

I've forked the project, and will supply a PR (hopefully very soon)!

Just wanted an Issue to Push the PR against.

Thanks for the great and simple project!!!

List or verify if a unit exist in a given implementation

Hi all,

I'm thinking to create a method to verify if a given unit is available for a specific implementation (or at least to list all available units for that).

In my mind it can be very useful in:

  • applications where users have a greater flexibility (e.g. by defining new units, or directly typing a specific unit)
  • the "Transform" phase of an ETL process
  • applications that need to validate user inputs
  • conversion application (both for listing available units, or for verify if the free-text wrote by the user comply)

I saw the AbstractPhysicalQuantity::unitNameOrAliasesAlreadyRegistered(), but it is protected, so inaccesible from the external classes.

I have several options:

  1. to mark ::unitNameOrAliasesAlreadyRegistered() as public (in effect it is just a method for reading, so I think there ins't a too rigid cause to limit its visibility)
  2. to declare a PhysicalQuantityInterface::unitAlreadyExists($unitInString); its implementation can "wrap" (adding just a couple of line of code) the unitNameOrAliasesAlreadyRegistered()
  3. to declare a PhysicalQuantityInterface::unitAlreadyExists($unitStr); its implementation can directly access and loop over the the static::$unitDefinitions array
  4. to declare a PhysicalQuantityInterface::listExistingUnits(); its implementation can returns an array of strings with all the existing units for that implementation

I know users can access to ::getUnitDefinitions() and loop over the UnitOfMeasure objects, but it requires more effort for a developer.

If you think this feature(s) can be useful I can quickly code it... just tell me what solution do you think is more suitable for the library (one between 1/2/3 or/and 4)...

Constructure by Array of configuration

Hi,

Are we be able to change the constructor to get the array of configuration instead?

Currently, the method signature is this one
public function __construct($name, $from_native_unit, $to_native_unit, $aliases = array())

But I am going to add function to return multiple unit, translator into it

for multiple unit ex. input as 1000.23m , then it be able to return as array 1m + 23mm

Example here

public function testSIScalingUnit ()
    {
        $area = new Area(1000200.000304, 'm^2');
        $actual = $area->toScalingUnit(array('km^2', 'm^2', 'cm^2', 'mm^2'));
        $this->assertEquals(1, $actual['km^2']);
        $this->assertEquals(200, $actual['m^2']);
        $this->assertEquals(3, $actual['cm^2']);
        $this->assertEquals(4, $actual['mm^2']);
    }

Link

Get class for unit

Similar to #46, is there a way, without using each individual PhysicalQuantity class, to determine which specific PhysicalQuantity class an alias applies to? For example, I want to be able to do something like

// Would return a namespaced classname of \PhpUnitsOfMeasure\PhysicalQuantity\Mass
$className = UnitOfMeasure::getClassByAlias('kilogram');
// or
// Would return an instance of \PhpUnitsOfMeasure\PhysicalQuantity\Mass
$physicalQuantityObject = UnitOfMeasure::getObjectByAlias('kilogram');

I'm open to making a PR to do this, if there's interest. It would benefit me so that I don't have to cycle through each actual PhysicalQuantity class calling ::getUnit and checking for exceptions.

Use of closures is preventing serialization

There's a problem with your HasSIUnitsTrait class that effectively renders the entire class useless when serialization is required, unless we take the extra steps to write __sleep() and __wakeup() methods for every object in our system that we want to use your classes in.

Closures can not be serialized, and our use case is in a shipping system where we need to be able to cache (via serialization) our objects so we don't have to continually repeat API calls during each request.

However line 166 of HasSIUnitsTrait....

$parsePattern = function ($pattern) use ($prefixDefinition) {...}

... and the ensuing code, is incompatible and causing fatal errors.

Any suggestions to avoid having to use __sleep() and __wakeup() everywhere?

Implement concept of precision

Currently, the transform functions don't have any regard for significant digits and proper error calculation.

This is a complicated issue. Some conversions are defined as having infinite precision; for instance the inch is defined to be precisely 0.3048 meters, and so can be treated as being infinitely precise. In contrast, a furlong is stated on wikipedia as being approximately 201.168 meters, but that is not the exact definition of a furlong, and thus the precision is limited to 6 significant figures.

Figure out the best way to represent the error in these transformations, and make sure that the conversions respect the proper treatment of significant digits and precision.

PHP Version

Greetings,

A fix:

Since version 1.2.0 you have composer.json to use PHP >= 5.3.5. In that version you use array in short notation with bracket wich is not available since 5.4

Also, In version 1.3.3 you downgrade to PHP >= 5.3.0 wich is even worse due to in that version you use traits (also 5.4 feature)

I'm new to github, so I hope to be writing in the right place

How do I..

How do I populate a list with mass conversion units. To allow the user the ability to select which measure they wish to convert?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.