Стартовая страница › Форумы › Разработка и интеграция › Лог. задача на время
- В этой теме 7 ответов, 3 участника, последнее обновление 9 месяцев, 2 недели назад сделано
manjey73.
-
АвторСообщения
-
10.09.2024 в 09:06 #34587
manjey73
УчастникПытаюсь тут придумать код логики, обрабатывающей время НА ЛЕТУ.
з.ы. на лету, потому что Сервер вместе с модулем может иметь свойство перегружаться.Дано:
1. Время старта (вообще дата, но интересно только время) скажем 15:00
2. Количество запусков в течении дня, например 2, то есть можно посчитать периодичность 24/2=12 то есть 2 раза через 12 часов
3. время работы — например 30 минутСобственно с начальной стадией понятно, определив периодичность, проверяем время старта Если оно больше 12 часов, отнимаем 12 часов, определив первый старт в 3:00
должно проработать 30 минут.
А если количество стартов должно быть 3?, то есть каждые 8 часов?В общем у меня ступор по организации кода, с учетом того, что сервер в любой момент может быть перегружен, а из известных данных только 3 пункта и расчет надо делать всегда на лету. Так как промежуточные значения некуда сохранять.
10.09.2024 в 10:34 #34591Romiros
УчастникСохраняй в storage как текстовый файл, при перезагрузке считывай из него. Наверное самое простое и надёжное средство.
10.09.2024 в 10:58 #34594manjey73
УчастникНе, думал об этом, в моем случае не лучшее решение.
Собственно время старта сохраняется, так как привязано к каналу.
Время работы и количество сохраняется в конфиг файле вообще.желательно именно на лету проверять, нужно ли стартовать или нет.
Сейчас один тест провожу, и опять нарываюсь на то, что времена разные, и все из-за того, что в канале время хранится в double без маркировки часового пояса.
Буду думать, как это обойти.10.09.2024 в 10:59 #34595manjey73
УчастникСобственно не хотелось бы лишним нагружать файл в storage, так как там совсем другая информация записывается.
10.09.2024 в 13:06 #34604Mikhail
МодераторЕсли какая-либо информация должна сохраняться независимо от рестарта Сервера, то её можно сохранить:
— в текущих данных каналов,
— в директории Storage (хранилище определяется настройками),
— в своей БД или файловой системе.После перезапуска Сервера нужно на основе загруженной информации запустить свою логику с нужного места.
10.09.2024 в 17:23 #34608manjey73
УчастникНемного математической магии, и даже обошелся без циклов. Хотя первоначально делал на цикле do/while.
Сижу тестирую на работе…
11.09.2024 в 12:24 #34618Mikhail
МодераторНемного математической магии
Это как? 🙂
11.09.2024 в 13:39 #34620manjey73
УчастникВсе подписал в комментариях. В первом варианте использовал цикл 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.
-
Этот ответ был изменен 9 месяцев, 2 недели назад от
-
АвторСообщения
- Вы должны авторизироваться для ответа в этой теме.