| 391 | } |
| 392 | |
| 393 | time_t GetNextTimeState(TRuleSequences const & rules, time_t const dateTime, RuleState state) |
| 394 | { |
| 395 | time_t constexpr kTimeTMax = std::numeric_limits<time_t>::max(); |
| 396 | time_t dateTimeResult = kTimeTMax; |
| 397 | time_t dateTimeToCheck; |
| 398 | |
| 399 | // Check in the next 7 days |
| 400 | for (int i = 0; i < 7; i++) |
| 401 | { |
| 402 | for (auto it = rules.rbegin(); it != rules.rend(); ++it) |
| 403 | { |
| 404 | auto const & times = it->GetTimes(); |
| 405 | |
| 406 | // If the rule has no times specified, check at 00:00 |
| 407 | if (times.size() == 0) |
| 408 | { |
| 409 | tm tm = MakeTimetuple(dateTime); |
| 410 | tm.tm_hour = 0; |
| 411 | tm.tm_min = 0; |
| 412 | dateTimeToCheck = mktime(&tm); |
| 413 | if (dateTimeToCheck == -1) |
| 414 | continue; |
| 415 | dateTimeToCheck += i * (24 * 60 * 60); |
| 416 | |
| 417 | if (dateTimeToCheck < dateTime || dateTimeToCheck > dateTimeResult) |
| 418 | continue; |
| 419 | |
| 420 | if (GetState(rules, dateTimeToCheck) == state) |
| 421 | dateTimeResult = dateTimeToCheck; |
| 422 | } |
| 423 | |
| 424 | if ((state == RuleState::Open && it->GetModifier() == RuleSequence::Modifier::Closed) || |
| 425 | (state == RuleState::Closed && |
| 426 | (it->GetModifier() == RuleSequence::Modifier::Open || it->GetModifier() == RuleSequence::Modifier::DefaultOpen))) |
| 427 | { |
| 428 | // Check the ending time of each rule |
| 429 | for (auto const & time : times) |
| 430 | { |
| 431 | tm tm = MakeTimetuple(dateTime); |
| 432 | tm.tm_hour = time.GetEnd().GetHourMinutes().GetHoursCount(); |
| 433 | tm.tm_min = time.GetEnd().GetHourMinutes().GetMinutesCount(); |
| 434 | dateTimeToCheck = mktime(&tm); |
| 435 | if (dateTimeToCheck == -1) |
| 436 | continue; |
| 437 | dateTimeToCheck += i * (24 * 60 * 60) + 60; // 1 minute offset |
| 438 | |
| 439 | if (dateTimeToCheck < dateTime || dateTimeToCheck > dateTimeResult) |
| 440 | continue; |
| 441 | |
| 442 | if (GetState(rules, dateTimeToCheck) == state) |
| 443 | dateTimeResult = dateTimeToCheck - 60; // remove 1 minute offset |
| 444 | } |
| 445 | } |
| 446 | else |
| 447 | { |
| 448 | // Check the starting time of each rule |
| 449 | for (auto const & time : times) |
| 450 | { |
no test coverage detected