Лог. задача на время

Просмотр 8 сообщений - с 1 по 8 (из 8 всего)
  • Автор
    Сообщения
  • #34587
    manjey73
    Участник

    Пытаюсь тут придумать код логики, обрабатывающей время НА ЛЕТУ.
    з.ы. на лету, потому что Сервер вместе с модулем может иметь свойство перегружаться.

    Дано:
    1. Время старта (вообще дата, но интересно только время) скажем 15:00
    2. Количество запусков в течении дня, например 2, то есть можно посчитать периодичность 24/2=12 то есть 2 раза через 12 часов
    3. время работы — например 30 минут

    Собственно с начальной стадией понятно, определив периодичность, проверяем время старта Если оно больше 12 часов, отнимаем 12 часов, определив первый старт в 3:00
    должно проработать 30 минут.
    А если количество стартов должно быть 3?, то есть каждые 8 часов?

    В общем у меня ступор по организации кода, с учетом того, что сервер в любой момент может быть перегружен, а из известных данных только 3 пункта и расчет надо делать всегда на лету. Так как промежуточные значения некуда сохранять.

    #34591
    Romiros
    Участник

    Сохраняй в storage как текстовый файл, при перезагрузке считывай из него. Наверное самое простое и надёжное средство.

    #34594
    manjey73
    Участник

    Не, думал об этом, в моем случае не лучшее решение.
    Собственно время старта сохраняется, так как привязано к каналу.
    Время работы и количество сохраняется в конфиг файле вообще.

    желательно именно на лету проверять, нужно ли стартовать или нет.

    Сейчас один тест провожу, и опять нарываюсь на то, что времена разные, и все из-за того, что в канале время хранится в double без маркировки часового пояса.
    Буду думать, как это обойти.

    #34595
    manjey73
    Участник

    Собственно не хотелось бы лишним нагружать файл в storage, так как там совсем другая информация записывается.

    #34604
    Mikhail
    Модератор

    Если какая-либо информация должна сохраняться независимо от рестарта Сервера, то её можно сохранить:
    — в текущих данных каналов,
    — в директории Storage (хранилище определяется настройками),
    — в своей БД или файловой системе.

    После перезапуска Сервера нужно на основе загруженной информации запустить свою логику с нужного места.

    #34608
    manjey73
    Участник

    Немного математической магии, и даже обошелся без циклов. Хотя первоначально делал на цикле do/while.

    Сижу тестирую на работе…

    #34618
    Mikhail
    Модератор

    Немного математической магии

    Это как? 🙂

    #34620
    manjey73
    Участник

    Все подписал в комментариях. В первом варианте использовал цикл do/while, но потом пришла идея, а почему бы не вычислить сам диапазон времени, который требуется проверять. В итоге помогли Math.Round и Math.Ceiling.
    Проверил даже в коде модуля, работает, опять правда случились затыки со временем.
    Сделать красиво не получается, так как double не хранить кроме времени ничего и нет TimeZone. Смысл кода думаю будет понятен, если вдруг кто захочет где-то применить.

            TimeOnly toNext;
            DateTime startDt = new DateTime(2024, 9, 10, 17, 21, 0); // Тут просто вписывал дату старта, можно прикрутить к календарю
    
            private void TestTime_Click(object sender, EventArgs e)
            {
                DateTime currDt = DateTime.UtcNow; // Текущее время в UTC раз сервер работает по UTC
                int amount = 12; // Количество запусков в сутках
                TimeOnly toStart = TimeOnly.FromDateTime(startDt.ToUniversalTime()); // Приведение времени старда без даты к UTC
                TimeOnly toCurr = TimeOnly.FromDateTime(currDt); // Текущее время без даты
                int minute = 10; // Время на которое надо запустить
                int period = 24/amount; // Определение периодов между запусками в часах
                double totalMinutes = (toCurr - toStart).TotalMinutes; // Определяем количество минут между временем старта и текущим
                rtb1.Text += $"Total Minutes {totalMinutes}  periodMin {period * 60} большее целое {Math.Ceiling(totalMinutes / (period * 60))}   меньшее целое {Math.Round(totalMinutes / (period * 60))}" + Environment.NewLine;
    
                int col = (int)Math.Round(totalMinutes / (period * 60)); // Тут магия :) определяем ближайшее меньшее целое расчитывая от всего минут / на минуты периода
    
                // Первоначально был цикл do/while, где до цикла col = 0, в else было col++, а при найденом периоде col = amount проверка while(col < amount)
                if (toStart.AddMinutes(col * period * 60) < toCurr && toCurr < toStart.AddMinutes(minute).AddMinutes(col * period * 60))  // Проверка диапазона времени с подстановкой сразу нужного периода
                {
                    rtb1.Text += $"Тут работает один код в течении времени на которое надо запустить - в примере minute = 10" + Environment.NewLine;
                }
                else
                {
                    rtb1.Text += $"Тут работает другой код, который должен работать оставшиеся 50 минут при запусках каждый час или как в примере 1ч 50 минут" + Environment.NewLine;
                    toNext = toStart.AddMinutes(Math.Ceiling(totalMinutes / (period * 60)) * period * 60); // Определение следующего периода запуска - используется расчет к ближайшему большему целому
                }
                rtb1.Text += $"startDt {startDt}  currDt {currDt}  toStart {toStart} toCurr {toCurr} period {period} toNext {toNext}" + Environment.NewLine;
            }
    
    • Этот ответ был изменен 9 месяцев, 2 недели назад от manjey73.
Просмотр 8 сообщений - с 1 по 8 (из 8 всего)
  • Вы должны авторизироваться для ответа в этой теме.