123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <?php
- namespace App\Yr\Forecast\Tabular\Time;
- /**
- * Time-object entity should inherit this
- */
- abstract class AbstractUnit implements DiffInterface, \JsonSerializable {
- const DEFAULT_VARIANCE = 2;
- private $value = 0;
- private $unit;
- /**
- * @param float The value
- * @param float The unit
- */
- public function __construct(float $value, string $unit) {
- $this->value = $value;
- $this->unit = $unit;
- }
- /**
- * Determines if the classes can operate on each other
- *
- * @param AbstractUnit $with Class to operate on
- * @param bool $throw Set to true if function should throw exception
- *
- * @return bool True if they can
- * @throws \InvalidArgumentException if $throw set to true
- */
- private function canOperate(AbstractUnit $with, bool $throw = false): bool {
- if ($with instanceof $this || $with instanceof CustomUnit)
- return true;
- if ($this instanceof CustomUnit && $with instanceof AbstractUnit)
- return true;
- if ($throw)
- throw new \InvalidArgumentException(sprintf(
- "Invalid type <%s>, expected of type \"%s\" or \"%s\"",
- get_class($with), get_class($this), CustomUnit::class
- ));
- return false;
- }
- /**
- * Transform custom unit to self
- */
- protected function transformClass(CustomUnit $cu): self {
- return unserialize(preg_replace(
- '/^O:\d+:"[^"]++"/',
- sprintf('O:%d:"%s"', strlen(static::class), static::class),
- serialize($cu)
- ));
- }
- /**
- * Addition method
- *
- * @param AbstractUnit $with Unit to add with
- * @thows \InvalidArgumentException
- * */
- public function add(AbstractUnit $with): self {
- $this->canOperate($with, true);
- return $this->transformClass(
- new CustomUnit($this->getValue() + $with->getValue(), $with->getUnit())
- );
- }
- /**
- * Subtraction method
- *
- * @param AbstractUnit $with Unit to sub with
- * @thows \InvalidArgumentException
- * */
- public function sub(AbstractUnit $with): self {
- $this->canOperate($with, true);
- return $this->transformClass(
- new CustomUnit($this->getValue() - $with->getValue(), $with->getUnit())
- );
- }
- /**
- * Multiplication method
- *
- * @param AbstractUnit $with Unit to multiply with
- * @thows \InvalidArgumentException
- * */
- public function mul(AbstractUnit $with): self {
- $this->canOperate($with, true);
- return $this->transformClass(
- new CustomUnit($this->getValue() * $with->getValue(), $with->getUnit())
- );
- }
- /**
- * Divide method
- *
- * @param AbstractUnit $with Unit to divide with
- * @thows \InvalidArgumentException
- * */
- public function div(AbstractUnit $with): self {
- $this->canOperate($with, true);
- return $this->transformClass(
- new CustomUnit($this->getValue() / $with->getValue(), $with->getUnit())
- );
- }
- /**
- * Get the value
- *
- * @return float
- */
- public function getValue(): float {
- return $this->value;
- }
- /**
- * Return the unit (e.g «degree»)
- *
- * @return string
- */
- public function getUnit(): string {
- return $this->unit;
- }
- /**
- * Note! Working on floats, so operates on 100-times values,
- * so result should be divided with 100 to get the actual
- * difference.
- *
- * {@inheritDoc}
- */
- public function diff(DiffInterface $d): int {
- if ($this->canOperate($d, false))
- return (int)($this->sub($d)->getValue() * 100);
- return 0;
- }
- public function jsonSerialize(): string {
- return $this->__toString();
- }
- public function __toString(): string {
- return sprintf(
- "%s: %01.1f %s", basename(str_replace(
- '\\', DIRECTORY_SEPARATOR, get_class($this)
- )), $this->value, $this->unit);
- }
- }
|