Skip to content

Repository files navigation

rasuvaeff/duration

Latest Stable VersionTotal DownloadsBuildStatic analysisPsalm levelPHPLicenseРусская версия

Type-safe, immutable, non-negative duration value object for PHP. Replaces bare int parameters (seconds? milliseconds?) with an explicit unit, removing a whole class of "seconds vs milliseconds" bugs. Designed as the foundation for timeout, wait and lease parameters across the resilience packages.

Using an AI coding assistant? llms.txt contains a compact API reference you can share with the model.

Requirements

  • PHP 8.3+
  • No runtime dependencies

Installation

composer require rasuvaeff/duration

Usage

useRasuvaeff\Duration\Duration;
$timeout = Duration::seconds(2.5);
$timeout->toMillis(); // => 2500$timeout->toMicros(); // => 2500000$timeout->toSeconds(); // => 2.5$total = Duration::millis(500)->plus(Duration::seconds(1));
$total->toMillis(); // => 1500
Duration::seconds(1)->isGreaterThan(Duration::millis(500)); // => trueecho Duration::minutes(1.5); // outputs 1.5min

Factories

MethodDescription
Duration::zero()Zero-length duration
Duration::micros(int $micros)From microseconds
Duration::millis(int $millis)From milliseconds
Duration::seconds(int|float $seconds)From seconds (fractional allowed)
Duration::minutes(int|float $minutes)From minutes (fractional allowed)
Duration::hours(int|float $hours)From hours (fractional allowed)
Duration::days(int|float $days)From days (fractional allowed)

Conversions

MethodReturnsNotes
toMicros()intExact — microseconds is the storage unit
toMillis()intRounded up (ceil)
toSeconds()float
toMinutes()float

toMillis() rounds up on purpose: a non-zero sub-millisecond duration must never collapse to 0, because 0ms means "no timeout / infinite" to cURL and most HTTP clients — the exact failure a timeout value is meant to prevent.

Arithmetic & comparison

MethodReturnsDescription
plus(Duration $other)DurationSum of two durations
minus(Duration $other)DurationSaturating difference — never negative (a passed deadline is 0)
Duration::min($a, $b)DurationStatic — the smaller of two durations
Duration::max($a, $b)DurationStatic — the larger of two durations
isZero()boolTrue when zero-length
isPositive()boolTrue when non-zero
equals(Duration $other)boolEqual length
compareTo(Duration $other)int-1 / 0 / 1
isGreaterThan(Duration $other)boolStrictly longer
isLessThan(Duration $other)boolStrictly shorter

String representation

Duration implements Stringable. Casting to string yields a human-readable form, choosing the largest unit with a value of at least 1:

"0" zero
"1µs" microseconds (integer)
"250ms" milliseconds (integer, rounded up — matches toMillis())
"2.5s" seconds (%g, trailing zeros trimmed)
"1.5min" minutes
"2h" hours
"1.5d" days

The unit set, rounding and suffix spelling are an observable contract: changing them is a major version bump. For machine-readable values use toMicros() / toMillis() / toSeconds() / toMinutes() directly.

Security

Not security-sensitive: a pure, side-effect-free value object. It performs no I/O and holds no secrets. The only enforced contract is the input domain:

  • Negative durations throw InvalidArgumentException (Duration cannot be negative).
  • Non-finite floats (INF / NAN) throw InvalidArgumentException (Duration must be finite).

Examples

See examples/ for runnable scripts. Examples are expected to execute without fatal errors and stay aligned with the documented public API.

ScriptShowsNeeds server?
basic.phpFactories, conversions, arithmetic, comparisonno

Development

No PHP/Composer on the host — run in Docker via the composer:2 image:

docker run --rm -v "$PWD":/app -w /app composer:2 composer install
docker run --rm -v "$PWD":/app -w /app composer:2 composer build
docker run --rm -v "$PWD":/app -w /app composer:2 composer cs:fix
docker run --rm -v "$PWD":/app -w /app composer:2 composer test
docker run --rm -v "$PWD":/app -w /app composer:2 composer release-check

Or with Make:

make install
make build
make cs-fix
make test
make test-coverage
make mutation
make release-check

make test-coverage and make mutation bootstrap pcov inside the composer:2 container because the base image has no coverage driver.

License

BSD-3-Clause

About

Type-safe immutable duration value object for PHP

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages