Created
March 21, 2025 13:02
-
-
Save devhammed/6f53ec01e6f596e1d94e0cb71e74a7c1 to your computer and use it in GitHub Desktop.
Dart Duration in PHP - https://api.flutter.dev/flutter/dart-core/Duration-class.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class Duration | |
* Represents a time span with microsecond precision, similar to Dart's Duration class. | |
*/ | |
class Duration | |
{ | |
/** | |
* @var int Total duration in microseconds. | |
*/ | |
private int $microseconds; | |
/** | |
* Duration constructor. | |
* | |
* @param int $days | |
* @param int $hours | |
* @param int $minutes | |
* @param int $seconds | |
* @param int $milliseconds | |
* @param int $microseconds | |
*/ | |
public function __construct( | |
int $days = 0, | |
int $hours = 0, | |
int $minutes = 0, | |
int $seconds = 0, | |
int $milliseconds = 0, | |
int $microseconds = 0 | |
) { | |
$this->microseconds = | |
$days * 86_400_000_000 + | |
$hours * 3_600_000_000 + | |
$minutes * 60_000_000 + | |
$seconds * 1_000_000 + | |
$milliseconds * 1_000 + | |
$microseconds; | |
} | |
/** | |
* Create a Duration from a raw microsecond value. | |
* | |
* @param int $microseconds | |
* @return Duration | |
*/ | |
public static function fromMicroseconds(int $microseconds): Duration | |
{ | |
return new Duration(microseconds: $microseconds); | |
} | |
/** | |
* @return int Duration in whole days. | |
*/ | |
public function inDays(): int | |
{ | |
return intdiv($this->microseconds, 86_400_000_000); | |
} | |
/** | |
* @return int Duration in whole hours. | |
*/ | |
public function inHours(): int | |
{ | |
return intdiv($this->microseconds, 3_600_000_000); | |
} | |
/** | |
* @return int Duration in whole minutes. | |
*/ | |
public function inMinutes(): int | |
{ | |
return intdiv($this->microseconds, 60_000_000); | |
} | |
/** | |
* @return int Duration in whole seconds. | |
*/ | |
public function inSeconds(): int | |
{ | |
return intdiv($this->microseconds, 1_000_000); | |
} | |
/** | |
* @return int Duration in whole milliseconds. | |
*/ | |
public function inMilliseconds(): int | |
{ | |
return intdiv($this->microseconds, 1_000); | |
} | |
/** | |
* @return int Duration in microseconds. | |
*/ | |
public function inMicroseconds(): int | |
{ | |
return $this->microseconds; | |
} | |
/** | |
* @return bool True if duration is negative. | |
*/ | |
public function isNegative(): bool | |
{ | |
return $this->microseconds < 0; | |
} | |
/** | |
* Get the absolute (positive) value of this Duration. | |
* | |
* @return Duration | |
*/ | |
public function abs(): Duration | |
{ | |
return self::fromMicroseconds(abs($this->microseconds)); | |
} | |
/** | |
* Compare this duration to another. | |
* | |
* @param Duration $other | |
* @return int Returns -1, 0, or 1 | |
*/ | |
public function compareTo(Duration $other): int | |
{ | |
return $this->microseconds <=> $other->microseconds; | |
} | |
/** | |
* String representation of the duration. | |
* | |
* @return string | |
*/ | |
public function toString(): string | |
{ | |
return (string) $this; | |
} | |
/** | |
* Add another Duration to this one. | |
* | |
* @param Duration $other | |
* @return Duration | |
*/ | |
public function add(Duration $other): Duration | |
{ | |
return self::fromMicroseconds($this->microseconds + $other->microseconds); | |
} | |
/** | |
* Subtract another Duration from this one. | |
* | |
* @param Duration $other | |
* @return Duration | |
*/ | |
public function subtract(Duration $other): Duration | |
{ | |
return self::fromMicroseconds($this->microseconds - $other->microseconds); | |
} | |
/** | |
* Multiply this duration by a factor. | |
* | |
* @param int|float $factor | |
* @return Duration | |
*/ | |
public function multiply(int|float $factor): Duration | |
{ | |
return self::fromMicroseconds((int) round($this->microseconds * $factor)); | |
} | |
/** | |
* Integer divide this duration by a divisor. | |
* | |
* @param int $divisor | |
* @return Duration | |
* @throws \DivisionByZeroError | |
*/ | |
public function divide(int $divisor): Duration | |
{ | |
if ($divisor === 0) { | |
throw new \DivisionByZeroError("Cannot divide by zero."); | |
} | |
return self::fromMicroseconds(intdiv($this->microseconds, $divisor)); | |
} | |
/** | |
* Check equality with another Duration. | |
* | |
* @param Duration $other | |
* @return bool | |
*/ | |
public function equals(Duration $other): bool | |
{ | |
return $this->microseconds === $other->microseconds; | |
} | |
/** | |
* Check if this duration is less than another. | |
* | |
* @param Duration $other | |
* @return bool | |
*/ | |
public function lessThan(Duration $other): bool | |
{ | |
return $this->microseconds < $other->microseconds; | |
} | |
/** | |
* Check if this duration is less than or equal to another. | |
* | |
* @param Duration $other | |
* @return bool | |
*/ | |
public function lessThanOrEqual(Duration $other): bool | |
{ | |
return $this->microseconds <= $other->microseconds; | |
} | |
/** | |
* Check if this duration is greater than another. | |
* | |
* @param Duration $other | |
* @return bool | |
*/ | |
public function greaterThan(Duration $other): bool | |
{ | |
return $this->microseconds > $other->microseconds; | |
} | |
/** | |
* Check if this duration is greater than or equal to another. | |
* | |
* @param Duration $other | |
* @return bool | |
*/ | |
public function greaterThanOrEqual(Duration $other): bool | |
{ | |
return $this->microseconds >= $other->microseconds; | |
} | |
/** | |
* Negate the duration (unary -). | |
* | |
* @return Duration | |
*/ | |
public function negate(): Duration | |
{ | |
return self::fromMicroseconds(-$this->microseconds); | |
} | |
/** | |
* Format the duration as HH:MM:SS.mmmuuu. | |
* | |
* @return string | |
*/ | |
public function __toString(): string | |
{ | |
$micros = abs($this->microseconds); | |
$sign = $this->microseconds < 0 ? '-' : ''; | |
$totalSeconds = intdiv($micros, 1_000_000); | |
$microRemainder = $micros % 1_000_000; | |
$hours = intdiv($totalSeconds, 3600); | |
$minutes = intdiv($totalSeconds % 3600, 60); | |
$seconds = $totalSeconds % 60; | |
$milliseconds = intdiv($microRemainder, 1_000); | |
$microseconds = $microRemainder % 1_000; | |
return sprintf( | |
"%s%02d:%02d:%02d.%03d%03d", | |
$sign, | |
$hours, | |
$minutes, | |
$seconds, | |
$milliseconds, | |
$microseconds | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment