galaxon / quantities
Contains classes for working with measurements such as angles, lengths, etc.
Requires
- php: ^8.4
- galaxon/core: ^1.0
Requires (Dev)
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- galaxon/coding-standard: @dev
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0 || ^11.0 || ^12.0
- squizlabs/php_codesniffer: ^4.0
README
This package enables calculations and conversions with physical and non-physical quantities, including support for SI and other systems of units (including data and currencies), metric and binary prefixes, parsing, and formatting.
License | Changelog | Documentation | Examples
Description
This package provides strongly-typed classes for physical quantities (length, mass, time, temperature, etc.) and some non-physical quantities (data, money), with comprehensive unit conversion capabilities. The system automatically finds conversion factors between compatible units, supports metric and binary prefixes, and handles offsets for temperature scales.
Key capabilities include:
- Type-safe measurements: Each measurement type (Length, Mass, Time, etc.) is a separate class. You can easily create your own custom quantity type classes.
- Automatic conversion: Easily convert between any compatible units, with most common units built-in, including SI, imperial, US customary, scientific, nautical, CSS, and more.
- Prefix support: Full support for SI metric and binary prefixes.
- Arithmetic operations: Add, subtract, multiply, and divide quantities with automatic unit handling.
- Flexible parsing: Parse strings like "123.45 km", "90deg", or "25°C" into Quantity objects.
- String formatting: Format quantities as ASCII or Unicode, with configurable decimal places and locale-specific currency formatting.
- Part decomposition: Break measurements into components (e.g. 12° 34′ 56″ or 1y 3mo 2d).
- Physical constants: Built-in constants like the speed of light, Planck's constant, and Avogadro's number as Quantity objects.
- Up-to-date exchange rates: Updated automatically as needed using the exchange rate API of your choice.
Development and Quality Assurance / AI Disclosure
Claude Chat and Claude Code were used in the development of this package. The core classes were designed, coded, and commented primarily by the author, with Claude providing substantial assistance with code review, suggesting improvements, debugging, and generating tests and documentation. All code was thoroughly reviewed by the author, and validated using industry-standard tools including PHP_Codesniffer, PHPStan (to level 9), and PHPUnit to ensure full compliance with PSR-12 coding standards and comprehensive unit testing with 100% code coverage. This collaborative approach resulted in a well-designed, production-quality, thoroughly-tested, and well-documented package delivered in significantly less time than with traditional development methods.
Requirements
- PHP ^8.4
- galaxon/core
Installation
composer require galaxon/quantities
Quick Start
use Galaxon\Quantities\QuantityType\Length; use Galaxon\Quantities\QuantityType\Temperature; use Galaxon\Quantities\QuantityType\Angle; // Create measurements $distance = new Length(5, 'km'); $temp = new Temperature(25, 'degC'); $angle = new Angle(90, 'deg'); $price = new Money(4269, 'EUR'); // Convert between units $miles = $distance->to('mi'); // 3.10686... miles $fahrenheit = $temp->to('degF'); // 77°F $radians = $angle->to('rad'); // 1.5707... rad $dollars = $price->to('USD'); // e.g. 4621 USD // Convert to SI units $force = new Force(28000, 'lbf'); $force = $force->toSi(); // 124... kN $force = $force->toSiBase(); // 124550... kg⋅m/s² // Arithmetic operations $total = $distance->add(new Length(500, 'm')); // 5.5 km $doubled = $distance->mul(2.0); // 10 km $period = new Frequency(2.4, 'GHz')->inv()->toSi(); // 416.7... ps // Physical constants $h = PhysicalConstant::planck(); $c = PhysicalConstant::speedOfLight(); // Scientific and engineering calculations $G = PhysicalConstant::gravitational(); $earthMass = new Mass(5.972e24, 'kg'); $moonMass = new Mass(7.342e22, 'kg'); $distance = new Length(3.844e8, 'm'); $force = $G->mul($earthMass)->mul($moonMass)->div($distance->sqr()); echo $force->to('N')->format('e', 2), "\n"; // 1.98×10²⁰ N // Parse from strings $length = Length::parse('123.45 km'); $temp = Temperature::parse('98.6°F'); $angle = Angle::parse("45° 30' 15\""); // Format as parts $angle = new Angle(45.5042, 'deg'); echo $angle->formatParts(precision: 1); // "45° 30′ 15.1″"
Developer Guide
- Concepts
- Terminology — Key terms and definitions used throughout the library.
- Units — Complete reference of all built-in units organised by quantity type.
- Dimensions and Base Units — Dimension codes, base units, and how the library tracks physical dimensions.
- Quantity Types — Typed quantity classes like Length, Mass, and Force, and how they map to dimensions.
- Prefixes — Metric, engineering, and binary prefixes for scaling units.
- Systems of Units — SI, imperial, US customary, and other unit systems.
- Physical Constants — Built-in physical constants as Quantity objects.
- Working with Quantities
- Creating Quantities — Creating new quantities with constructors and the factory method.
- Unit Conversion — Converting between units, expansion, simplification, and auto-prefixing.
- Arithmetic Operations — Add, subtract, multiply, and divide quantities.
- Calculation Examples — Real-world physics and engineering calculations.
- Currency Calculations — Example conversions and calculations involving currencies.
- Comparison Functions — Exact and approximate equality, ordering, and tolerances.
- String Functions — Parsing strings into quantities and formatting output (ASCII and Unicode).
- Part Decomposition — Working with quantities as parts (e.g. 45° 30′ 15″ or 1h 30min 45s).
- Customization — Adding custom units, conversions, and quantity type classes.
Reference
Main Public API
Other than the quantity type classes (below), these are the main classes you'll use.
| Class | Description |
|---|---|
| Quantity | Abstract base class for all measurement types. Provides unit conversion, arithmetic operations, comparison, formatting, and part decomposition. |
| PhysicalConstant | Access to physical constants (speed of light, Planck constant, etc.) as Quantity objects. |
| UnitSystem | Enum for systems of units (SI, Imperial, US Customary, etc.). |
Quantity Types
All quantity type classes extend Quantity and define their specific units and conversions. See Units for a complete reference of all built-in units organized by quantity type.
| Class | Dimension | SI or common base unit | Description |
|---|---|---|---|
| Acceleration | T-2L | m/s² | Rate of change of velocity. |
| AmountOfSubstance | N | mol | SI base quantity for counting entities. |
| Angle | A | rad | Angular measurements with trig functions. |
| Area | L2 | m² | Two-dimensional extent. |
| Capacitance | T4I2L-2M-1 | F | Ability to store electric charge. |
| CatalyticActivity | T-1N | kat | Rate of catalysis. |
| Conductance | T3I2L-2M-1 | S | Electrical conductance. |
| Data | D | B | Digital storage with metric and binary prefixes. |
| Density | L-3M | kg/m³ | Mass per unit volume. |
| Dimensionless | empty | empty | Ratios, percentages, and pure numbers. |
| ElectricCharge | TI | C | Quantity of electricity. |
| ElectricCurrent | I | A | SI base quantity for electric current. |
| Energy | T-2L2M | J | Capacity to do work. |
| Force | T-2LM | N | Interaction causing acceleration. |
| Frequency | T-1 | Hz, Bq | Cycles per unit time. |
| Illuminance | L-2J | lx | Luminous flux per area. |
| Inductance | T-2L2MI-2 | H | Property opposing current change. |
| Length | L | m | SI base quantity for distance. |
| LuminousFlux | AJ | lm | Perceived light power. |
| LuminousIntensity | J | cd | SI base quantity for luminous intensity. |
| MagneticFlux | T-2L2MI-1 | Wb | Total magnetic field through surface. |
| MagneticFluxDensity | T-2MI-1 | T | Magnetic field strength. |
| Mass | M | kg | SI base quantity for mass. |
| Money | C | XAU | Currency conversions and calculations. |
| Power | T-3L2M | W | Rate of energy transfer. |
| Pressure | T-2L-1M | Pa | Force per unit area. |
| RadiationDose | T-2L2 | Gy, Sv | Absorbed and equivalent radiation dose. |
| Resistance | T-3L2MI-2 | Ω | Opposition to electric current. |
| SolidAngle | A2 | sr | Three-dimensional angular extent. |
| Temperature | H | K | SI base quantity with affine conversions. |
| Time | T | s | SI base quantity for duration. |
| Velocity | T-1L | m/s | Rate of change of position. |
| Voltage | T-3L2MI-1 | V | Electric potential difference. |
| Volume | L3 | m³ | Three-dimensional extent. |
Services
These classes are predominantly internal, except for adding custom units via UnitService::add(), or registering new quantity types via QuantityTypeService::add().
| Class | Description |
|---|---|
| UnitService | Manages units and unit systems. Provides lazy loading and lookup methods. |
| ConversionService | Manages unit conversions and converters. |
| QuantityTypeService | Manages quantity types with their dimensions and classes. |
| PrefixService | Manages SI and binary prefixes (lookup, filtering by group). |
| DimensionService | Utilities for working with physical dimension codes (validation, composition, transformation). |
| QuantityPartsService | Decomposes quantities into parts (e.g. hours, minutes, seconds). |
| RegexService | Centralised regex patterns and validation for unit symbols. |
Internal Classes
These classes provide the core functionality of the library and will typically not be used directly by end-users.
| Class | Description |
|---|---|
| Unit | Represents a single-symbol measurement unit with optional prefix support. |
| UnitTerm | A unit with optional prefix and exponent (e.g., km², ms⁻¹). |
| DerivedUnit | Compound unit expression combining unit terms via multiplication/division. |
| Prefix | SI metric and binary prefixes (kilo, mega, kibi, etc.). |
| Conversion | Represents a unit conversion with factor and error tracking. |
| Converter | Graph-based algorithm for finding conversion paths between units. |
| FloatWithError | Floating-point numbers with tracked error bounds for precision monitoring. |
| QuantityType | Data class representing a quantity type with its dimension, SI unit, and PHP class. |
| UnitInterface | Interface implemented by Unit, UnitTerm, and DerivedUnit. |
Exceptions
Custom exception types to provide additional context when needed. Both extend DomainException, as they relate to provided values being outside a valid domain.
| Class | Description |
|---|---|
| UnknownUnitException | Thrown when a unit symbol cannot be resolved. |
| DimensionMismatchException | Thrown when units have incompatible dimensions. |
Currency Classes
Classes for currency data management and exchange rate integration.
| Class | Description |
|---|---|
| CurrencyService | Manages currency unit data and exchange rate conversions. |
| ExchangeRateServiceInterface | Contract for exchange rate providers. |
| CurrencyLayerService | CurrencyLayer API (USD-based, 1,000 req/month free). |
| ExchangeRateApiService | ExchangeRate-API (any base currency, 1,500 req/month free). |
| FixerService | Fixer.io API (EUR-based, 10,000 req/month free). |
| FrankfurterService | Frankfurter API (ECB data, completely free, no API key). |
| OpenExchangeRatesService | Open Exchange Rates API (USD-based, free tier available). |
Testing
The library includes comprehensive test coverage:
# Run all tests vendor/bin/phpunit # Run specific test class vendor/bin/phpunit tests/QuantityTest.php # Run with coverage (generates HTML report and clover.xml) composer test
License
MIT License - see LICENSE for details
Support
- Issues: https://github.com/mossy2100/PHP-Quantities/issues
- Documentation: See docs/ directory for detailed class documentation
For questions or suggestions, please open an issue.
Changelog
See CHANGELOG.md for version history and changes.
