为什么这个加法函数有时在PHP中不起作用?

问题描述 投票:0回答:1

我目前正在编写一个类来以特定格式管理时间。输出始终采用以下格式:0000:00:0:00:00代表YYYY:WW:D:HH:MM。我有一个添加时间的功能,在我尝试多次调用它之前,它似乎运行得很好。

我使用此代码添加了时间,它应该返回0000:00:0:00:42,但它返回了0000:00:0:03:60

这是我的全班。 https://3v4l.org/YiEQF上的代码演示

<?php

namespace Core\component\time;

final class TimeFactory {

    /** @var int */
    private $year;
    /** @var int */
    private $weekNumber;
    /** @var int */
    private $day;
    /** @var int */
    private $hour;
    /** @var int */
    private $minute;

    /**
     * @param string $formatted
     * @return static
     */
    public static function createFromString(string $formatted): self {
        if (!preg_match('/^(\d{4}):(\d{2}):(\d{1}):(\d{2}):(\d{2})$/', $formatted, $matches)) {
            throw new \InvalidArgumentException('Invalid currency format.');
        }
        return new self(...array_slice($matches, 1));
    }

   
    /**
     * TimeFactory constructor.
     * @param int $year
     * @param int $weekNumber
     * @param int $day
     * @param int $hour
     * @param int $minute
     */
    public function __construct(int $year, int $weekNumber, int $day, int $hour, int $minute)
    {
        $this->year = $year;
        $this->weekNumber = $weekNumber;
        $this->day = $day;
        $this->hour = $hour;
        $this->minute = $minute;
    }

    /**
     * @param int $addedYears
     * @return bool
     */
    public function addYears(int $addedYears): bool {
        $newYears = $this->year + $addedYears;
        if($newYears > 9999) {
            return false;
        } else {
            $this->year += $newYears;
        }
        return true;
    }

    /**
     * @param int $addedWeeks
     */
    public function addWeeks(int $addedWeeks): void {
        $newWeeks = $this->weekNumber + $addedWeeks;
        if($newWeeks >= 52) {
            $years = round($newWeeks / 52, 0, PHP_ROUND_HALF_DOWN);
            $this->addYears($years);
        }
        $this->weekNumber += $newWeeks % 52;
    }

    /**
     * @param int $addedDays
     */
    public function addDays(int $addedDays): void {
        $newDays = $this->day + $addedDays;
        if($newDays >= 7) {
            $weeks = round($newDays / 7, 0, PHP_ROUND_HALF_DOWN);
            $this->addWeeks($weeks);
        }
        $this->day += $newDays % 7;
    }

    /**
     * @param int $addedHours
     */
    public function addHours(int $addedHours): void {
        $newHours = $this->hour + $addedHours;
        if($newHours >= 24) {
            $days = round($newHours / 24, 0, PHP_ROUND_HALF_DOWN);
            $this->addDays($days);
        }
        $this->hour += $newHours % 24;
    }

    /**
     * @param int $addedMinutes
     */
    public function addMinutes(int $addedMinutes): void {
        $newMinutes = $this->minute + $addedMinutes;
        if($newMinutes >= 60) {
            $hours = round($newMinutes / 60, 0, PHP_ROUND_HALF_DOWN);
            $this->addHours($hours);
        }
        $this->minute += $newMinutes % 60;
    }

    /**
     * @return int
     */
    public function getYears(): int {
        return $this->year;
    }

    /**
     * @return int
     */
    public function getWeeks(): int {
        return $this->weekNumber;
    }

    /**
     * @return int
     */
    public function getDays(): int {
        return $this->day;
    }

    /**
     * @return int
     */
    public function getHours(): int {
        return $this->hour;
    }

    /**
     * @return int
     */
    public function getMinutes(): int {
        return $this->minute;
    }

