Это может быть лучше, чем эффективно. Если интервал не длится годами, вам не нужно беспокоиться об эффективности, а может даже и не об этом.
Давайте сначала объявим некоторые константы с хорошими именами. Мой код Java, но его нетрудно перевести на выбранный вами язык программирования.
private static int HOURS_PER_DAY = 24;
private static double DAY_BEGINS = 7;
private static double NIGHT_BEGINS = 19;
Теперь мой алгоритм выглядит следующим образом:
// Maintenance interval to calculate;
// numbers are numbers of hours since start of the day where the shift begins
double start = 10;
double end = 49;
if (start < 0 || start >= 24 || end < start) {
throw new IllegalStateException();
}
double nightHours = 0;
double dayHours = 0;
double time = start;
double nextNightBegins = NIGHT_BEGINS;
double nextDayBegins = DAY_BEGINS;
if (time >= DAY_BEGINS) {
nextDayBegins += HOURS_PER_DAY;
if (time < NIGHT_BEGINS) { // time is in day time
// establish loop invariant
dayHours += NIGHT_BEGINS - time;
time = NIGHT_BEGINS;
}
nextNightBegins += HOURS_PER_DAY;
}
// Loop invariant:
// time <= nextDayBegins < nextNightBegins || time == end.
// Hours up to time have been summed into dayHours and nightHours.
while (time < end) {
assert time <= nextDayBegins : "" + time + " >= " + nextDayBegins;
assert nextDayBegins < nextNightBegins;
double nightHoursUntil = Math.min(nextDayBegins, end);
nightHours += nightHoursUntil - time;
time = nightHoursUntil;
nextDayBegins += HOURS_PER_DAY;
if (time < end) {
double dayHoursUntil = Math.min(nextNightBegins, end);
dayHours += dayHoursUntil - time;
time = dayHoursUntil;
nextNightBegins += HOURS_PER_DAY;
}
}
assert time == end;
System.out.format(Locale.ENGLISH,
"%.2f hours during nighttime, %.2f hours during daytime%n",
nightHours, dayHours);
if (nightHours > dayHours) {
System.out.println("Nighttime maintenance interval)");
} else if (nightHours < dayHours) {
System.out.println("Daytime maintenance interval");
} else { // they are equal
System.out.println("Undecided maintenance interval)");
}
Выведите как кодовые стойки:
18.00 hours during nighttime, 21.00 hours during daytime
Daytime maintenance interval
Я предпочитаю , а не , чтобы воспользоваться тем, что с вашими границами день и ночь имеют одинаковую длину (по 12 часов каждый). Когда-нибудь будут внесены изменения, так что вместо этого ночь начнется в 18:30, и вы не захотите рисковать тем, что ваша программа тогда начнет молчаливо ошибочно классифицировать. В моем алгоритме выше вы можете изменить константу (от 19 до 18,5 в примере), и код все еще будет работать.
Я действительно рассматривал возможность использования LocalTime
Java для времен, но LocalTime
только идет до 23: 59: 59.999999999, поэтому не сработало бы сразу.
Математический ответ
То, что вы просили: Моя идея состоит в том, чтобы рассчитать, сколько больше или меньше часов в ночное время, чем в дневное время по сравнению с тем, что я определяю как стандартную ситуацию , где интервал начинается и заканчивается в 00:00. Для этого расчета мы можем смело взять остаток по модулю 24 конечного времени, поскольку он дает нам правильный час дня (за исключением переходов по летнему времени и таких аномалий). Так что установите e
на e % 24
и определите функцию nMinusD
, которая дает нам, сколько ночных и дневных часов сравнивается с e == 0
со знаком:
nMinusD(e) = e for e <= 7
14 - e for 7 <= e <= 19
e - 24 for e >= 19
Создание кривой на лист бумаги может помочь в понимании.
Для начала нам просто нужно поменять знак результата. Таким образом, окончательная разница между ночными и дневными часами со знаком составляет
diff = nMinusD(e) - nMinusD(s)
Теперь вы можете посмотреть на знак diff
.
diff > 0 => more nighttime hours than daytime hours
diff = 0 => equally many nighttime and daytime hours
diff < 0 => more daytime than nighttime hours