forked from organicmaps/organicmaps
[3party][opening_hours] Add GetNextTimeOpen/Closed functions
Signed-off-by: David Martinez <47610359+dvdmrtnz@users.noreply.github.com>
This commit is contained in:
parent
8a28f281ae
commit
48b11d9e12
4 changed files with 102 additions and 0 deletions
|
@ -889,11 +889,21 @@ bool OpeningHours::IsOpen(time_t const dateTime) const
|
|||
return osmoh::IsOpen(m_rule, dateTime);
|
||||
}
|
||||
|
||||
time_t OpeningHours::GetNextTimeOpen(time_t const dateTime) const
|
||||
{
|
||||
return osmoh::GetNextTimeOpen(m_rule, dateTime);
|
||||
}
|
||||
|
||||
bool OpeningHours::IsClosed(time_t const dateTime) const
|
||||
{
|
||||
return osmoh::IsClosed(m_rule, dateTime);
|
||||
}
|
||||
|
||||
time_t OpeningHours::GetNextTimeClosed(time_t const dateTime) const
|
||||
{
|
||||
return osmoh::GetNextTimeClosed(m_rule, dateTime);
|
||||
}
|
||||
|
||||
bool OpeningHours::IsUnknown(time_t const dateTime) const
|
||||
{
|
||||
return osmoh::IsUnknown(m_rule, dateTime);
|
||||
|
|
|
@ -701,7 +701,9 @@ public:
|
|||
OpeningHours(TRuleSequences const & rule);
|
||||
|
||||
bool IsOpen(time_t const dateTime) const;
|
||||
time_t GetNextTimeOpen(time_t const dateTime) const;
|
||||
bool IsClosed(time_t const dateTime) const;
|
||||
time_t GetNextTimeClosed(time_t const dateTime) const;
|
||||
bool IsUnknown(time_t const dateTime) const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
|
|
@ -385,6 +385,83 @@ bool IsActive(RuleSequence const & rule, time_t const timestamp)
|
|||
return res.first && res.second;
|
||||
}
|
||||
|
||||
time_t GetNextTimeState(TRuleSequences const & rules, time_t const dateTime, RuleState state)
|
||||
{
|
||||
time_t constexpr kTimeTMax = std::numeric_limits<time_t>::max();
|
||||
time_t dateTimeResult = kTimeTMax;
|
||||
time_t dateTimeToCheck;
|
||||
|
||||
// Check current state
|
||||
if (GetState(rules, dateTime) == state)
|
||||
return dateTime;
|
||||
|
||||
// Check in the next 7 days
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
for (auto it = rules.rbegin(); it != rules.rend(); ++it)
|
||||
{
|
||||
auto const & times = it->GetTimes();
|
||||
|
||||
// If the rule has no times specified, check at 00:00
|
||||
if (times.size() == 0)
|
||||
{
|
||||
tm tm = MakeTimetuple(dateTime);
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
dateTimeToCheck = mktime(&tm) + i * (24 * 60 * 60);
|
||||
|
||||
if (dateTimeToCheck < dateTime || dateTimeToCheck > dateTimeResult)
|
||||
continue;
|
||||
|
||||
if (GetState(rules, dateTimeToCheck) == state)
|
||||
dateTimeResult = dateTimeToCheck;
|
||||
}
|
||||
|
||||
if (state == RuleState::Open && it->GetModifier() == RuleSequence::Modifier::Closed ||
|
||||
state == RuleState::Closed &&
|
||||
(it->GetModifier() == RuleSequence::Modifier::Open || it->GetModifier() == RuleSequence::Modifier::DefaultOpen))
|
||||
{
|
||||
// Check the ending time of each rule
|
||||
for (auto const & time : times)
|
||||
{
|
||||
tm tm = MakeTimetuple(dateTime);
|
||||
tm.tm_hour = time.GetEnd().GetHourMinutes().GetHoursCount();
|
||||
tm.tm_min = time.GetEnd().GetHourMinutes().GetMinutesCount();
|
||||
dateTimeToCheck = mktime(&tm) + i * (24 * 60 * 60) + 60; // 1 minute offset
|
||||
|
||||
if (dateTimeToCheck < dateTime || dateTimeToCheck > dateTimeResult)
|
||||
continue;
|
||||
|
||||
if (GetState(rules, dateTimeToCheck) == state)
|
||||
dateTimeResult = dateTimeToCheck;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check the starting time of each rule
|
||||
for (auto const & time : times)
|
||||
{
|
||||
tm tm = MakeTimetuple(dateTime);
|
||||
tm.tm_hour = time.GetStart().GetHourMinutes().GetHoursCount();
|
||||
tm.tm_min = time.GetStart().GetHourMinutes().GetMinutesCount();
|
||||
dateTimeToCheck = mktime(&tm) + i * (24 * 60 * 60);
|
||||
|
||||
if (dateTimeToCheck < dateTime || dateTimeToCheck > dateTimeResult)
|
||||
continue;
|
||||
|
||||
if (GetState(rules, dateTimeToCheck) == state)
|
||||
dateTimeResult = dateTimeToCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dateTimeResult < kTimeTMax)
|
||||
return dateTimeResult;
|
||||
}
|
||||
|
||||
return kTimeTMax;
|
||||
}
|
||||
|
||||
RuleState GetState(TRuleSequences const & rules, time_t const timestamp)
|
||||
{
|
||||
RuleSequence const * emptyRule = nullptr;
|
||||
|
|
|
@ -15,18 +15,31 @@ enum class RuleState
|
|||
|
||||
RuleState GetState(TRuleSequences const & rules, time_t const dateTime);
|
||||
|
||||
time_t GetNextTimeState(TRuleSequences const & rules, time_t const dateTime, RuleState state);
|
||||
|
||||
inline bool IsOpen(TRuleSequences const & rules, time_t const dateTime)
|
||||
{
|
||||
return GetState(rules, dateTime) == RuleState::Open;
|
||||
}
|
||||
|
||||
inline time_t GetNextTimeOpen(TRuleSequences const & rules, time_t const dateTime)
|
||||
{
|
||||
return GetNextTimeState(rules, dateTime, RuleState::Open);
|
||||
}
|
||||
|
||||
inline bool IsClosed(TRuleSequences const & rules, time_t const dateTime)
|
||||
{
|
||||
return GetState(rules, dateTime) == RuleState::Closed;
|
||||
}
|
||||
|
||||
inline time_t GetNextTimeClosed(TRuleSequences const & rules, time_t const dateTime)
|
||||
{
|
||||
return GetNextTimeState(rules, dateTime, RuleState::Closed);
|
||||
}
|
||||
|
||||
inline bool IsUnknown(TRuleSequences const & rules, time_t const dateTime)
|
||||
{
|
||||
return GetState(rules, dateTime) == RuleState::Unknown;
|
||||
}
|
||||
|
||||
} // namespace osmoh
|
||||
|
|
Loading…
Add table
Reference in a new issue