Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
CRAP | |
76.60% |
36 / 47 |
| DateSolar | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
10.04 | |
76.60% |
36 / 47 |
| __construct | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
| fromUnixTime | |
0.00% |
0 / 1 |
6.03 | |
65.52% |
19 / 29 |
|||
| toUnixTime | |
0.00% |
0 / 1 |
2.00 | |
91.67% |
11 / 12 |
|||
| <?php | |
| namespace Popy\Calendar\Converter\UnixTimeConverter; | |
| use BCMathExtended\BC; | |
| use Popy\Calendar\Converter\Conversion; | |
| use Popy\Calendar\Converter\UnixTimeConverterInterface; | |
| use Popy\Calendar\Converter\CompleteLeapYearCalculatorInterface; | |
| use Popy\Calendar\ValueObject\DateSolarRepresentationInterface; | |
| /** | |
| * Handles DateSolarRepresentationInterface. | |
| * | |
| * The eraDayIndex is calculated using an "eraStart" reference date. Year, year | |
| * length and leap days calculations are delegated to a LeapYearCalculator. | |
| */ | |
| class DateSolar implements UnixTimeConverterInterface | |
| { | |
| /** | |
| * Era start unix time. | |
| * | |
| * @var integer | |
| */ | |
| protected $eraStart; | |
| /** | |
| * Day length in seconds. | |
| * | |
| * @var integer|float|string | |
| */ | |
| protected $dayLengthInSeconds = 24 * 3600; | |
| /** | |
| * Leap year calculator. | |
| * | |
| * @var CompleteLeapYearCalculatorInterface | |
| */ | |
| protected $calculator; | |
| /** | |
| * Class constructor. | |
| * | |
| * @param CompleteLeapYearCalculatorInterface $calculator Leap year calculator. | |
| * @param integer $eraStart Era start unix time. | |
| * @param integer|float|string|null $dayLengthInSeconds Day length in seconds. | |
| */ | |
| public function __construct(CompleteLeapYearCalculatorInterface $calculator, $eraStart, $dayLengthInSeconds = null) | |
| { | |
| $this->calculator = $calculator; | |
| $this->eraStart = $eraStart; | |
| if (null !== $dayLengthInSeconds) { | |
| $this->dayLengthInSeconds = $dayLengthInSeconds; | |
| } | |
| } | |
| /** | |
| * @inheritDoc | |
| */ | |
| public function fromUnixTime(Conversion $conversion) | |
| { | |
| if (!$conversion->getTo() instanceof DateSolarRepresentationInterface) { | |
| return; | |
| } | |
| $res = $conversion->getTo(); | |
| // TODO : remove code repetition by using a separate abstraction | |
| // handling basic math operations. | |
| if (is_integer($this->dayLengthInSeconds) || !class_exists(BC::class)) { | |
| // bc not needed/not available | |
| // Relative time from era start. | |
| $relativeTime = $conversion->getUnixTime() - $this->eraStart; | |
| // Calculating global day index. Floor is used to properly handle | |
| // negative values | |
| $eraDayIndex = (int)floor($relativeTime / $this->dayLengthInSeconds); | |
| $time = $relativeTime - $eraDayIndex * $this->dayLengthInSeconds; | |
| // TODO : handle the loss as microseconds ? | |
| if (is_float($time)) { | |
| $time = (int)ceil($time); | |
| } | |
| $conversion->setUnixTime($time); | |
| } else { | |
| // Using bc math if available for non int dayLengthInSeconds in | |
| // order to stay as precise as possible. | |
| // Relative time from era start. | |
| $relativeTime = bcsub($conversion->getUnixTime(), $this->eraStart); | |
| // Calculating global day index. Floor is used to properly handle | |
| // negative values | |
| $eraDayIndex = BC::floor( | |
| bcdiv($relativeTime, $this->dayLengthInSeconds) | |
| ); | |
| // TODO : handle the loss as microseconds ? | |
| $time = BC::ceil(bcsub( | |
| $relativeTime, | |
| bcmul($eraDayIndex, $this->dayLengthInSeconds) | |
| )); | |
| $conversion->setUnixTime((int)$time); | |
| } | |
| list($year, $dayIndex) = $this->calculator | |
| ->getYearAndDayIndexFromErayDayIndex($eraDayIndex) | |
| ; | |
| $res = $res | |
| ->withYear($year, $this->calculator->isLeapYear($year)) | |
| ->withDayIndex($dayIndex, $eraDayIndex) | |
| ; | |
| $conversion->setTo($res); | |
| } | |
| /** | |
| * @inheritDoc | |
| */ | |
| public function toUnixTime(Conversion $conversion) | |
| { | |
| $input = $conversion->getTo(); | |
| if (!$input instanceof DateSolarRepresentationInterface) { | |
| return; | |
| } | |
| $year = $input->getYear(); | |
| $eraDayIndex = $input->getDayIndex() | |
| + $this->calculator->getYearEraDayIndex($year) | |
| ; | |
| // TODO : BC Math implementation | |
| $conversion->setUnixTime(intval( | |
| $conversion->getUnixTime() + $this->eraStart | |
| + $eraDayIndex * $this->dayLengthInSeconds | |
| )); | |
| } | |
| } |