【发布时间】:2019-11-11 11:34:57
【问题描述】:
我目前正在编写一个课程来以特定格式管理时间。输出始终采用以下格式: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();
任何帮助将不胜感激!
【问题讨论】:
-
所以
WW部分应该是什么 - 周数?那么,为什么你首先要为此编写自己的类——而不是使用 PHP 的 DateTime?毕竟,显示日期的周数只是输出格式的问题。 -
@04FS 我之前用过 DateTime 类,但是不能显示零时间。
-
是的,WW 是周数。
-
“但它不能显示零时间” - 究竟是什么意思?
-
@04FS PHP 的
DateTime类不能显示零时间,因为它遵循日历格式。不过,我的时间需要从零开始,而 DateTime 类不能这样做。
标签: php algorithm function math time