Реализовать ускорение времени

У меня стоит задача реализовать буст (ускорение времени с начала старта какой-то даты) к примеру у нас есть сегодняшняя дата, с активным бустом, спустя 5 сек, при проверке сколько прошло времени мы должны получить не 5 сек а 10 сек (время ускорено в 2 раза). Но при этом, не терять старый буст, когда уже активный пропадет, то есть - время должно будет считаться как обычно но уже с приплюсованным старым ускорением. Как это можно реализовать? Примерная конструкция ниже:

import datetime
import time

cases = (2, 0, 1, 1, 1, 2)

intervals = (
    (31536000, 'год', 'года', 'лет'),
    (2592000, 'месяц', 'месяца', 'месяцев'),
    (86400, 'день', 'дня', 'дней'),  # 60 * 60 * 24
    (3600, 'час', 'часа', 'часов'),  # 60 * 60
    (60, 'минуту', 'минуты', 'минут'),
    (1, 'секунду', 'секунды', 'секунд'),)

def plural_form(n: int, v: (list, tuple)):
    """Функция возвращает число и просклонённое слово после него

    Аргументы:
    :param n: число
    :param v: варианты слова в формате (для 1, для 2, для 5)

    Пример:
    plural_form(difference.days, ("день", "дня", "дней"))

    :return: Число и просклонённое слово после него
    """

    return "{:,}".format(n).replace(",", ".") + f" {v[2 if (4 < n % 100 < 20) else cases[min(n % 10, 5)]]}"

def show_time(seconds, granularity=5):
    """Функция возвращает цифровое время с использованием utctimestamp
    granularity - длинна возвращаемого значения.
    """
    result = []

    seconds = int(seconds)

    for count, *name in intervals:
        value = seconds // count
        if value:
            seconds -= value * count
            result.append(plural_form(value, name))

    return '. '.join(result[:granularity]) if result else '0 сек'


boost = False

#Время начала события
start_date = datetime.datetime.now()
#Слипаем что бы прошло какое-то время
time.sleep(5)

#Проверяем сколько прошло времени.
time_passed = (datetime.datetime.now() - start_date).total_seconds()

print(start_date)
print(show_time(time_passed))

Ответы (1 шт):

Автор решения: Roman Konoval

Нужно хранить три значения:

  1. текущий boost
  2. текущее опережение времени
  3. время последней смены буста

На основании этих данных можно считать текущее время с учетом буста:

class TimeBoost:
    def __init__(self):
        self.current_lead = datetime.timedelta()
        self.current_boost = 1
        self.last_boost_change = datetime.datetime.now()

    def now(self):
        return self.last_boost_change + self.current_lead +\
            self._get_time_since_last_boost_change(datetime.datetime.now())

    def _get_time_since_last_boost_change(self, dt):
        return (dt - self.last_boost_change) * self.current_boost

    def set_boost(self, new_boost):
        now_dt = datetime.datetime.now()
        self.current_lead += self._get_time_since_last_boost_change(now_dt) -\
            (now_dt - self.last_boost_change)
        self.last_boost_change = now_dt
        self.current_boost = new_boost

Использовать так:

boost = TimeBoost()

start_date = datetime.datetime.now()
time.sleep(2)
print(boost.now() - start_date)
boost.set_boost(2)
time.sleep(2)
print(boost.now() - start_date)
boost.set_boost(1)
time.sleep(2)
print(boost.now() - start_date)

Это покажет:

0:00:02.003711
0:00:06.010011
0:00:08.011695
→ Ссылка