Giter Site home page Giter Site logo

jordanbrauer / unit-converter Goto Github PK

View Code? Open in Web Editor NEW
128.0 5.0 39.0 20.77 MB

Convert standard units from one to another with this easy to use, lightweight package

Home Page: https://jordanbrauer.github.io/unit-converter/

License: MIT License

PHP 99.65% Makefile 0.35%
php package library component composer unit-converter unit-conversion php7 oop measurements

unit-converter's Introduction

Unit Converter

Latest Stable Version Latest Unstable Version PHP from Packagist composer.lock available license

CI Workflow Code Maintainability Code Coverage Technical Debt Maintenance Packagist


Convert all kinds of standard units of measurement from one to another with this highly customizable, easy to use, lightweight PHP component.

Table of Contents:

  1. About the Component
  2. Installing the Component
  3. Basic Usage
  4. Documentation

1. About the Component

This unit converter component aims to be modern and follow best practices. It also aims to be fully SI compliant (eventually...).

It supports the following types of measurement by default (support for more measurement types are on the roadmap).

  • Area
  • Data Transfer Rates Coming Soon!
  • Digital Storage New!
  • Energy (Power)
  • Frequency
  • Fuel Economy
  • Length
  • Mass (Weight)
  • Plane Angle (Rotation)
  • Pressure
  • Speed
  • Temperature
  • Time
  • Volume

You also have the ability to override & customize the default units, as well as add your own!

2. Installing the Component

The best way to install the component is with Composer. For other supported methods, see the wiki artile on installation.

$ composer require jordanbrauer/unit-converter

3. Basic Usage

Using the component is very easy, especially if you have used the Symfony or Laravel frameworks before.

Quick-Start

If you'd like to skip the minutiae of this component's setup and get right down to business, you can get started by constructing a pre-configured converter via static constructors or the builder object, like so,

Static Constructors
use UnitConverter\UnitConverter;

$converter = UnitConverter::default(); # simple calculator
$converter = UnitConverter::binary(); # binary calculator (BC math)
Builder
use UnitConverter\UnitConverter;

$converter = UnitConverter::createBuilder()
    ->addSimpleCalculator()
    ->addDefaultRegistry()
    ->build();

and use it like this,

$converter->convert(1)->from("in")->to("cm"); # (float) 2.54

and you're done! For a more in-depth setup guide, check the wiki.

Usage Examples

Here are where some usage examples of something that may fit more along the lines of "real-life", are found. Keep in mind that the code examples in each use-case, while working & valid, do contain some pseudo-code in them for demonstration purposes.

The Traffic Camera

In this example, pretend we have a traffic camera that only captures speeds in Imperial measurement of miles per hour. The traffic camera records each passing car's speed to determine if they were speeding & if so, snap a photo of their license plate as proof to serve a ticket. In this case, the camera caught a speed of 59 miles per hour.

Here we construct a new unit & give it a value representing how many of the unit exists,

$capturedSpeed = new MilePerHour(59);

Next, a conversion of units needs to take place, because this traffic camera model is being used in a country that uses the metric system.

As you can see in this example, we are leveraging the power of typehints to ensure we only receive units of the desired measurement. Inside of the closure, we are using one of the unit's most convenient & powerful methods: as(). It allows us to convert units without the direct use of the UnitConverter & UnitRegistry objects โ€“ giving the benefit of even cleaner code & type safety.

$isOverSpeedLimit = function (SpeedUnit $speed) {
    return $speed->as(new KilometrePerHour) > 50;
};

if ($isOverSpeedLimit($capturedSpeed)) { # (bool) true
    TrafficCamera::snapPhoto();
}

Conversion Results as Words

Sometimes you might need localization support for values. This component makes that a breeze by making using the intl extension. Simply opt for using the spellout method in lieu of to. You may also provide an optional locale as the second parameter to translate.

$converter->convert(1)->from('in')->spellout('cm');       # (string) two point five four
$converter->convert(1)->from('in')->spellout('cm', 'fr'); # (string) deux virgule cinq quatre

4. Documentation

There are two kinds of in-depth documentation for this project: user & API documentation. Use whichever one you need to help answer your questions!

User Documentation

Setup guides, in-depth examples, tutorials, and explanations on the component for users who are looking to integrate it into their project, as-is.

User Documentation

API Documentation

If you are looking to extend and hack on this component for your own project, these pages will give you insight into all about how the component works, through the awesome power of dockblocks!

API Documentation

unit-converter's People

Contributors

andrejsstepanovs avatar booni3 avatar cezam avatar dependabot[bot] avatar elliotwms avatar fakhruu avatar jmauerhan avatar jordanbrauer avatar laurent35240 avatar mammutalex avatar martianoff avatar ocramius avatar progi1984 avatar proualexandre avatar r3l4x3 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

