diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 51d8c1580e..b4937c48b4 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestTime) { Time time{}; time.SetHours(22_h); - time.SetMinutes(15_min); + time = time + 15_min; BOOST_CHECK(time.HasValue()); BOOST_CHECK(time.IsHoursMinutes()); BOOST_CHECK(time.IsTime()); @@ -173,6 +173,10 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestTime) BOOST_CHECK(!time.IsEventOffset()); BOOST_CHECK_EQUAL(ToString(time), "sunrise"); + + time = time - 90_min; + BOOST_CHECK(time.IsEventOffset()); + BOOST_CHECK_EQUAL(ToString(time), "(sunrise-01:30)"); } { Time time{}; @@ -392,6 +396,12 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestMonthDay) BOOST_CHECK(!md.IsVariable()); BOOST_CHECK_EQUAL(ToString(md), ""); } + { + MonthDay md; + md.SetVariableDate(MonthDay::EVariableDate::Easter); + BOOST_CHECK(!md.IsEmpty()); + BOOST_CHECK_EQUAL(ToString(md), "easter"); + } { MonthDay md; md.SetMonth(MonthDay::EMonth::Jul); @@ -694,6 +704,11 @@ BOOST_AUTO_TEST_CASE(OpeningHoursMonthdayRanges_TestParseUnparse) auto const parsedUnparsed = ParseAndUnparse(rule); BOOST_CHECK_EQUAL(parsedUnparsed, rule); } + { + auto const rule = "easter -2 days+"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } { auto const rule = "Jan-Feb/10"; auto const parsedUnparsed = ParseAndUnparse(rule); @@ -832,14 +847,30 @@ BOOST_AUTO_TEST_CASE(OpeningHoursRuleSequence_TestParseUnparse) auto const parsedUnparsed = ParseAndUnparse(rule); BOOST_CHECK_EQUAL(parsedUnparsed, rule); } + { + auto const rule = "easter -2 days+: closed"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + { + auto const rule = "easter: open"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + + { + auto const rule = ( "PH, Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open; " + //"\"Eintritt ins gesamte Haus frei\"; " + "Jan 01, Dec 24, Dec 25, easter -2 days+: closed" ); + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + { + auto const rule = "Su-Th (sunset-24:00); Fr-Sa (sunrise+12:12)"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } } - // { - // auto const rule = ( "PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open " - // "\"Eintritt ins gesamte Haus frei\"; " - // "Jan 1,Dec 24,Dec 25,easter -2 days: closed" ); - // auto const parsedUnparsed = ParseAndUnparse(rule); - // BOOST_CHECK_EQUAL(parsedUnparsed, rule); - // } // BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) // { diff --git a/3party/opening_hours/osm_parsers.hpp b/3party/opening_hours/osm_parsers.hpp index c4dbc3cda6..4d23655646 100644 --- a/3party/opening_hours/osm_parsers.hpp +++ b/3party/opening_hours/osm_parsers.hpp @@ -382,6 +382,7 @@ class time_selector : public qi::grammar const validate_timespan = validate_timespan_impl(); - hour_minutes = (hours >> lit(':') >> minutes)[bind(&osmoh::Time::SetHours, _val, _1), - bind(&osmoh::Time::SetMinutes, _val, _2)] + hour_minutes = + (hours >> lit(':') >> minutes) [bind(&osmoh::Time::SetHours, _val, _1), + _val = _val + _2] ; - extended_hour_minutes = (exthours >> lit(':') >> minutes)[bind(&osmoh::Time::SetHours, _val, _1), - bind(&osmoh::Time::SetMinutes, _val, _2)] + extended_hour_minutes = + (exthours >> lit(':') >> minutes)[bind(&osmoh::Time::SetHours, _val, _1), + _val = _val + _2] ; - variable_time = + variable_time = eps [phx::bind(&osmoh::Time::SetHours, _val, 0_h)] >> (lit('(') >> charset::no_case[event][bind(&osmoh::Time::SetEvent, _val, _1)] - >> (char_('+') | char_('-')[_val = -_val]) - >> hour_minutes + >> ( (lit('+') >> hour_minutes) [_val = _val + _1] + | (lit('-') >> hour_minutes) [_val = _val - _1] ) >> lit(')') ) | charset::no_case[event][bind(&osmoh::Time::SetEvent, _val, _1)] diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index db72e98804..b56b1b3e00 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -146,15 +146,15 @@ Time::TMinutes Time::GetMinutes() const void Time::SetHours(THours const hours) { m_state |= eHaveHours | eHaveMinutes; - m_duration += hours; + m_duration = hours; } void Time::SetMinutes(TMinutes const minutes) { m_state |= eHaveMinutes; - if (minutes > THours(1)) + m_duration = minutes; + if (m_duration > 1_h || m_duration < -1_h) m_state |= eHaveHours; - m_duration += minutes; } void Time::SetEvent(EEvent const event) @@ -164,7 +164,7 @@ void Time::SetEvent(EEvent const event) bool Time::IsEvent() const { - return m_event != EEvent::eNotEvent; + return GetEvent() != EEvent::eNotEvent; } bool Time::IsEventOffset() const @@ -192,10 +192,18 @@ bool Time::HasValue() const return IsEvent() || IsTime() || IsMinutes(); } -Time & Time::operator-(Time const & time) +Time Time::operator+(Time const & t) { - m_duration -= time.m_duration; - return *this; + Time result = *this; + result.SetMinutes(m_duration + t.m_duration); + return result; +} + +Time Time::operator-(Time const & t) +{ + Time result = *this; + result.SetMinutes(m_duration - t.m_duration); + return result; } Time & Time::operator-() @@ -243,7 +251,7 @@ std::ostream & operator<<(std::ostream & ost, Time const & time) { if (time.IsEventOffset()) { - ost << '(' << hours; + ost << '(' << time.GetEvent(); if (hours < 0) ost << '-'; else @@ -253,7 +261,8 @@ std::ostream & operator<<(std::ostream & ost, Time const & time) PrintPaddedNumber(ost, std::abs(minutes), 2); ost << ')'; } - ost << time.GetEvent(); + else + ost << time.GetEvent(); } else if (time.IsMinutes()) PrintPaddedNumber(ost, std::abs(minutes), 2); @@ -696,32 +705,32 @@ std::ostream & operator<<(std::ostream & ost, DateOffset const & offset) bool MonthDay::IsEmpty() const { - return !HasYear() && !HasMonth() && !HasDayNum(); + return !HasYear() && !HasMonth() && !HasDayNum() && !IsVariable(); } bool MonthDay::IsVariable() const { - return m_variable_date != EVariableDate::None; + return GetVariableDate() != EVariableDate::None; } bool MonthDay::HasYear() const { - return m_year != 0; + return GetYear() != 0; } bool MonthDay::HasMonth() const { - return m_month != EMonth::None; + return GetMonth() != EMonth::None; } bool MonthDay::HasDayNum() const { - return m_daynum != 0; + return GetDayNum() != 0; } bool MonthDay::HasOffset() const { - return !m_offset.IsEmpty(); + return !GetOffset().IsEmpty(); } MonthDay::TYear MonthDay::GetYear() const @@ -826,11 +835,11 @@ std::ostream & operator<<(std::ostream & ost, MonthDay::EVariableDate const date switch (date) { case MonthDay::EVariableDate::None: - break; ost << "none"; - case MonthDay::EVariableDate::Easter: break; + case MonthDay::EVariableDate::Easter: ost << "easter"; + break; } return ost; } @@ -851,9 +860,10 @@ std::ostream & operator<<(std::ostream & ost, MonthDay const md) ost << ' '; PrintPaddedNumber(ost, md.GetDayNum(), 2); } - if (md.HasOffset()) - ost << ' ' << md.GetOffset(); + } + if (md.HasOffset()) + ost << ' ' << md.GetOffset(); return ost; } @@ -1315,6 +1325,7 @@ std::ostream & operator<<(std::ostream & ost, RuleSequence::Modifier const modif std::ostream & operator<<(std::ostream & ost, RuleSequence const & s) { + if (s.Is24Per7()) ost << "24/7"; else @@ -1323,20 +1334,45 @@ std::ostream & operator<<(std::ostream & ost, RuleSequence const & s) ost << s.GetComment() << ':'; else { + bool space = false; + auto const putSpace = [&space, &ost] { + if (space) + ost << ' '; + space = true; + }; + if (s.HasYears()) + { + putSpace(); ost << s.GetYears(); + } if (s.HasMonth()) + { + putSpace(); ost << s.GetMonths(); + } if (s.HasWeeks()) + { + putSpace(); ost << s.GetWeeks(); + } if (s.HasSeparatorForReadability()) + { + space = false; ost << ':'; + } if (s.HasWeekdays()) + { + putSpace(); ost << s.GetWeekdays(); + } if (s.HasTimes()) + { + putSpace(); ost << s.GetTimes(); + } } } if (s.GetModifier() != RuleSequence::Modifier::DefaultOpen) diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 108ad5a135..306f6df476 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -86,7 +86,8 @@ class Time bool IsTime() const; bool HasValue() const; - Time & operator-(Time const & time); + Time operator+(Time const & t); + Time operator-(Time const & t); Time & operator-(); private: