Как я могу управлять временем / датой в качестве валюты в PHP? - PullRequest
0 голосов
/ 09 ноября 2019

Я занимаюсь разработкой приложения, в котором единственной существующей валютой является время. Время отображается в этом формате для пользователя 0000:00:0:00:00, что означает YYYY:WW:D:HH:MM. Время должно всегда отображаться в этом формате, поэтому, если бы у меня был только один час, время должно отображаться в этом формате 0000:00:1:00:00.

Мне также нужны методы для добавления/ уменьшить / установить время.

То, что я пробовал

  • Обрабатывать его как int
  • Обрабатывать его как строку иредактируем только определенные цифры.
  • Используя класс DateTime(). Это работало хорошо, пока я не хотел отображать нулевое время, поэтому 0000:00:0:00:00, что невозможно для этого класса.

Это сводит меня с ума уже неделю. Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2019

Это действительно должно быть разделено на две отдельные проблемы в вашем приложении.

  1. Внутренние операции управления временем - Как ваша система использует время? Вы просто добавляете / вычитаете? Какую самую короткую единицу времени вы будете оперировать? Это 1 second или у вас будет sub-second точность?
  2. Визуальный слой - Как отображается время для пользователя? Вы можете использовать ответ @ Jeto в качестве руководства. Это место, где вы берете внутреннюю единицу времени и конвертируете ее в визуальное значение, которое фактически видит пользователь.

Я твердо верю, что это разделение интересов сделает вашу жизнь намного проще в будущем. Вы сможете легко выполнить юнит-тестирование каждого отдельного компонента и слоя.


Возможно, вы вообще не хотите касаться DateTime , потому что он начнет применять «календарь». логика для ваших номеров. В математике у вас может внезапно оказаться високосный год, что, вероятно, не то, что вам нужно.

DateInterval лучше подходит здесь, поскольку, как следует из названия, он предназначен для работы с интервалами(что вы хотите), а не физические календарные даты. Однако я боюсь, что вы все равно очень быстро столкнетесь с непреднамеренными крайними случаями.

Сохранение вашей продолжительности в строковом формате - ужасная идея, потому что вам придется анализировать ее каждый рази по-прежнему приводить его к меткам DateInterval или unix, чрезмерно усложняя это.

В моей голове остается только один соперник - integer . Отметка времени Unix является наиболее очевидным кандидатом здесь, но вам, возможно, придется использовать microtime или что-то подобное, если вам нужны затраты менее секунды.


Как только вы определились со своим внутренним форматом данных, вы сможете легко создать анализатор визуального представления. Вы знаете, «разделите секунды на 60, чтобы получить минуты», «разделите на 60, чтобы получить часы», «на 24, чтобы получить дни» и т. Д. И т. Д., Добавьте к каждому результату нули, чтобы сделать его двузначным, и все готово!

Удачи:)

0 голосов
/ 09 ноября 2019

Вы можете создать свой собственный класс, который может работать из желаемого формата и выводить его в соответствии с ним:

final class TimeCurrency
{
  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));
  }

  /** @var int */
  private $year;
  /** @var int */
  private $weekNumber;
  /** @var int */
  private $day;
  /** @var int */
  private $hour;
  /** @var int */
  private $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;
  }

  public function addYears(int $addedYears): void
  {
    $this->year += $addedYears;
  }

  public function __toString(): string
  {
    return sprintf('%04d:%02d:%d:%02d:%02d', $this->year, $this->weekNumber, $this->day, $this->hour, $this->minute);
  }
}

// Example usage
$currency = TimeCurrency::createFromString('2010:21:1:23:21');
$currency->addYears(4);
echo $currency;

Демо: https://3v4l.org/cqRPE

Очевидно, что это неполныйНапример, потому что немного сложно понять, что именно вам нужно из вашего вступительного поста, но это должно, по крайней мере, дать вам идею.

Возможно, вам понадобится немало дополнительных методов в зависимости от ваших потребностей, некоторых проверок достоверности (например, минут <= 59) и т. Д. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...