Note
This is one of 199 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.
🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️
- About
- Status
- Installation
- Dependencies
- API
- Authors
- License
Extensible SI unit creation, conversions, quantities & calculations (incl. ~170 predefined units & constants).
All unit definitions, quantities & conversions are based on the SI unit system & concepts described here:
- https://en.wikipedia.org/wiki/International_System_of_Units
- https://en.wikipedia.org/wiki/SI_base_unit
- https://en.wikipedia.org/wiki/SI_derived_unit
- https://en.wikipedia.org/wiki/Coherence_(units_of_measurement)
- https://en.wikipedia.org/wiki/Metric_prefix
The overall conversion approach is inspired & partially based on:
Each unit is defined via a 7-dimensional vector representing individual exponents for each of the SI base unit dimensions, in order:
id | SI dimension | Base unit | Base unit symbol |
---|---|---|---|
0 | mass | kilogram | kg |
1 | length | meter | m |
2 | time | second | s |
3 | current | ampere | A |
4 | temperature | kelvin | K |
5 | amount of substance | mole | mol |
6 | luminous intensity | candela | cd |
Dimensionless units (e.g. radian, byte) are supported too and represented by a vector with all dimensions set to zero.
Additionally, we also define a scale factor and zero offset for each unit, with most dimensions' base units usually using a factor of 1 and no offset.
For example, here's how we can define kilograms and meters:
import { coherent, unit } from "@thi.ng/units";
// kilogram, SI dimension 0
const KG = coherent(0);
// { dim: [ 1, 0, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }
// meters, SI dimension 1
const M = coherent(1);
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }
// kelvin, SI dimension 4 (here without syntax sugar)
const K = unit(4, 1, 0, true);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ], scale: 1, offset: 0, coherent: true }
// fahrenheit, SI dim 4 with custom scale factor and zero offset
const F = unit(4, 1 / 1.8, 459.67 / 1.8);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ], scale: 0.5555, offset: 255.3722, coherent: false }
More complex units like electrical resistance (e.g. ohm) are based on more than a single dimension:
import { div, A, V } from "@thi.ng/units";
// ohm = volt / ampere
div(V, A)
// { dim: [ 1, 2, -3, -2, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }
This dimension vector represents the unit definition for (see SI derived units):
Ω = kg⋅m2⋅s−3⋅A−2
Btw. The
formatSI()
function can be used to format a unit's dimension vector:
import { div, formatSI, A, V } from "@thi.ng/units";
formatSI(div(V, A));
// "kg·m2·s-3·A-2"
The following units are provided as "builtins", here grouped by dimension:
Unit name | Variable name | Description |
---|---|---|
m/s2 |
m_s2 |
meter per second squared |
ft/s2 |
ft_s2 |
foot per second squared |
rad/s2 |
rad_s2 |
radian per second squared |
g0 |
g0 |
standard gravity |
Unit name | Variable name | Description |
---|---|---|
arcmin |
arcmin |
arc minute |
arcsec |
arcsec |
arc second |
deg |
deg |
degree |
gon |
gon |
gradian |
rad |
rad |
radian |
sr |
sr |
steradian |
turn |
turn |
turn |
Unit name | Variable name | Description |
---|---|---|
m2 |
m2 |
square meter |
cm2 |
cm2 |
square centimeter |
mm2 |
mm2 |
square millimeter |
km2 |
km2 |
square kilometer |
ha |
ha |
hectar |
ac |
ac |
acre |
sqin |
sqin |
square inch |
sqft |
sqft |
square foot |
sqmi |
sqmi |
square mile |
Unit name | Variable name | Description |
---|---|---|
bit |
bit |
bit |
kbit |
kbit |
kilobit |
Mbit |
Mbit |
megabit |
Gbit |
Gbit |
gigabit |
Tbit |
Tbit |
terabit |
kibit |
kibit |
kibibit (1024) |
Mibit |
Mibit |
mebibit (1024) |
Gibit |
Gibit |
gibibit (1024) |
Tibit |
Tibit |
tebibit (1024) |
B |
B |
byte (8 bit) |
kB |
kB |
kilobyte (metric) |
MB |
MB |
megabyte (metric) |
GB |
GB |
gigabyte (metric) |
TB |
TB |
terabyte (metric) |
PB |
PB |
petabyte (metric) |
EB |
EB |
exabyte (metric) |
KiB |
KiB |
kibibyte (1024) |
MiB |
MiB |
mebibyte (1024) |
GiB |
GiB |
gibibyte (1024) |
TiB |
TiB |
tebibyte (1024) |
PiB |
PiB |
pebibyte (1024) |
EiB |
EiB |
exbibyte (1024) |
Unit | Variable name | Description |
---|---|---|
kg/m3 |
kg_m3 |
density |
1/inch |
dpi |
dots per inch |
Unit | Variable name | Description |
---|---|---|
A |
A |
ampere |
mA |
mA |
milliampere |
mAh |
mAh |
milliampere-hours |
C |
C |
coulomb |
V |
V |
volt |
mV |
mV |
millivolt |
kV |
kV |
kilovolt |
MV |
MV |
megavolt |
F |
F |
farad |
pF |
pF |
picofarad |
µF |
µF |
microfarad |
Ω |
Ω / ohm |
ohm |
kΩ |
kΩ / kohm |
kiloohm |
MΩ |
MΩ / Mohm |
megaohm |
GΩ |
GΩ / Gohm |
gigaohm |
S |
S |
siemens |
Wb |
Wb |
weber |
T |
T |
tesla |
H |
H |
henry |
Unit | Variable name | Description |
---|---|---|
J |
J |
joule |
kJ |
kJ |
kilojoule |
MJ |
MJ |
megajoule |
GJ |
GJ |
gigajoule |
cal |
cal |
calorie |
kcal |
kcal |
kilocalorie |
Unit | Variable name | Description |
---|---|---|
N |
N |
newton |
Unit | Variable name | Description |
---|---|---|
Hz |
Hz |
hertz |
kHz |
KHz |
kilohertz |
MHz |
MHz |
megahertz |
GHz |
GHz |
gigahertz |
THz |
THz |
terahertz |
rpm |
rpm |
rotation per minute |
ω |
ω / omega |
radian per second |
Unit name | Variable name | Description |
---|---|---|
m |
m |
meter |
Å |
angstrom |
angstrom |
nm |
nm |
nanometer |
µm |
µm |
micrometer |
mm |
mm |
millimeter |
cm |
cm |
centimeter |
km |
km |
kilometer |
au |
au |
astronomical unit |
pc |
pc |
parsec |
ly |
ly |
light year |
in |
in |
inch |
mil |
mil / thou |
1/1000th inch |
ft |
ft |
foot |
yd |
yd |
yard |
mi |
mi |
mile |
nmi |
nmi |
nautical mile |
pica |
pica |
pica |
point |
point |
point |
Unit | Variable name | Description |
---|---|---|
cd |
cd |
candela |
lm |
lm |
lumen |
lx |
lx |
lux |
Unit name | Variable name | Description |
---|---|---|
µg |
µg |
microgram |
mg |
mg |
milligram |
g |
g |
gram |
kg |
kg |
kilogram |
t |
t |
tonne |
kt |
kt |
kilotonne |
Mt |
Mt |
megatonne |
Gt |
Gt |
gigatonne |
lb |
lb |
imperial pound |
st |
st |
stone |
https://en.wikipedia.org/wiki/Parts-per_notation
Unit name | Variable name | Description |
---|---|---|
% |
percent |
part per hundred |
‰ |
permille |
part per thousand |
‱ |
permyriad |
part per ten thousand |
pcm |
pcm |
part per hundred thousand |
ppm |
ppm |
part per million |
ppb |
ppb |
part per billion |
ppt |
ppt |
part per trillion |
Unit name | Variable name | Description |
---|---|---|
W |
W |
watt |
mW |
mW |
milliwatt |
kW |
kW |
kilowatt |
MW |
MW |
megawatt |
GW |
GW |
gigawatt |
TW |
TW |
terawatt |
Wh |
Wh |
watt-hour |
kWh |
kWh |
kilowatt-hour |
Unit name | Variable name | Description |
---|---|---|
Pa |
Pa |
pascal |
kPa |
KPa |
kilopascal |
MPa |
MPa |
megapascal |
GPa |
GPa |
gigapascal |
at |
at |
technical atmosphere |
atm |
atm |
atmosphere |
bar |
bar |
bar |
psi |
psi |
pound per square inch |
Unit | Variable name | Description |
---|---|---|
m/s |
m_s |
meter per second |
km/h |
km_h |
kilometer per hour |
mph |
mph |
mile per hour |
kn |
kn |
knot |
Unit | Variable name | Description |
---|---|---|
mol |
mol |
mole |
Unit | Variable name | Description |
---|---|---|
K |
K |
kelvin |
℃ |
celsius |
degree celsius |
℉ |
fahrenheit |
degree fahrenheit |
Unit | Variable name | Description |
---|---|---|
s |
s |
second |
ms |
ms |
millisecond |
µs |
µs |
microsecond |
ns |
ns |
nanosecond |
min |
min |
minute |
h |
h |
hour |
d |
d |
day |
week |
week |
week |
month |
month |
month (30 days) |
year |
year |
year (365.25 days) |
Unit | Variable name | Description |
---|---|---|
m3 |
m3 |
cubic meter |
mm3 |
mm3 |
cubic millimeter |
cm3 |
cm3 |
cubic centimeter |
km3 |
km3 |
cubic kilometer |
l |
l |
liter |
cl |
cl |
centiliter |
ml |
ml |
milliliter |
gal |
gal |
imperial gallon |
pt |
pt |
imperial pint |
fl oz |
floz |
imperial fluid ounce |
us gal |
us_gal |
US gallon |
us pt |
us_pt |
US pint |
us cup |
us_cup |
US cup |
us fl oz |
us_floz |
US fluid ounce |
Existing coherent units can be prefixed to produce derived versions:
import { prefix, Hz } from "@thi.ng/units";
// define micrometer (also available as preset)
prefix("µ", "m")
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 0.000001, offset: 0, coherent: false }
// define kKhz
prefix("k", Hz);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1000, offset: 0, coherent: false }
The following combinators can be used to derive scaled and/or more complex units (or quantities) in multiple SI dimensions:
div(a, b)
: derives a new unit via the division of the given unitsmul(a, b)
: derives a new unit as the product of the given unitspow(u, k)
: raises given unit to powerk
(e.g. meter ⇒ square meter)reciprocal(u)
: Creates reciprocal of given unit (e.g. Hz ⇒ 1/second)
import { div, mul, pow, prefix, reciprocal, bit, m, s } from "@thi.ng/units";
// acceleration (meter per second squared)
const m_s2 = div(m, pow(s, 2));
// { dim: [ 0, 1, -2, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: false }
// define kilowatt-hour (also available as preset)
const kWh = mul(prefix("k","W"), "h");
// { dim: [ 1, 2, -2, 0, 0, 0, 0 ], scale: 3600000, offset: 0, coherent: false }
// define `word` as 16 bits
const word = mul(bit, 16);
// { dim: [ 0, 0, 0, 0, 0, 0, 0 ], scale: 16, offset: 0, coherent: false }
// Hz = 1/s
const Hz = reciprocal(s);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: false }
Units (and quantities) can be converted using
convert()
. Only
units with compatible (incl. reciprocal) dimensions can be converted, otherwise
an error will be thrown. On the other hand, all dimensionless units can be
converted to other dimensionless units (even if it would be semantic
nonsense).
Units can be specified in various ways:
import { convert, div, reciprocal, h, km_h, mph, yd } from "@thi.ng/units";
// convert from km/h to mph using unit names
convert(100, "km/h", "mph");
// 62.13711922373341
// or using predefined unit constants directly
convert(60, mph, km_h);
// 96.56063999999998
// or using anonymous units (meter/second ⇒ yard/hour)
convert(1, "m/s", div(yd, h));
// 3937.007874015749
// convert into opposite direction (meter/second ⇒ second/meter)
convert(10, "m/s", reciprocal("m/s"));
// 0.1
Another example using dimensionless units (here angles, arc second ⇒ radian) to compute the distance of 10 arcsec on the earth surface (in meters):
import { convert, R } from "@thi.ng/units";
// earth radius in meters
// (also available as quantity EARTH_RADIUS, see section below)
const R = 6371000;
convert(10, "arcsec", "rad") * R;
// 308.87479623488537
The library also supports defining quantities, i.e. certain finite amounts of a
given unit. These can be a number or vector-based and can be used for
calculations & conversions using the above mentioned polymorphic functions:
div()
, mul()
, reciprocal()
and convert()
.
Quantities are created via
quantity()
which acts as factory function for a thin Quantity
class wrapper. The latter
also implements the standard
IDeref
interface
to obtain the unwrapped amount (though it only should be used for dimensionless
quantities). Use convert()
otherwise!
import { convert, div, quantity } from "@thi.ng/units";
// (also available as preset)
const speedOfLight = quantity(299792458, "m/s");
// compute wavelength of a WiFi signal in millimeters
convert(div(speedOfLight, quantity(2.4,"GHz")), "mm");
// 124.9135
Some examples using vector quantities:
import { convert, mul, quantity, NONE } from "@thi.ng/units";
// DIN A4 paper size (also available as preset)
const A4 = quantity([210, 297], "mm");
// (also available as preset)
const DPI_300 = quantity(300, "dpi");
// convert paper size to inches
convert(A4, "in");
// [ 8.2677, 11.6929 ]
// or calculate pixel dimensions @ 300 dpi
// the result of this product is dimensionless,
// so we use the NONE preset as target unit...
convert(mul(A4, DPI_300), NONE)
// [ 2480.314960629921, 3507.8740157480315 ]
// alternatively, dimensionless units can be deref'd directly
mul(A4, DPI_300).deref()
// [ 2480.314960629921, 3507.8740157480315 ]
When combining different quantities, their units do not need to be the same (but compatible):
import { convert, mul, quantity } from "@thi.ng/units";
// compute 10 mm x 2 inch and convert to square centimeter
convert(mul(quantity(10, "mm"), quantity(2, "in")), "cm2")
// 5.08
The following constants are provided (more to come):
Var name | Unit | Comment |
---|---|---|
DIN_A0 ... DIN_A8 |
2d vector of mm |
Paper sizes(1) |
DPI_72 / DPI_150 / DPI_300 / DPI_600 |
dots per inch | Screen/print resolutions |
EARTH_GRAVITY |
m/s |
|
EARTH_CIRCUMFERENCE |
m |
|
EARTH_MASS |
kg |
|
EARTH_RADIUS |
m |
|
GRAVITATION |
kg-1·m3·s-2 |
Gravitational constant |
SPEED_OF_LIGHT |
m/s |
|
SPEED_OF_SOUND_IN_AIR |
m/s |
at 20 ℃ |
SPEED_OF_SOUND_IN_WATER |
m/s |
at 20 ℃ |
US_ANSI_A ... US_ANSI_E |
2d vector of inch |
Paper sizes(1) |
US_ARCH_A ... US_ARCH_E |
2d vector of inch |
Paper sizes(1) |
US_LETTER / US_HALF_LETTER |
2d vector of inch |
Paper sizes(1) |
US_LEGAL / US_JUNIOR_LEGAL |
2d vector of inch |
Paper sizes(1) |
- (1) - all paper sizes are also available as landscape presets
(using
_LANDSCAPE
as suffix).
Densities of selected materials:
Var name | Unit |
---|---|
AIR |
kg/m3 |
ALUMINIUM |
kg/m3 |
CONCRETE |
kg/m3 |
COPPER |
kg/m3 |
DIAMOND |
kg/m3 |
GLASS |
kg/m3 |
GOLD |
kg/m3 |
ICE |
kg/m3 |
IRON |
kg/m3 |
NYLON |
kg/m3 |
PLASTIC |
kg/m3 |
PLATINUM |
kg/m3 |
SAND |
kg/m3 |
SALT_WATER |
kg/m3 |
SILICON |
kg/m3 |
SILVER |
kg/m3 |
STEEL |
kg/m3 |
TITANIUM |
kg/m3 |
WATER |
kg/m3 |
WOOD |
kg/m3 |
BETA - possibly breaking changes forthcoming
Search or submit any issues for this package
yarn add @thi.ng/units
ESM import:
import * as units from "@thi.ng/units";
Browser ESM import:
<script type="module" src="https://esm.run/@thi.ng/units"></script>
For Node.js REPL:
const units = await import("@thi.ng/units");
Package sizes (brotli'd, pre-treeshake): ESM: 4.78 KB
Note: @thi.ng/api is in most cases a type-only import (not used at runtime)
If this project contributes to an academic publication, please cite it as:
@misc{thing-units,
title = "@thi.ng/units",
author = "Karsten Schmidt",
note = "https://thi.ng/units",
year = 2021
}
© 2021 - 2024 Karsten Schmidt // Apache License 2.0