unit-converter's Issues

Implement new Unit property "siUnit" to indicate the units SI acceptance

As part of the effort to enforce a standard for unit symbol/notations (#45), I think it would be a good idea to include as much metadata as possible about a unit of measure.

Specifications

  • This enhancement should include an accompanying test(s).
  • Property should be protected.
  • Property should have the name siUnit.
  • Property should be of type bool.
  • Property should have matching setter and isser methods that return UnitInterface & bool respectively.

Add support for units of measurement, Frequency

Frequency

namespace UnitConverter\Unit\Frequency;

Units of Frequency (Multiples)

  • hertz (Hz) = 1
  • kilohertz (kHz) = 1000
  • megahertz (MHz) = 1000000
  • gigahertz (GHz) = 1000000000
  • terahertz (THz) = 1000000000000

Units of Frequency (Sub-multiples)

  • millihertz (mHz) = 0.001

Add methods to Time units for determining leaps

Summary

Currently the time units for months and years assume that all years and months are the exact same length of time, which everyone know's is not true. We should remedy this by adding some helper methods to Time units. Perhaps, they need to implement the calculate method.

See #38 for an example that was submitted, but never followed up on by the person. ๐Ÿ™

Basic units of measurement for Time

Thanks @teunw for adding the basic time units via #35!

namespace UnitConverter\Unit\Time;

  • Millisecond = ms
  • Second = s
  • Hour = hr
  • Minute = min
  • Day = day
  • Month (31 days) = month
  • Microsecond = ฮผs
  • Nanosecond = ns
  • Week = week
  • Year (365 days) = year

Add PHP CS Fixer to project

This will remove the worry for formatting during development.

It should ideally be set as a pre-commit hook (see Composer Git Hooks, or Husky JS, for no-config setup). Worst cases Ontario, we set it as a release step in the Robofile.

Custom ErrorException classes would be nice

Currently all errors/exceptions are being thrown as ErrorException. I'd like to have some explicit error classes for the needs of the converter.

E.g.,

  • UnknownMeasurementErrorException
  • UnknownUnitErrorException
  • MissingRegistryErrorException

Basic units of measurement for Area

namespace UnitConverter\Unit\Area;

  • Acre = ac
  • Hectare = ha
  • Square Centimeter = cm2
  • Square Foot = ft2
  • Square Kilometer = km2
  • Square Meter = m2
  • Square Mile = mi2
  • Square Millimeter = mm2

Add support for units of measurement, Digital Storage

Digital Storage

namespace UnitConverter\Unit\DigitalStorage

  • The abstract DigitalStorageUnit class exists for all subsequent data transfer rate units to extend from.
    • It declares the protected property $baseUnit as Bit::class.
    • It declares the protected property $unitOf as Measure::DIGITAL_STORAGE.

Bit Storage Units (Decimal)

  • bit (b) = 1
  • kilobit (kb) = 1000
  • megabit (Mb) = 1000000
  • gigabit (Gb) = 1000000000
  • terabit (Tb) = 1000000000000

Bit Storage Units (Binary)

  • kibibit (Kib) = 1024
  • mebibit (Mib) = 1049000
  • gibibit (Gib) = 1074000000
  • tebibit (Tib) = 1100000000000

Byte Storage Units (Decimal)

  • byte (B) = 8
  • kilobyte (kB) = 8000
  • megabyte (MB) = 8000000
  • gigabyte (GB) = 8000000000
  • terabyte (TB) = 8000000000000

[7.0.1][FatalErrorException] BinaryCalculator::round must be compatible with UnitConverter\Calculator\AbstractCalculator::round

Currently I can't run my code because the BinaryCalculator's round method doesn't match the AbstractCalculator's round method signature (abstract requires float, while binary returns string).

Console error message:
Declaration of UnitConverter\Calculator\BinaryCalculator::round($value, ?int $precision = NULL): string must be compatible with UnitConverter\Calculator\AbstractCalculator::round($value, ?int $precision = NULL): float

Self-converting units (such as temperature) are not logged

Steps to Reproduce

  1. Setup a simple converter.
$converter = UnitConverter::createBuilder()
    ->addSimpleCalculator()
    ->addDefaultRegistry()
    ->build();
  1. Run a few conversions, making sure that one of them is a temperature conversion (or some other self-converting measurement).
$converter->convert(10)->from('yd')->to('m');
$converter->convert(10)->from('lb')->to('g');
$converter->convert(10)->from('C')->to('F'); # problem child right here
  1. Finally, dump the conversion log to get a report of the calculations made during the converter's lifecycle.
dump($converter->getConversionLog());

Expected Result

The conversion log should contain all three calculations, not just the first two.

Actual Result

The conversion log contains only the first two calculations. It is missing the

[
    [
        {
            "operator": "multiply",
            "parameters": {
                "left": "10",
                "right": 0.91439999999999999058530875117867253720760345458984375
            },
            "result": 9.1440000000000001278976924368180334568023681640625
        },
        {
            "operator": "divide",
            "parameters": {
                "left": 9.1440000000000001278976924368180334568023681640625,
                "right": 1
            },
            "result": 9.1440000000000001278976924368180334568023681640625
        },
        {
            "operator": "round",
            "parameters": {
                "value": 9.1440000000000001278976924368180334568023681640625,
                "precision": null
            },
            "result": 9.1400000000000005684341886080801486968994140625
        }
    ],
    [
        {
            "operator": "multiply",
            "parameters": {
                "left": "10",
                "right": 0.453591999999999995196731106261722743511199951171875
            },
            "result": 4.53591999999999995196731106261722743511199951171875
        },
        {
            "operator": "divide",
            "parameters": {
                "left": 4.53591999999999995196731106261722743511199951171875,
                "right": 0.001000000000000000020816681711721685132943093776702880859375
            },
            "result": 4535.920000000000072759576141834259033203125
        },
        {
            "operator": "round",
            "parameters": {
                "value": 4535.920000000000072759576141834259033203125,
                "precision": null
            },
            "result": 4535.920000000000072759576141834259033203125
        }
    ]
]

Add new unit property, "scientificSymbol" for special unicode character symbols

Could be useful for when needing to output symbols as scientific notation rather than "shorthand notation", especially because typing special unicode characters is not fun.

See #45 for more details (very related + answers to "problem" in PDFs).

Specs

  • The property should be added to the UnitConverter\Unit\AbstractUnit abstract class.
  • The property should be of type string.
  • The property should have matching setter method;
public function setScientificSymbol (string $scientificSymbol) : UnitInterface;
  • The property should have matching getter method;
public function getScientificSymbol () : string;

Implement indication of metric(si)/imperial systems

Could probably be done at the class level, e.g.,

use LengthUnit;

abstract class MetricLengthUnit extends LengthUnit;

abstract class ImperialLengthUnit extends LengthUnit;

Not sure though - just an idea.

Dev documentation for API + examples

Currently have PHPUnit 2.9 hooked up. I am not a fan of any of their themes however, and their docs are extremely lacking... All I know (for now) is that they use Twig for their templates /shrug.

Performance metrics/benchmarks?

It would be pretty cool to have some sort of performance metrics for this package. It could also help make it "competitive" for use in production.

Add support for units of measurement, Data Transfer Rate

Data Transfer Rate

namespace UnitConverter\Unit\DataTransferRate

  • The abstract DataTransferRateUnit class exists for all subsequent data transfer rate units to extend from.
    • It declares the protected property $baseUnit as BitPerSecond::class.
    • It declares the protected property $unitOf as Measure::DATA_TRANSFER_RATE.

Bit Transfer Rate Units (Decimal)

  • bit per second (bit/s) = 1
  • kilobit per second (kbit/s) = 1000
  • megabit per second (Mbit/s) = 1000000
  • gigabit per second (Gbit/s) = 1000000000
  • terabit per second (Tbit/s) = 1000000000000

Bit Transfer Rate Units (Binary)

  • kibibit per second (Kibit/s) = 1024
  • mebibit per second (Mibit/s) = 1049000
  • gibibit per second (Gibit/s) = 1074000000
  • tebibit per second (Tibit/s) = 1100000000000

Byte Transfer Rate Units (Decimal)

  • byte per second (B/s) = 8
  • kilobyte per second (kB/s) = 8000
  • megabyte per second (MB/s) = 8000000
  • gigabyte per second (GB/s) = 8000000000
  • terabyte per second (TB/s) = 8000000000000

List all suported units

Does a method exist to list all the units currently supported by the librarie ? If not, i think implement it will be a good improuvment. I know the listMesurements method of the UnitRegistry class but it seems to list only the kind of unit, like length or speed, but not the unit itself.

Add support for units of measurement, Fuel Economy

Fuel Economy

namespace UnitConverter\Unit\FuelEconomy;

Units of Fuel Economy

  • kilometre per litre (km/l) = 1
  • miles per gallon (US) (mpg) = 2.35215
  • miles per gallon (UK) (mpg) = 2.82481
  • litre per 100 kilometres (L/100km) = 100

Code style updates

Summary

Fix some code styling, and perhaps add additional guidelines to the CONTRIBUTING.md document.

  • Move declare (strict_types = 1); statements to the same line as the opening <?php tag, like so:
<?php declare(strict_types = 1);
# ...
  • Update docblocks by adding missing explanations for intellisense and APIgen.
  • Add nullables to appropriate return types, e.g., public function foo (string $bar): ?string
  • Update the @copyright docblock tags in file header comments.

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.