Unit Conversion
Unit conversion is a fundamental operation in quantity formatting and parsing. Understanding how conversions work helps you correctly handle quantity values across different unit systems.
UnitConversionSpec
Unit conversion is performed through a UnitConversionSpec. These objects encapsulate the conversion factors and offsets needed to convert a value from one unit to another.
How UnitConversionSpec Works
Unit conversions are applied through the following steps:
- Pre-conversion inversion (if
inversion === InvertPreConversion):value = 1/value - Apply factor and offset:
value = (value * factor) + offset - Post-conversion inversion (if
inversion === InvertPostConversion):value = 1/value
For most unit conversions (length, angle, area, etc.), only the factor is used (offset and inversion are zero/undefined). Temperature conversions use non-zero offsets. Inversion is used when converting to or from inverted units - An example would be dimensionless ratios where one unit is the mathematical inverse of another (e.g., vertical-per-horizontal slope ↔ horizontal-per-vertical slope).
Generating UnitConversionSpec
UnitConversionSpec objects are created from UnitConversionProps returned by a UnitsProvider. The provider's getConversion method calculates conversion properties based on unit definitions:
- BasicUnitsProvider - Uses hardcoded conversion factors for common units
- SchemaUnitProvider - Calculates conversions from EC schema unit definitions
- Custom providers - Can implement custom conversion logic
The FormatterSpec and ParserSpec classes create UnitConversionSpec instances from these properties during initialization.
When Conversions Are Cached
During initialization of FormatterSpec and ParserSpec, they request and cache UnitConversionSpec objects from the UnitsProvider:
- FormatterSpec - Caches conversions from persistence unit to all format display units
- ParserSpec - Caches conversions from all units in the phenomenon to the persistence unit
This caching strategy:
- Eliminates async calls during formatting/parsing operations
- Improves performance for repeated operations
- Ensures consistent conversions throughout the spec's lifetime
Conversion in Formatting
When formatting a quantity value:
- The value starts in the persistence unit (e.g., meters)
- The
FormatterSpecapplies the cachedUnitConversionSpecfor each display unit - For composite formats, each sub-unit conversion is applied in sequence
- The converted values are formatted according to the format specification
Example: Converting 1.5 meters to feet-inches, given a FormatProps that uses fractional, composite unit of feet and inches
Conversion in Parsing
When parsing a string to a quantity value:
- The string is tokenized to extract values and unit labels
- For each unit label, the appropriate
UnitConversionSpecis retrieved from the cached specs - Each value is converted to the persistence unit
- For composite values, converted sub-unit values are summed
- The final result is returned in the persistence unit
Example: Parsing "4'-11 1/16"" to meters, given a FormatProps that uses fractional, composite unit of feet and inches
Unit Family Validation
Before converting, the UnitsProvider validates that both units belong to the same phenomenon (unit family):
- ✅ Valid: Length (meters) → Length (feet)
- ✅ Valid: Angle (radians) → Angle (degrees)
- ❌ Invalid: Length (meters) → Angle (degrees)
Attempting to convert between incompatible phenomena will result in an error.
Performance Considerations
To optimize conversion performance:
- Reuse specs - Create FormatterSpec and ParserSpec once and reuse them (e.g., store as class instance properties) rather than recreating on each operation
- Batch operations - Format/parse multiple values with the same spec
- Cache providers - Don't recreate UnitsProvider instances unnecessarily
- Use schema providers - SchemaUnitProvider is more comprehensive than BasicUnitsProvider
Example: Direct Unit Conversion
While most conversions happen automatically through FormatterSpec and ParserSpec, you can also request conversions directly from a UnitsProvider:
See Also
- Units - Understanding unit definitions and phenomena
- Providers - UnitsProvider implementations
- Parsing and Formatting - How conversions are applied during formatting/parsing
- Parser and Formatter - Core implementation classes for formatting/parsing
Last Updated: 23 January, 2026