    public function reduceTime(Int $amount, String $type) : bool {
        switch($type) {
            case "m":
                if($this->getMinutes() >= $amount) {
                    $this->minute -= $amount;
                    return true;
                } else {
                    if($this->getHours() > 0) {
                        $this->hour -= 1;
                        $minutesToAdd = 60 - $amount;
                        $this->addMinutes($minutesToAdd);
                        return true;
                    } elseif ($this->getDays() > 0) {
                        $this->day -= 1;
                        $hoursToAdd = 23;
                        $minutesToAdd = 60 - $amount;
                        $this->addHours($hoursToAdd);
                        $this->addMinutes($minutesToAdd);
                        return true;
                    } elseif ($this->getWeeks() > 0) {
                        $this->weekNumber -= 1;
                        $daysToAdd = 6;
                        $hoursToAdd = 23;
                        $minutesToAdd = 60 - $amount;
                        $this->addDays($daysToAdd);
                        $this->addHours($hoursToAdd);
                        $this->addMinutes($minutesToAdd);
                        return true;
                    }  elseif ($this->getYears() > 0) {
                        $this->year -= 1;
                        $weeksToAdd = 51;
                        $daysToAdd = 6;
                        $hoursToAdd = 23;
                        $minutesToAdd = 60 - $amount;
                        $this->addWeeks($weeksToAdd);
                        $this->addDays($daysToAdd);
                        $this->addHours($hoursToAdd);
                        $this->addMinutes($minutesToAdd);
                        return true;
                    }
                }
                break;
            case "h":
                if($this->getHours() >= $amount) {
                    $this->hour -= $amount;
                    return true;
                } else {
                    if ($this->getDays() > 0) {
                        $this->day -= 1;
                        $hoursToAdd = 24 - $amount;
                        $this->addHours($hoursToAdd);
                        return true;
                    } elseif ($this->getWeeks() > 0) {
                        $this->weekNumber -= 1;
                        $daysToAdd = 6;
                        $hoursToAdd = 24 - $amount;
                        $this->addDays($daysToAdd);
                        $this->addHours($hoursToAdd);
                        return true;
                    }  elseif ($this->getYears() > 0) {
                        $this->year -= 1;
                        $weeksToAdd = 51;
                        $daysToAdd = 6;
                        $hoursToAdd = 24 - $amount;
                        $this->addWeeks($weeksToAdd);
                        $this->addDays($daysToAdd);
                        $this->addHours($hoursToAdd);
                        return true;
                    }
                }
                break;
            case "d":
                if($this->getDays() >= $amount) {
                    $this->day -= $amount;
                    return true;
                } else {
                    if ($this->getWeeks() > 0) {
                        $this->weekNumber--;
                        $daysToAdd = 7 - $amount;
                        $this->addDays($daysToAdd);
                        return true;
                    } elseif ($this->getYears() > 0) {
                        $this->year--;
                        $weeksToAdd = 51;
                        $daysToAdd = 7 - $amount;
                        $this->addWeeks($weeksToAdd);
                        $this->addDays($daysToAdd);
                        return true;
                    }
                }
                break;
            case "w":
                if($this->getWeeks() >= $amount) {
                    $this->weekNumber -= $amount;
                    return true;
                } else {
                    if ($this->getYears() > 0) {
                        $weeksToAdd = 52 - $amount;
                        $this->addWeeks($weeksToAdd);
                        return true;
                    }
                }
                break;
            case "y":
                if($this->getYears() >= $amount) {
                    $this->year -= $amount;
                    return true;
                }
        }
        return false;
    }
    /**
     * @return string
     */
    public function __toString(): string {
        return sprintf('%04d:%02d:%d:%02d:%02d', $this->year, $this->weekNumber, $this->day, $this->hour, $this->minute);
    }
}
$factory = TimeFactory::createFromString("0000:00:0:00:00");
$factory->addMinutes(2);
$factory->addMinutes(4);
$factory->addMinutes(6);
$factory->addMinutes(8);
$factory->addMinutes(10);
$factory->addMinutes(12);

echo $factory;
echo "\n" . $factory->getMinutes();
echo "\n" . $factory->getHours();
echo "\n" . $factory->getDays();
echo "\n" . $factory->getWeeks();
echo "\n" . $factory->getYears();

任何帮助将不胜感激!

php algorithm function math time
1个回答
0
投票

不确定整个过程是否是实现所需目标的最佳方法,但这是问题所在(我认为)。

仅以分钟代码为例...

public function addMinutes(int $addedMinutes): void {
    $newMinutes = $this->minute + $addedMinutes;
    if($newMinutes >= 60) {
        $hours = round($newMinutes / 60, 0, PHP_ROUND_HALF_DOWN);
        $this->addHours($hours);
    }
    $this->minute += $newMinutes % 60;
}

所以首先您将新的分钟数添加到现有时间...

$newMinutes = $this->minute + $addedMinutes;

处理小时翻转,然后再次添加新的分钟字段...

$this->minute += $newMinutes % 60;

在每一层重复一次。

所以我建议类似的东西>

public function addMinutes(int $addedMinutes): void {
    $newMinutes = $this->minute + $addedMinutes;
    if($newMinutes >= 60) {
        $hours = round($newMinutes / 60, 0, PHP_ROUND_HALF_DOWN);
        $this->addHours($hours);
        $newMinutes -= ($hours * 60);
    }
    $this->minute = $newMinutes;
}

这执行类似的处理,但是最后一部分只是分配新的分钟,而不是再次添加它们。

© www.soinside.com 2019 - 2024. All rights reserved.