forked from organicmaps/organicmaps-tmp
Rewrite osmoh::Time, osmoh::Timespan. Rewrite time_selector.
This commit is contained in:
parent
b8970aa481
commit
2fd6a8cdf7
5 changed files with 1538 additions and 1160 deletions
|
@ -1,45 +1,44 @@
|
|||
#include "osm_time_range.hpp"
|
||||
|
||||
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
|
||||
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
BOOST_FUSION_ADAPT_ADT
|
||||
(
|
||||
osmoh::Time,
|
||||
(uint8_t, hours)
|
||||
(uint8_t, minutes)
|
||||
(uint8_t, flags)
|
||||
(osmoh::Time::THours, osmoh::Time::THours, obj.GetHours(), obj.SetHours(val))
|
||||
(osmoh::Time::TMinutes, osmoh::Time::TMinutes, obj.GetMinutes(), obj.SetMinutes(val))
|
||||
(osmoh::Time::EEvent, osmoh::Time::EEvent, obj.GetEvent(), obj.SetEvent(val))
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
BOOST_FUSION_ADAPT_ADT
|
||||
(
|
||||
osmoh::TimeSpan,
|
||||
(osmoh::Time, from)
|
||||
(osmoh::Time, to)
|
||||
(uint8_t, flags)
|
||||
(osmoh::Time, period)
|
||||
osmoh::Timespan,
|
||||
(osmoh::Time const &, osmoh::Time const &, obj.GetStart(), obj.SetStart(val))
|
||||
(osmoh::Time const &, osmoh::Time const & , obj.GetEnd(), obj.SetEnd(val))
|
||||
(osmoh::Time const &, osmoh::Time const &, obj.GetPeriod(), obj.SetPeriod(val))
|
||||
(bool, bool, obj.HasPlus(), obj.SetPlus(val))
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::Weekday,
|
||||
(uint8_t, weekdays)
|
||||
(uint16_t, nth)
|
||||
(int32_t, offset)
|
||||
)
|
||||
// BOOST_FUSION_ADAPT_STRUCT
|
||||
// (
|
||||
// osmoh::Weekday,
|
||||
// (uint8_t, weekdays)
|
||||
// (uint16_t, nth)
|
||||
// (int32_t, offset)
|
||||
// )
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::State,
|
||||
(uint8_t, state)
|
||||
(std::string, comment)
|
||||
)
|
||||
// BOOST_FUSION_ADAPT_STRUCT
|
||||
// (
|
||||
// osmoh::State,
|
||||
// (uint8_t, state)
|
||||
// (std::string, comment)
|
||||
// )
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::TimeRule,
|
||||
(osmoh::TWeekdays, weekdays)
|
||||
(osmoh::TTimeSpans, timespan)
|
||||
(osmoh::State, state)
|
||||
(uint8_t, int_flags)
|
||||
)
|
||||
// BOOST_FUSION_ADAPT_STRUCT
|
||||
// (
|
||||
// osmoh::TimeRule,
|
||||
// (osmoh::TWeekdays, weekdays)
|
||||
// (osmoh::TTimeSpans, timespan)
|
||||
// (osmoh::State, state)
|
||||
// (uint8_t, int_flags)
|
||||
// )
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <osm_time_range.hpp>
|
||||
#include <osm_parsers.hpp>
|
||||
|
||||
|
@ -56,7 +57,7 @@ bool test(Char const * in, Parser const & p, bool full_match = true)
|
|||
return boost::spirit::qi::parse(in, last, p) && (!full_match || (in == last));
|
||||
}
|
||||
|
||||
template <template <typename> class Parser, typename Char>
|
||||
template <template <typename> class Parser, typename ParseResult, typename Char>
|
||||
std::basic_string<Char> ParseAndUnparse(Char const * input)
|
||||
{
|
||||
// we don't care about the result of the "what" function.
|
||||
|
@ -65,30 +66,27 @@ std::basic_string<Char> ParseAndUnparse(Char const * input)
|
|||
using boost::spirit::qi::phrase_parse;
|
||||
using boost::spirit::standard_wide::space;
|
||||
|
||||
// TODO move to template
|
||||
osmoh::TTimeRules timeRules;
|
||||
ParseResult parseResult;
|
||||
std::basic_string<Char> const str(input);
|
||||
|
||||
Parser<decltype(begin(str))> p;
|
||||
boost::spirit::qi::what(p);
|
||||
|
||||
auto first = begin(str);
|
||||
auto const last = end(str);
|
||||
auto parsed = boost::spirit::qi::phrase_parse(
|
||||
begin(str),
|
||||
end(str),
|
||||
first,
|
||||
last,
|
||||
p,
|
||||
space,
|
||||
timeRules);
|
||||
parseResult);
|
||||
|
||||
if (!parsed)
|
||||
if (!parsed || first != last)
|
||||
return {};
|
||||
|
||||
std::basic_stringstream<Char> sstr;
|
||||
for (auto it = begin(timeRules); it != end(timeRules); ++it)
|
||||
{
|
||||
sstr << (*it);
|
||||
if (next(it) != end(timeRules))
|
||||
sstr << ' ';
|
||||
}
|
||||
sstr << parseResult;
|
||||
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
|
@ -121,429 +119,472 @@ BOOST_AUTO_TEST_CASE(OpeningHours_Locale)
|
|||
std::locale::global(prev);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit)
|
||||
BOOST_AUTO_TEST_CASE(OpeningHours_ParseUnparse)
|
||||
{
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("12-12-2013 7:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("12-12-2013 16:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("12-12-2013 20:00").IsOpen());
|
||||
auto const rule = "06:00";
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
}
|
||||
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
auto const rule = "06:00+";
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
auto const rule = "06:00-02:00";
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("22-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("29-03-2015 16:00").IsClosed());
|
||||
auto const rule = "06:00-02:00+";
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("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");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("03-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.Comment().empty());
|
||||
BOOST_CHECK(oh.UpdateState("07-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.Comment().empty() == false);
|
||||
auto const rule = "06:00-02:00/03";
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("04-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("16-03-2015 16:00").IsClosed());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").Comment() == "public room");
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9:00-02:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 07:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 09:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 12:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 24:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 00:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 01:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 01:59").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 02:00").IsClosed());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00pm"); // hours > 12, ignore pm
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00h-7:00 pm"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 11-19 Uhr;Sa: 10-18 Uhr");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("08-03-2015 20:00").IsClosed(), true);
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("18-03-2015 12:00").IsClosed(), false);
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("16-03-2015 10:00").IsOpen(), false);
|
||||
BOOST_CHECK(oh.UpdateState("14-03-2015 10:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("16-03-2015 11:00").IsOpen());
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr 9-19");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false);
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false);
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9-19"); // it's no time, it's days of month
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false);
|
||||
BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false);
|
||||
BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet)
|
||||
{
|
||||
{
|
||||
// TODO(mgsergio) move validation from parsing
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
auto const rule = "06:00-02:00/21:03";
|
||||
BOOST_CHECK_EQUAL(ParseAndUnparse<osmoh::parsing::time_domain>(rule), rule);
|
||||
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
|
||||
osmoh::TTimespans>(rule);
|
||||
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
|
||||
}
|
||||
|
||||
{
|
||||
// BOOST_CHECK(test_hard<osmoh::parsing::time_domain>("06:00-09:00/03"));
|
||||
//BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/03");
|
||||
BOOST_CHECK(oh.IsValid() == false);
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("sunrise-sunset");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep Su [1,3] 14:30-17:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00+");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00+");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("24/7");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 08:00-23:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("(sunrise+02:00)-(sunset-04:12)");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo closed");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-21:00 \"call us\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("10:00-13:30,17:00-20:30");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Tu-Su 10:00-18:00, Mo 12:00-17:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("jun 16-mar 14 sunrise-sunset");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Sa-Su; PH");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Su; PH");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
// TODO(mgsergio) Check if we need locale. // пн -> Пн
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("May 15-Sep 23 10:00-18:00; Sep 24 - May 14 \"by appointment\"");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("May-Aug: Mo-Sa 14:30-Sunset; Su 10:30-Sunset; Sep-Apr off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("May-Oct; Nov-Apr off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Fr-Sa");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 03: Mo-Th 07:00-20:00; Apr 01-Oct 03: Fr-Su 07:00-21:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 14 07:00-13:00, 15:00-22:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-08:30; 15:30-16:30");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Dec 1-20: dusk-dawn off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1 off; Dec 25-26 off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1: off; Dec 25-26: off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 09:00-18:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep sunrise-sunset; Dec 1-20 dusk-dawn off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo off; Tu-Sa 09:30-19:00; Su 10:00-14:30; Jan 1 off; Dec 25-26 off");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo-Th 08:00-19:00, Fr 08:00-17:00, Su[-2] 08:00-15:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Lu-Di 10:00-18:00"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise; Sa 09:00-18:00;TU,su,pH OFF"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00h-19:00 h"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00h to 19:00 h"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09h to 19:00"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9h-19h"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9am-9pm"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00H-19:00 h"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,PH OFF"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,ph Off"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("05:00 – 22:00"); // long dash instead minus
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("05:00 - 22:00"); // minus
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-20:00 open \"Bei schönem Wetter. Falls unklar kann angerufen werden\""); // charset
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-22:00; Tu off; dec 31 off; Jan 1 off"); // symbols case
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00"); // leading zeros
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("09:00-9:30"); // leading zeros
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("Mo 08:00-11:00,14:00-17:00; Tu 08:00-11:00, 14:00-17:00; We 08:00-11:00; Th 08:00-11:00, 14:00-16:00; Fr 08:00-11:00");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( OpeningHours_CountFailed )
|
||||
{
|
||||
std::ifstream datalist("opening-count.lst");
|
||||
BOOST_REQUIRE_MESSAGE(datalist.is_open(), "Can't open ./opening-count.lst: " << std::strerror(errno));
|
||||
// BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit)
|
||||
// {
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("12-12-2013 7:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("12-12-2013 16:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("12-12-2013 20:00").IsOpen());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
// }
|
||||
|
||||
std::string line;
|
||||
size_t line_num = 0;
|
||||
size_t num_failed = 0;
|
||||
size_t num_total = 0;
|
||||
std::map<size_t, size_t> desc;
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("22-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("29-03-2015 16:00").IsClosed());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("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");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("03-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.Comment().empty());
|
||||
// BOOST_CHECK(oh.UpdateState("07-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.Comment().empty() == false);
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("04-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("16-03-2015 16:00").IsClosed());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").Comment() == "public room");
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9:00-02:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 07:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 09:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 12:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 24:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 00:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 01:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 01:59").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 02:00").IsClosed());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00pm"); // hours > 12, ignore pm
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00h-7:00 pm"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 11-19 Uhr;Sa: 10-18 Uhr");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("08-03-2015 20:00").IsClosed(), true);
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("18-03-2015 12:00").IsClosed(), false);
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("16-03-2015 10:00").IsOpen(), false);
|
||||
// BOOST_CHECK(oh.UpdateState("14-03-2015 10:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("16-03-2015 11:00").IsOpen());
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr 9-19");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false);
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false);
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9-19"); // it's no time, it's days of month
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false);
|
||||
// BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false);
|
||||
// BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen());
|
||||
// }
|
||||
// }
|
||||
|
||||
while (std::getline(datalist, line))
|
||||
{
|
||||
size_t count = 1;
|
||||
std::string datastr;
|
||||
// BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet)
|
||||
// {
|
||||
// {
|
||||
// // TODO(mgsergio) move validation from parsing
|
||||
// // OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03");
|
||||
// // BOOST_CHECK(oh.IsValid());
|
||||
// auto const rule = "06:00-02:00/21:03";
|
||||
// BOOST_CHECK_EQUAL(ParseAndUnparse<osmoh::parsing::time_domain>(rule), rule);
|
||||
// }
|
||||
|
||||
auto d = line.find('|');
|
||||
if (d == std::string::npos)
|
||||
{
|
||||
BOOST_WARN_MESSAGE((d != std::string::npos), "Incorrect line " << line_num << " format: " << line);
|
||||
datastr = line;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = std::stol(line.substr(0,d));
|
||||
datastr = line.substr(d+1);
|
||||
}
|
||||
// {
|
||||
// // BOOST_CHECK(test_hard<osmoh::parsing::time_domain>("06:00-09:00/03"));
|
||||
// //BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/03");
|
||||
// BOOST_CHECK(oh.IsValid() == false);
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("sunrise-sunset");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep Su [1,3] 14:30-17:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00+");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00+");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("24/7");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 08:00-23:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("(sunrise+02:00)-(sunset-04:12)");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo closed");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-21:00 \"call us\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("10:00-13:30,17:00-20:30");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Tu-Su 10:00-18:00, Mo 12:00-17:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("jun 16-mar 14 sunrise-sunset");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Sa-Su; PH");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Su; PH");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// // TODO(mgsergio) Check if we need locale. // пн -> Пн
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("May 15-Sep 23 10:00-18:00; Sep 24 - May 14 \"by appointment\"");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("May-Aug: Mo-Sa 14:30-Sunset; Su 10:30-Sunset; Sep-Apr off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("May-Oct; Nov-Apr off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Fr-Sa");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 03: Mo-Th 07:00-20:00; Apr 01-Oct 03: Fr-Su 07:00-21:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 14 07:00-13:00, 15:00-22:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-08:30; 15:30-16:30");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Dec 1-20: dusk-dawn off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1 off; Dec 25-26 off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1: off; Dec 25-26: off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 09:00-18:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep sunrise-sunset; Dec 1-20 dusk-dawn off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo off; Tu-Sa 09:30-19:00; Su 10:00-14:30; Jan 1 off; Dec 25-26 off");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo-Th 08:00-19:00, Fr 08:00-17:00, Su[-2] 08:00-15:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Lu-Di 10:00-18:00"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise; Sa 09:00-18:00;TU,su,pH OFF"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00h-19:00 h"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00h to 19:00 h"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09h to 19:00"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9h-19h"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9am-9pm"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00H-19:00 h"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,PH OFF"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,ph Off"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("05:00 – 22:00"); // long dash instead minus
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("05:00 - 22:00"); // minus
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-20:00 open \"Bei schönem Wetter. Falls unklar kann angerufen werden\""); // charset
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-22:00; Tu off; dec 31 off; Jan 1 off"); // symbols case
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00"); // leading zeros
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("09:00-9:30"); // leading zeros
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// {
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("Mo 08:00-11:00,14:00-17:00; Tu 08:00-11:00, 14:00-17:00; We 08:00-11:00; Th 08:00-11:00, 14:00-16:00; Fr 08:00-11:00");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
// }
|
||||
// }
|
||||
|
||||
line_num++;
|
||||
|
||||
OSMTimeRange oh = OSMTimeRange::FromString(datastr);
|
||||
if (!oh.IsValid()) {
|
||||
num_failed += count;
|
||||
desc[count]++;
|
||||
BOOST_TEST_MESSAGE("-- " << count << " :[" << datastr << "]");
|
||||
}
|
||||
num_total += count;
|
||||
}
|
||||
BOOST_CHECK_MESSAGE((num_failed == 0), "Failed " << num_failed << " of " << num_total << " (" << double(num_failed)/(double(num_total)/100) << "%)");
|
||||
std::stringstream desc_message;
|
||||
for (auto const & e : desc) {
|
||||
desc_message << "Weight: " << e.first << " Count: " << e.second << std::endl;
|
||||
}
|
||||
BOOST_TEST_MESSAGE(desc_message.str());
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE( OpeningHours_CountFailed )
|
||||
// {
|
||||
// std::ifstream datalist("opening-count.lst");
|
||||
// BOOST_REQUIRE_MESSAGE(datalist.is_open(), "Can't open ./opening-count.lst: " << std::strerror(errno));
|
||||
|
||||
// std::string line;
|
||||
// size_t line_num = 0;
|
||||
// size_t num_failed = 0;
|
||||
// size_t num_total = 0;
|
||||
// std::map<size_t, size_t> desc;
|
||||
|
||||
// while (std::getline(datalist, line))
|
||||
// {
|
||||
// size_t count = 1;
|
||||
// std::string datastr;
|
||||
|
||||
// auto d = line.find('|');
|
||||
// if (d == std::string::npos)
|
||||
// {
|
||||
// BOOST_WARN_MESSAGE((d != std::string::npos), "Incorrect line " << line_num << " format: " << line);
|
||||
// datastr = line;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// count = std::stol(line.substr(0,d));
|
||||
// datastr = line.substr(d+1);
|
||||
// }
|
||||
|
||||
// line_num++;
|
||||
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString(datastr);
|
||||
// if (!oh.IsValid()) {
|
||||
// num_failed += count;
|
||||
// desc[count]++;
|
||||
// BOOST_TEST_MESSAGE("-- " << count << " :[" << datastr << "]");
|
||||
// }
|
||||
// num_total += count;
|
||||
// }
|
||||
// BOOST_CHECK_MESSAGE((num_failed == 0), "Failed " << num_failed << " of " << num_total << " (" << double(num_failed)/(double(num_total)/100) << "%)");
|
||||
// std::stringstream desc_message;
|
||||
// for (auto const & e : desc) {
|
||||
// desc_message << "Weight: " << e.first << " Count: " << e.second << std::endl;
|
||||
// }
|
||||
// BOOST_TEST_MESSAGE(desc_message.str());
|
||||
// }
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||
#include <boost/spirit/include/phoenix_statement.hpp>
|
||||
#include <boost/spirit/include/phoenix_bind.hpp>
|
||||
#include <boost/spirit/include/phoenix_object.hpp>
|
||||
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
|
@ -41,42 +43,42 @@ class test_impl
|
|||
};
|
||||
phx::function<test_impl> const test = test_impl();
|
||||
|
||||
inline boost::posix_time::time_period make_time_period(boost::gregorian::date const & d,
|
||||
osmoh::TimeSpan const & ts)
|
||||
{
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
// inline boost::posix_time::time_period make_time_period(boost::gregorian::date const & d,
|
||||
// osmoh::TimeSpan const & ts)
|
||||
// {
|
||||
// using boost::posix_time::ptime;
|
||||
// using boost::posix_time::hours;
|
||||
// using boost::posix_time::minutes;
|
||||
// using boost::posix_time::time_period;
|
||||
|
||||
/// TODO(yershov@): Need create code for calculate real values
|
||||
ptime sunrise(d, hours(6));
|
||||
ptime sunset(d, hours(19));
|
||||
// /// TODO(yershov@): Need create code for calculate real values
|
||||
// ptime sunrise(d, hours(6));
|
||||
// ptime sunset(d, hours(19));
|
||||
|
||||
ptime t1, t2;
|
||||
// ptime t1, t2;
|
||||
|
||||
if (ts.from.flags & osmoh::Time::eSunrise)
|
||||
t1 = sunrise;
|
||||
else if (ts.from.flags & osmoh::Time::eSunset)
|
||||
t1 = sunset;
|
||||
else
|
||||
t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0));
|
||||
// if (ts.from.flags & osmoh::Time::eSunrise)
|
||||
// t1 = sunrise;
|
||||
// else if (ts.from.flags & osmoh::Time::eSunset)
|
||||
// t1 = sunset;
|
||||
// else
|
||||
// t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0));
|
||||
|
||||
t2 = t1;
|
||||
// t2 = t1;
|
||||
|
||||
if (ts.to.flags & osmoh::Time::eSunrise)
|
||||
t2 = sunrise;
|
||||
else if (ts.to.flags & osmoh::Time::eSunset)
|
||||
t2 = sunset;
|
||||
else
|
||||
{
|
||||
t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0));
|
||||
if (t2 < t1)
|
||||
t2 += hours(24);
|
||||
}
|
||||
// if (ts.to.flags & osmoh::Time::eSunrise)
|
||||
// t2 = sunrise;
|
||||
// else if (ts.to.flags & osmoh::Time::eSunset)
|
||||
// t2 = sunset;
|
||||
// else
|
||||
// {
|
||||
// t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0));
|
||||
// if (t2 < t1)
|
||||
// t2 += hours(24);
|
||||
// }
|
||||
|
||||
return time_period(t1, t2);
|
||||
}
|
||||
// return time_period(t1, t2);
|
||||
// }
|
||||
|
||||
namespace parsing
|
||||
{
|
||||
|
@ -94,18 +96,21 @@ class dash_ : public qi::symbols<wchar_t>
|
|||
add
|
||||
(L"-")
|
||||
/* not standard */
|
||||
(L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis")
|
||||
// (L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis")
|
||||
;
|
||||
}
|
||||
} dash;
|
||||
|
||||
class event_ : public qi::symbols<wchar_t, uint8_t>
|
||||
class event_ : public qi::symbols<char, osmoh::Time::EEvent>
|
||||
{
|
||||
public:
|
||||
event_()
|
||||
{
|
||||
add
|
||||
(L"dawn", osmoh::Time::eSunrise)(L"sunrise", osmoh::Time::eSunrise)(L"sunset", osmoh::Time::eSunset)(L"dusk", osmoh::Time::eSunset)
|
||||
("dawn", osmoh::Time::EEvent::eSunrise)
|
||||
("sunrise", osmoh::Time::EEvent::eSunrise)
|
||||
("sunset", osmoh::Time::EEvent::eSunset)
|
||||
("dusk", osmoh::Time::EEvent::eSunset)
|
||||
;
|
||||
}
|
||||
} event;
|
||||
|
@ -116,16 +121,16 @@ struct wdays_ : qi::symbols<wchar_t, unsigned>
|
|||
{
|
||||
add
|
||||
(L"mo", 0)(L"tu", 1)(L"we", 2)(L"th", 3)(L"fr", 4)(L"sa", 5)(L"su", 6) // en
|
||||
(L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en
|
||||
(L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru
|
||||
(L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it
|
||||
(L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp
|
||||
(L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional
|
||||
(L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian
|
||||
// (L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en
|
||||
// (L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru
|
||||
// (L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru
|
||||
// (L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr
|
||||
// (L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it
|
||||
// (L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp
|
||||
// (L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional
|
||||
// (L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian
|
||||
|
||||
(L"wd", 2)
|
||||
// (L"wd", 2)
|
||||
|
||||
;
|
||||
}
|
||||
|
@ -142,46 +147,46 @@ struct month_ : qi::symbols<wchar_t, unsigned>
|
|||
}
|
||||
} month;
|
||||
|
||||
struct hours_ : qi::symbols<char, uint8_t>
|
||||
struct hours_ : qi::symbols<char, osmoh::Time::THours>
|
||||
{
|
||||
hours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)
|
||||
// ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0_h)("01", 1_h)("02", 2_h)("03", 3_h)("04", 4_h)("05", 5_h)("06", 6_h)("07", 7_h)("08", 8_h)("09", 9_h)
|
||||
("10", 10_h)("11", 11_h)("12", 12_h)("13", 13_h)("14", 14_h)("15", 15_h)("16", 16_h)("17", 17_h)("18", 18_h)("19", 19_h)
|
||||
("20", 20_h)("21", 21_h)("22", 22_h)("23", 23_h)("24", 24_h)
|
||||
;
|
||||
}
|
||||
} hours;
|
||||
|
||||
struct exthours_ : qi::symbols<char, uint8_t>
|
||||
struct exthours_ : qi::symbols<char, osmoh::Time::THours>
|
||||
{
|
||||
exthours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)
|
||||
// ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0_h)("01", 1_h)("02", 2_h)("03", 3_h)("04", 4_h)("05", 5_h)("06", 6_h)("07", 7_h)("08", 8_h)("09", 9_h)
|
||||
("10", 10_h)("11", 11_h)("12", 12_h)("13", 13_h)("14", 14_h)("15", 15_h)("16", 16_h)("17", 17_h)("18", 18_h)("19", 19_h)
|
||||
("20", 20_h)("21", 21_h)("22", 22_h)("23", 23_h)("24", 24_h)("25", 25_h)("26", 26_h)("27", 27_h)("28", 28_h)("29", 29_h)
|
||||
("30", 30_h)("31", 31_h)("32", 32_h)("33", 33_h)("34", 34_h)("35", 35_h)("36", 36_h)("37", 37_h)("38", 38_h)("39", 39_h)
|
||||
("40", 40_h)("41", 41_h)("42", 42_h)("43", 43_h)("44", 44_h)("45", 45_h)("46", 46_h)("47", 47_h)("48", 48_h)
|
||||
;
|
||||
}
|
||||
} exthours;
|
||||
|
||||
struct minutes_ : qi::symbols<char, uint8_t>
|
||||
struct minutes_ : qi::symbols<char, osmoh::Time::TMinutes>
|
||||
{
|
||||
minutes_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49)
|
||||
("50", 50)("51", 51)("52", 52)("53", 53)("54", 54)("55", 55)("56", 56)("57", 57)("58", 58)("59", 59)
|
||||
// ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0_min)("01", 1_min)("02", 2_min)("03", 3_min)("04", 4_min)("05", 5_min)("06", 6_min)("07", 7_min)("08", 8_min)("09", 9_min)
|
||||
("10", 10_min)("11", 11_min)("12", 12_min)("13", 13_min)("14", 14_min)("15", 15_min)("16", 16_min)("17", 17_min)("18", 18_min)("19", 19_min)
|
||||
("20", 20_min)("21", 21_min)("22", 22_min)("23", 23_min)("24", 24_min)("25", 25_min)("26", 26_min)("27", 27_min)("28", 28_min)("29", 29_min)
|
||||
("30", 30_min)("31", 31_min)("32", 32_min)("33", 33_min)("34", 34_min)("35", 35_min)("36", 36_min)("37", 37_min)("38", 38_min)("39", 39_min)
|
||||
("40", 40_min)("41", 41_min)("42", 42_min)("43", 43_min)("44", 44_min)("45", 45_min)("46", 46_min)("47", 47_min)("48", 48_min)("49", 49_min)
|
||||
("50", 50_min)("51", 51_min)("52", 52_min)("53", 53_min)("54", 54_min)("55", 55_min)("56", 56_min)("57", 57_min)("58", 58_min)("59", 59_min)
|
||||
;
|
||||
}
|
||||
} minutes;
|
||||
|
@ -191,7 +196,7 @@ struct weeknum_ : qi::symbols<char, unsigned>
|
|||
weeknum_()
|
||||
{
|
||||
add
|
||||
( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9)
|
||||
// ( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
|
@ -207,7 +212,7 @@ struct daynum_ : qi::symbols<char, unsigned>
|
|||
daynum_()
|
||||
{
|
||||
add
|
||||
("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9)
|
||||
// ("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
|
@ -216,202 +221,202 @@ struct daynum_ : qi::symbols<char, unsigned>
|
|||
}
|
||||
} daynum;
|
||||
|
||||
template <class Iterator>
|
||||
class year_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> year;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
year_selector() : year_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
// template <class Iterator>
|
||||
// class year_selector : public qi::grammar<Iterator, space_type>
|
||||
// {
|
||||
// protected:
|
||||
// qi::rule<Iterator, space_type> year;
|
||||
// qi::rule<Iterator, space_type> year_range;
|
||||
// qi::rule<Iterator, space_type> main;
|
||||
// public:
|
||||
// year_selector() : year_selector::base_type(main)
|
||||
// {
|
||||
// using qi::uint_;
|
||||
// using qi::lit;
|
||||
// using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> _4digit = {};
|
||||
// static const qi::int_parser<unsigned, 10, 4, 4> _4digit = {};
|
||||
|
||||
year %= _4digit;
|
||||
year_range %= (year >> dash >> year >> '/' >> uint_)
|
||||
| (year >> dash >> year)
|
||||
| year >> char_('+')
|
||||
| year
|
||||
;
|
||||
main %= year_range % ',';
|
||||
}
|
||||
};
|
||||
// year %= _4digit;
|
||||
// year_range %= (year >> dash >> year >> '/' >> uint_)
|
||||
// | (year >> dash >> year)
|
||||
// | year >> char_('+')
|
||||
// | year
|
||||
// ;
|
||||
// main %= year_range % ',';
|
||||
// }
|
||||
// };
|
||||
|
||||
// template <typename Iterator>
|
||||
// class week_selector : public qi::grammar<Iterator, space_type>
|
||||
// {
|
||||
// protected:
|
||||
// qi::rule<Iterator, space_type> week;
|
||||
// qi::rule<Iterator, space_type> year_range;
|
||||
// qi::rule<Iterator, space_type> main;
|
||||
// public:
|
||||
// week_selector() : week_selector::base_type(main)
|
||||
// {
|
||||
// using qi::uint_;
|
||||
// using qi::lit;
|
||||
// using charset::char_;
|
||||
|
||||
// week %= (weeknum >> dash >> weeknum >> '/' >> uint_)
|
||||
// | (weeknum >> dash >> weeknum)
|
||||
// | weeknum
|
||||
// ;
|
||||
|
||||
// main %= charset::no_case[lit("week")] >> week % ',';
|
||||
// }
|
||||
// };
|
||||
|
||||
// template <typename Iterator>
|
||||
// class month_selector : public qi::grammar<Iterator, space_type>
|
||||
// {
|
||||
// protected:
|
||||
// qi::rule<Iterator, space_type> date;
|
||||
// qi::rule<Iterator, space_type> day_offset;
|
||||
// qi::rule<Iterator, space_type> date_with_offsets;
|
||||
// qi::rule<Iterator, space_type> monthday_range;
|
||||
// qi::rule<Iterator, space_type> month_range;
|
||||
// qi::rule<Iterator, space_type> main;
|
||||
// public:
|
||||
// month_selector() : month_selector::base_type(main)
|
||||
// {
|
||||
// using qi::int_;
|
||||
// using qi::lit;
|
||||
// using qi::double_;
|
||||
// using qi::lexeme;
|
||||
// using charset::char_;
|
||||
|
||||
// static const qi::int_parser<unsigned, 10, 4, 4> year = {};
|
||||
|
||||
// day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))];
|
||||
|
||||
// date %= charset::no_case[(-year >> month >> daynum)]
|
||||
// | (-year >> charset::no_case[lit("easter")])
|
||||
// | daynum >> !(lit(':') >> qi::digit)
|
||||
// ;
|
||||
|
||||
// date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset;
|
||||
|
||||
// monthday_range %= (date_with_offsets >> dash >> date_with_offsets)
|
||||
// | (date_with_offsets >> '+')
|
||||
// | date_with_offsets
|
||||
// | charset::no_case[(-year >> month >> dash >> month >> '/' >> int_)]
|
||||
// | charset::no_case[(-year >> month >> dash >> month)]
|
||||
// | charset::no_case[(-year >> month)]
|
||||
// ;
|
||||
|
||||
// month_range %= charset::no_case[(month >> dash >> month)]
|
||||
// | charset::no_case[month]
|
||||
// ;
|
||||
|
||||
// main %= (monthday_range % ',') | (month_range % ',');
|
||||
|
||||
// BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(month_range);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(monthday_range);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(date_with_offsets);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(date);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(day_offset);
|
||||
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
// template <typename Iterator>
|
||||
// class weekday_selector : public qi::grammar<Iterator, osmoh::TWeekdays(), space_type>
|
||||
// {
|
||||
// protected:
|
||||
// qi::rule<Iterator, uint8_t(), space_type> nth;
|
||||
// qi::rule<Iterator, uint16_t(), space_type> nth_entry;
|
||||
// qi::rule<Iterator, int32_t(), space_type, qi::locals<int8_t>> day_offset;
|
||||
// qi::rule<Iterator, space_type> holyday;
|
||||
// qi::rule<Iterator, space_type> holiday_sequence;
|
||||
// qi::rule<Iterator, osmoh::Weekday(), space_type> weekday_range;
|
||||
// qi::rule<Iterator, osmoh::TWeekdays(), space_type> weekday_sequence;
|
||||
// qi::rule<Iterator, osmoh::TWeekdays(), space_type> main;
|
||||
// public:
|
||||
// weekday_selector() : weekday_selector::base_type(main)
|
||||
// {
|
||||
// using qi::_a;
|
||||
// using qi::_1;
|
||||
// using qi::_2;
|
||||
// using qi::_val;
|
||||
// using qi::lit;
|
||||
// using qi::ushort_;
|
||||
// using boost::phoenix::at_c;
|
||||
|
||||
// nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5);
|
||||
|
||||
// nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)]
|
||||
// | (lit('-') >> nth) [_val |= (0x0100 << (_1 - 1))]
|
||||
// | nth [_val |= (1 << (_1 - 1))]
|
||||
// ;
|
||||
|
||||
// day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))];
|
||||
// holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")];
|
||||
// holiday_sequence %= holyday % ',';
|
||||
// weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
// >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L','
|
||||
// >> L']' >> day_offset[at_c<2>(_val) = _1])
|
||||
// | (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']')
|
||||
// | charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)]
|
||||
// | charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
// ;
|
||||
|
||||
// weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':');
|
||||
|
||||
// main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1])
|
||||
// | weekday_sequence[_val = _1] >> -(-lit(L',') >> holiday_sequence)
|
||||
// | holiday_sequence
|
||||
// ;
|
||||
|
||||
// BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(weekday_sequence);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(weekday_range);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(holiday_sequence);
|
||||
|
||||
// }
|
||||
// };
|
||||
|
||||
template <typename Iterator>
|
||||
class week_selector : public qi::grammar<Iterator, space_type>
|
||||
class time_selector : public qi::grammar<Iterator, osmoh::TTimespans(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> week;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
week_selector() : week_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
|
||||
week %= (weeknum >> dash >> weeknum >> '/' >> uint_)
|
||||
| (weeknum >> dash >> weeknum)
|
||||
| weeknum
|
||||
;
|
||||
|
||||
main %= charset::no_case[lit("week")] >> week % ',';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class month_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> date;
|
||||
qi::rule<Iterator, space_type> day_offset;
|
||||
qi::rule<Iterator, space_type> date_with_offsets;
|
||||
qi::rule<Iterator, space_type> monthday_range;
|
||||
qi::rule<Iterator, space_type> month_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
month_selector() : month_selector::base_type(main)
|
||||
{
|
||||
using qi::int_;
|
||||
using qi::lit;
|
||||
using qi::double_;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> year = {};
|
||||
|
||||
day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))];
|
||||
|
||||
date %= charset::no_case[(-year >> month >> daynum)]
|
||||
| (-year >> charset::no_case[lit("easter")])
|
||||
| daynum >> !(lit(':') >> qi::digit)
|
||||
;
|
||||
|
||||
date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset;
|
||||
|
||||
monthday_range %= (date_with_offsets >> dash >> date_with_offsets)
|
||||
| (date_with_offsets >> '+')
|
||||
| date_with_offsets
|
||||
| charset::no_case[(-year >> month >> dash >> month >> '/' >> int_)]
|
||||
| charset::no_case[(-year >> month >> dash >> month)]
|
||||
| charset::no_case[(-year >> month)]
|
||||
;
|
||||
|
||||
month_range %= charset::no_case[(month >> dash >> month)]
|
||||
| charset::no_case[month]
|
||||
;
|
||||
|
||||
main %= (monthday_range % ',') | (month_range % ',');
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(month_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(monthday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date_with_offsets);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date);
|
||||
BOOST_SPIRIT_DEBUG_NODE(day_offset);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
class weekday_selector : public qi::grammar<Iterator, osmoh::TWeekdays(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, uint8_t(), space_type> nth;
|
||||
qi::rule<Iterator, uint16_t(), space_type> nth_entry;
|
||||
qi::rule<Iterator, int32_t(), space_type, qi::locals<int8_t>> day_offset;
|
||||
qi::rule<Iterator, space_type> holyday;
|
||||
qi::rule<Iterator, space_type> holiday_sequence;
|
||||
qi::rule<Iterator, osmoh::Weekday(), space_type> weekday_range;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> weekday_sequence;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> main;
|
||||
public:
|
||||
weekday_selector() : weekday_selector::base_type(main)
|
||||
{
|
||||
using qi::_a;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::ushort_;
|
||||
using boost::phoenix::at_c;
|
||||
|
||||
nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5);
|
||||
|
||||
nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)]
|
||||
| (lit('-') >> nth) [_val |= (0x0100 << (_1 - 1))]
|
||||
| nth [_val |= (1 << (_1 - 1))]
|
||||
;
|
||||
|
||||
day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))];
|
||||
holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")];
|
||||
holiday_sequence %= holyday % ',';
|
||||
weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
>> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L','
|
||||
>> L']' >> day_offset[at_c<2>(_val) = _1])
|
||||
| (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']')
|
||||
| charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)]
|
||||
| charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
;
|
||||
|
||||
weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':');
|
||||
|
||||
main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1])
|
||||
| weekday_sequence[_val = _1] >> -(-lit(L',') >> holiday_sequence)
|
||||
| holiday_sequence
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(holiday_sequence);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> extended_hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> extended_hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> variable_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> extended_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> time;
|
||||
qi::rule<Iterator, osmoh::TimeSpan(), space_type> timespan;
|
||||
qi::rule<Iterator, osmoh::TTimeSpans(), space_type> main;
|
||||
qi::rule<Iterator, osmoh::Timespan(), space_type> timespan;
|
||||
qi::rule<Iterator, osmoh::TTimespans(), space_type> main;
|
||||
|
||||
class validate_timespan_impl
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
struct result { typedef bool type; };
|
||||
// class validate_timespan_impl
|
||||
// {
|
||||
// public:
|
||||
// template <typename T>
|
||||
// struct result { typedef bool type; };
|
||||
|
||||
bool operator() (osmoh::TimeSpan const & ts) const
|
||||
{
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::time_duration;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
// bool operator() (osmoh::TimeSpan const & ts) const
|
||||
// {
|
||||
// using boost::posix_time::ptime;
|
||||
// using boost::posix_time::time_duration;
|
||||
// using boost::posix_time::hours;
|
||||
// using boost::posix_time::minutes;
|
||||
// using boost::posix_time::time_period;
|
||||
|
||||
bool result = true;
|
||||
if (ts.period.flags)
|
||||
{
|
||||
time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts);
|
||||
result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */));
|
||||
}
|
||||
// bool result = true;
|
||||
// if (ts.period.flags)
|
||||
// {
|
||||
// time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts);
|
||||
// result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */));
|
||||
// }
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
// return result;
|
||||
// }
|
||||
// };
|
||||
|
||||
public:
|
||||
time_selector() : time_selector::base_type(main)
|
||||
|
@ -423,39 +428,29 @@ class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_ty
|
|||
using qi::_a;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::_pass;
|
||||
// using qi::_pass;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using boost::phoenix::bind;
|
||||
using boost::phoenix::construct;
|
||||
|
||||
phx::function<validate_timespan_impl> const validate_timespan = validate_timespan_impl();
|
||||
// phx::function<validate_timespan_impl> const validate_timespan = validate_timespan_impl();
|
||||
|
||||
hour_minutes = hours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
hour_minutes = (hours >> lit(':') >> minutes)[bind(&osmoh::Time::SetHours, _val, _1),
|
||||
bind(&osmoh::Time::SetMinutes, _val, _2)]
|
||||
;
|
||||
|
||||
extended_hour_minutes = exthours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
extended_hour_minutes = (exthours >> lit(':') >> minutes)[bind(&osmoh::Time::SetHours, _val, _1),
|
||||
bind(&osmoh::Time::SetMinutes, _val, _2)]
|
||||
;
|
||||
|
||||
variable_time =
|
||||
(lit('(')
|
||||
>> charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
>> (
|
||||
char_('+')[at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| char_('-')[at_c<2>(_val) |= osmoh::Time::eMinus]
|
||||
)
|
||||
>> hour_minutes[at_c<2>(_1) |= at_c<2>(_val), _val = _1]
|
||||
>> charset::no_case[event][bind(&osmoh::Time::SetEvent, _val, _1)]
|
||||
>> (char_('+') | char_('-')[_val = -_val])
|
||||
>> hour_minutes
|
||||
>> lit(')')
|
||||
)
|
||||
| charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
| charset::no_case[event][bind(&osmoh::Time::SetEvent, _val, _1)]
|
||||
;
|
||||
|
||||
extended_time %= extended_hour_minutes | variable_time;
|
||||
|
@ -464,21 +459,34 @@ class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_ty
|
|||
|
||||
timespan =
|
||||
(time >> dash >> extended_time >> L'/' >> hour_minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<3>(_val) = _3]
|
||||
[bind(&osmoh::Timespan::SetStart, _val, _1),
|
||||
bind(&osmoh::Timespan::SetEnd, _val, _2),
|
||||
bind(&osmoh::Timespan::SetPeriod, _val, _3)]
|
||||
|
||||
| (time >> dash >> extended_time >> L'/' >> minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<1>(at_c<3>(_val)) = _3, at_c<2>(at_c<3>(_val)) = osmoh::Time::eMinutes]
|
||||
[bind(&osmoh::Timespan::SetStart, _val, _1),
|
||||
bind(&osmoh::Timespan::SetEnd, _val, _2),
|
||||
bind(&osmoh::Timespan::SetPeriod, _val, _3)]
|
||||
// bind(&osmoh::Timespan::SetPeriod, _val, construct<osmoh::Time::TMinutes>(_3))]
|
||||
|
||||
| (time >> dash >> extended_time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
[bind(&osmoh::Timespan::SetStart, _val, _1),
|
||||
bind(&osmoh::Timespan::SetEnd, _val, _2),
|
||||
bind(&osmoh::Timespan::SetPlus, _val, true)]
|
||||
|
||||
| (time >> dash >> extended_time)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2]
|
||||
[bind(&osmoh::Timespan::SetStart, _val, _1),
|
||||
bind(&osmoh::Timespan::SetEnd, _val, _2)]
|
||||
|
||||
| (time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| time [at_c<0>(_val) = _1]
|
||||
[bind(&osmoh::Timespan::SetStart, _val, _1),
|
||||
bind(&osmoh::Timespan::SetPlus, _val, true)]
|
||||
|
||||
| time[bind(&osmoh::Timespan::SetStart, _val, _1)]
|
||||
;
|
||||
|
||||
main %= timespan[_pass = validate_timespan(_1)] % ',';
|
||||
// main %= timespan[_pass = validate_timespan(_1)] % ',';
|
||||
main %= timespan % ',';
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(timespan);
|
||||
|
@ -489,130 +497,130 @@ class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_ty
|
|||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class selectors : public qi::grammar<Iterator, osmoh::TimeRule(), space_type>
|
||||
{
|
||||
protected:
|
||||
weekday_selector<Iterator> weekday_selector;
|
||||
time_selector<Iterator> time_selector;
|
||||
year_selector<Iterator> year_selector;
|
||||
month_selector<Iterator> month_selector;
|
||||
week_selector<Iterator> week_selector;
|
||||
// template <typename Iterator>
|
||||
// class selectors : public qi::grammar<Iterator, osmoh::TimeRule(), space_type>
|
||||
// {
|
||||
// protected:
|
||||
// weekday_selector<Iterator> weekday_selector;
|
||||
// time_selector<Iterator> time_selector;
|
||||
// year_selector<Iterator> year_selector;
|
||||
// month_selector<Iterator> month_selector;
|
||||
// week_selector<Iterator> week_selector;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> small_range_selectors;
|
||||
qi::rule<Iterator, space_type> wide_range_selectors;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> main;
|
||||
public:
|
||||
selectors() : selectors::base_type(main)
|
||||
{
|
||||
using qi::_1;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using osmoh::State;
|
||||
// qi::rule<Iterator, std::string(), space_type> comment;
|
||||
// qi::rule<Iterator, osmoh::TimeRule(), space_type> small_range_selectors;
|
||||
// qi::rule<Iterator, space_type> wide_range_selectors;
|
||||
// qi::rule<Iterator, osmoh::TimeRule(), space_type> main;
|
||||
// public:
|
||||
// selectors() : selectors::base_type(main)
|
||||
// {
|
||||
// using qi::_1;
|
||||
// using qi::_val;
|
||||
// using qi::lit;
|
||||
// using qi::lexeme;
|
||||
// using charset::char_;
|
||||
// using boost::phoenix::at_c;
|
||||
// using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'];
|
||||
wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':');
|
||||
small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]);
|
||||
// comment %= lexeme['"' >> +(char_ - '"') >> '"'];
|
||||
// wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':');
|
||||
// small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]);
|
||||
|
||||
main =
|
||||
(
|
||||
lit(L"24/7")
|
||||
| lit(L"24時間営業")
|
||||
| lit(L"7/24")
|
||||
| lit(L"24時間")
|
||||
| charset::no_case[lit(L"daily 24/7")]
|
||||
| charset::no_case[lit(L"24 hours")]
|
||||
| charset::no_case[lit(L"24 horas")]
|
||||
| charset::no_case[lit(L"круглосуточно")]
|
||||
| charset::no_case[lit(L"24 часа")]
|
||||
| charset::no_case[lit(L"24 hrs")]
|
||||
| charset::no_case[lit(L"nonstop")]
|
||||
| charset::no_case[lit(L"24hrs")]
|
||||
| charset::no_case[lit(L"open 24 hours")]
|
||||
| charset::no_case[lit(L"24 stunden")]
|
||||
)[at_c<0>(at_c<2>(_val)) = State::eOpen]
|
||||
| (-wide_range_selectors >> small_range_selectors[_val = _1, at_c<0>(at_c<2>(_val)) = State::eOpen])
|
||||
;
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(small_range_selectors);
|
||||
BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors);
|
||||
}
|
||||
};
|
||||
// main =
|
||||
// (
|
||||
// lit(L"24/7")
|
||||
// | lit(L"24時間営業")
|
||||
// | lit(L"7/24")
|
||||
// | lit(L"24時間")
|
||||
// | charset::no_case[lit(L"daily 24/7")]
|
||||
// | charset::no_case[lit(L"24 hours")]
|
||||
// | charset::no_case[lit(L"24 horas")]
|
||||
// | charset::no_case[lit(L"круглосуточно")]
|
||||
// | charset::no_case[lit(L"24 часа")]
|
||||
// | charset::no_case[lit(L"24 hrs")]
|
||||
// | charset::no_case[lit(L"nonstop")]
|
||||
// | charset::no_case[lit(L"24hrs")]
|
||||
// | charset::no_case[lit(L"open 24 hours")]
|
||||
// | charset::no_case[lit(L"24 stunden")]
|
||||
// )[at_c<0>(at_c<2>(_val)) = State::eOpen]
|
||||
// | (-wide_range_selectors >> small_range_selectors[_val = _1, at_c<0>(at_c<2>(_val)) = State::eOpen])
|
||||
// ;
|
||||
// BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(small_range_selectors);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors);
|
||||
// }
|
||||
// };
|
||||
|
||||
template <typename Iterator>
|
||||
class time_domain : public qi::grammar<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>>
|
||||
{
|
||||
protected:
|
||||
selectors<Iterator> selector_sequence;
|
||||
// template <typename Iterator>
|
||||
// class time_domain : public qi::grammar<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>>
|
||||
// {
|
||||
// protected:
|
||||
// selectors<Iterator> selector_sequence;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, space_type> separator;
|
||||
qi::rule<Iterator, space_type> base_separator;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> rule_sequence;
|
||||
qi::rule<Iterator, osmoh::State(), space_type> rule_modifier;
|
||||
qi::rule<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>> main;
|
||||
// qi::rule<Iterator, std::string(), space_type> comment;
|
||||
// qi::rule<Iterator, space_type> separator;
|
||||
// qi::rule<Iterator, space_type> base_separator;
|
||||
// qi::rule<Iterator, osmoh::TimeRule(), space_type> rule_sequence;
|
||||
// qi::rule<Iterator, osmoh::State(), space_type> rule_modifier;
|
||||
// qi::rule<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>> main;
|
||||
|
||||
public:
|
||||
time_domain() : time_domain::base_type(main)
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using qi::_1;
|
||||
using qi::_a;
|
||||
using qi::_val;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using qi::lazy;
|
||||
using qi::eps;
|
||||
using osmoh::State;
|
||||
// public:
|
||||
// time_domain() : time_domain::base_type(main)
|
||||
// {
|
||||
// using qi::lit;
|
||||
// using qi::lexeme;
|
||||
// using qi::_1;
|
||||
// using qi::_a;
|
||||
// using qi::_val;
|
||||
// using charset::char_;
|
||||
// using boost::phoenix::at_c;
|
||||
// using qi::lazy;
|
||||
// using qi::eps;
|
||||
// using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')'];
|
||||
base_separator = lit(';') | lit("||");
|
||||
separator = lit(';') | lit("||") | lit(',');
|
||||
// comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')'];
|
||||
// base_separator = lit(';') | lit("||");
|
||||
// separator = lit(';') | lit("||") | lit(',');
|
||||
|
||||
rule_modifier =
|
||||
(charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1])
|
||||
| ((charset::no_case[lit("closed") | lit("off")])[at_c<0>(_val) = State::eClosed] >> -comment[at_c<1>(_val) = _1])
|
||||
| (charset::no_case[lit("unknown")][at_c<0>(_val) = State::eUnknown] >> -comment[at_c<1>(_val) = _1])
|
||||
| comment[at_c<0>(_val) = State::eUnknown, at_c<1>(_val) = _1]
|
||||
;
|
||||
// rule_modifier =
|
||||
// (charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1])
|
||||
// | ((charset::no_case[lit("closed") | lit("off")])[at_c<0>(_val) = State::eClosed] >> -comment[at_c<1>(_val) = _1])
|
||||
// | (charset::no_case[lit("unknown")][at_c<0>(_val) = State::eUnknown] >> -comment[at_c<1>(_val) = _1])
|
||||
// | comment[at_c<0>(_val) = State::eUnknown, at_c<1>(_val) = _1]
|
||||
// ;
|
||||
|
||||
rule_sequence = selector_sequence[_val = _1]
|
||||
>> -rule_modifier[at_c<2>(_val) = _1, at_c<3>(_val) = 1];
|
||||
// rule_sequence = selector_sequence[_val = _1]
|
||||
// >> -rule_modifier[at_c<2>(_val) = _1, at_c<3>(_val) = 1];
|
||||
|
||||
main %= -(lit("opening_hours") >> lit('='))
|
||||
>> rule_sequence[_a = phx::val(&base_separator),
|
||||
phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a);
|
||||
// main %= -(lit("opening_hours") >> lit('='))
|
||||
// >> rule_sequence[_a = phx::val(&base_separator),
|
||||
// phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a);
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_modifier);
|
||||
}
|
||||
};
|
||||
// BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(rule_sequence);
|
||||
// BOOST_SPIRIT_DEBUG_NODE(rule_modifier);
|
||||
// }
|
||||
// };
|
||||
|
||||
template <typename Iterator>
|
||||
inline bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context)
|
||||
{
|
||||
using qi::phrase_parse;
|
||||
using charset::space;
|
||||
// template <typename Iterator>
|
||||
// inline bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context)
|
||||
// {
|
||||
// using qi::phrase_parse;
|
||||
// using charset::space;
|
||||
|
||||
time_domain<Iterator> time_domain;
|
||||
// time_domain<Iterator> time_domain;
|
||||
|
||||
bool r = phrase_parse(
|
||||
first, /* start iterator */
|
||||
last, /* end iterator */
|
||||
time_domain, /* the parser */
|
||||
space, /* the skip-parser */
|
||||
context /* result storage */
|
||||
);
|
||||
// bool r = phrase_parse(
|
||||
// first, /* start iterator */
|
||||
// last, /* end iterator */
|
||||
// time_domain, /* the parser */
|
||||
// space, /* the skip-parser */
|
||||
// context /* result storage */
|
||||
// );
|
||||
|
||||
if (first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
// if (first != last) // fail if we did not get a full match
|
||||
// return false;
|
||||
// return r;
|
||||
// }
|
||||
} // namespace parsing
|
||||
} // namespace osmoh
|
||||
|
|
|
@ -26,270 +26,486 @@
|
|||
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <cstdlib>
|
||||
#include <codecvt>
|
||||
|
||||
namespace osmoh
|
||||
{
|
||||
|
||||
std::ostream & operator << (std::ostream & s, Time const & t)
|
||||
Time::Time(TMinutes const minutes)
|
||||
{
|
||||
bool event = (t.flags & Time::eSunrise) || (t.flags & Time::eSunset);
|
||||
if (event)
|
||||
s << ((t.flags & Time::eSunrise) ? "sunrise" : "sunset") << " (";
|
||||
std::ios_base::fmtflags sf = s.flags();
|
||||
if (t.flags & (Time::ePlus | Time::eMinus))
|
||||
s << ((t.flags & Time::ePlus) ? "+" : "-");
|
||||
if (t.flags & Time::eHours)
|
||||
s << std::setw(2) << std::setfill('0') << (int)t.hours;
|
||||
if (t.flags & Time::eMinutes)
|
||||
s << ":" << std::setw(2) << std::setfill('0') << (int)t.minutes;
|
||||
s.flags(sf);
|
||||
if (event)
|
||||
s << ")";
|
||||
return s;
|
||||
SetMinutes(minutes);
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & s, TimeSpan const & span)
|
||||
{
|
||||
s << span.from;
|
||||
if (span.to.flags)
|
||||
s << '-' << span.to;
|
||||
if (span.flags == Time::ePlus)
|
||||
s << "...";
|
||||
if (span.flags == Time::eExt)
|
||||
s << '/' << span.period;
|
||||
// Time::Time(THours const hours, TMinutes const minutes) { }
|
||||
// Time::Time(EEvent const event, THours const hours = 0, TMinutes const minutes = 0) { }
|
||||
|
||||
return s;
|
||||
Time::THours::rep Time::GetHoursCount() const
|
||||
{
|
||||
return GetHours().count();
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & s, Weekday const & w)
|
||||
Time::TMinutes::rep Time::GetMinutesCount() const
|
||||
{
|
||||
static char const * wdays[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"};
|
||||
static uint8_t const kDaysInWeek = 7;
|
||||
static uint8_t const kWeeksInMonth = 5;
|
||||
|
||||
for (size_t i = 0; i < kDaysInWeek; ++i)
|
||||
{
|
||||
if (w.weekdays & (1 << i))
|
||||
{
|
||||
if (w.weekdays & ((1 << i) - 1))
|
||||
s << ',';
|
||||
s << wdays[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (w.nth)
|
||||
{
|
||||
s << "[";
|
||||
|
||||
uint8_t a = w.nth & 0xFF;
|
||||
for (size_t i = 0; i < kWeeksInMonth; ++i)
|
||||
{
|
||||
if (a & (1 << i))
|
||||
{
|
||||
if (a & ((1 << i) - 1))
|
||||
s << ',';
|
||||
s << (i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
a = (w.nth >> 8) & 0xFF;
|
||||
for (size_t i = 0; i < kWeeksInMonth; ++i)
|
||||
{
|
||||
if (a & (1 << i))
|
||||
{
|
||||
if (a & ((1 << i) - 1))
|
||||
s << ',';
|
||||
s << '-' << (i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
s << "]";
|
||||
}
|
||||
|
||||
if (w.offset)
|
||||
s << ' ' << w.offset << " day(s)";
|
||||
return s;
|
||||
return GetMinutes().count();
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & s, State const & w)
|
||||
Time::THours Time::GetHours() const
|
||||
{
|
||||
static char const * st[] = {"unknown", "closed", "open"};
|
||||
s << ' ' << st[w.state] << " " << w.comment;
|
||||
return s;
|
||||
if (IsEvent())
|
||||
return GetEventTime().GetHours();
|
||||
else if (IsEventOffset())
|
||||
return (GetEventTime() - *this).GetHours();
|
||||
return std::chrono::duration_cast<THours>(m_duration);
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & s, TimeRule const & w)
|
||||
Time::TMinutes Time::GetMinutes() const
|
||||
{
|
||||
for (auto const & e : w.weekdays)
|
||||
s << e;
|
||||
if (!w.weekdays.empty() && !w.timespan.empty())
|
||||
s << ' ';
|
||||
for (auto const & e : w.timespan)
|
||||
s << e;
|
||||
|
||||
std::cout << "Weekdays size " << w.weekdays.size() <<
|
||||
" Timespan size " << w.timespan.size() << std::endl;
|
||||
return s << w.state;
|
||||
}
|
||||
} // namespace osmoh
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p)
|
||||
{
|
||||
using boost::gregorian::days;
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
time_period tp1 = osmoh::make_time_period(d-days(1), ts);
|
||||
time_period tp2 = osmoh::make_time_period(d, ts);
|
||||
/* very useful in debug */
|
||||
// std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl;
|
||||
// std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl;
|
||||
return tp1.contains(p) || tp2.contains(p);
|
||||
if (IsEvent())
|
||||
return GetEventTime().GetMinutes();
|
||||
else if (IsEventOffset())
|
||||
return (GetEventTime() - *this).GetMinutes();
|
||||
return std::chrono::duration_cast<TMinutes>(m_duration) - GetHours();
|
||||
}
|
||||
|
||||
bool check_weekday(osmoh::Weekday const & wd, boost::gregorian::date const & d)
|
||||
void Time::SetHours(THours const hours)
|
||||
{
|
||||
using namespace boost::gregorian;
|
||||
|
||||
bool hit = false;
|
||||
typedef nth_day_of_the_week_in_month nth_dow;
|
||||
if (wd.nth)
|
||||
{
|
||||
for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i)
|
||||
{
|
||||
if (!(wd.weekdays & (1 << i)))
|
||||
continue;
|
||||
|
||||
uint8_t a = wd.nth & 0xFF;
|
||||
for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j)
|
||||
{
|
||||
if (a & (1 << j))
|
||||
{
|
||||
nth_dow ndm(nth_dow::week_num(j + 1), nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month());
|
||||
hit |= (d == ndm.get_date(d.year()));
|
||||
}
|
||||
}
|
||||
a = (wd.nth >> 8) & 0xFF;
|
||||
for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j)
|
||||
{
|
||||
if (a & (1 << j))
|
||||
{
|
||||
last_day_of_the_week_in_month lwdm(nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month());
|
||||
hit |= (d == ((lwdm.get_date(d.year()) - weeks(j)) + days(wd.offset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i)
|
||||
{
|
||||
if (!(wd.weekdays & (1 << i)))
|
||||
continue;
|
||||
hit |= (d.day_of_week() == ((i + 1 == 7) ? 0 : (i + 1)));
|
||||
}
|
||||
}
|
||||
/* very useful in debug */
|
||||
// std::cout << d.day_of_week() << " " << d << " --> " << wd << (hit ? " hit" : " miss") << std::endl;
|
||||
return hit;
|
||||
m_state |= eHaveHours | eHaveMinutes;
|
||||
m_duration += hours;
|
||||
}
|
||||
|
||||
bool check_rule(osmoh::TimeRule const & r, std::tm const & stm,
|
||||
std::ostream * hitcontext = nullptr)
|
||||
void Time::SetMinutes(TMinutes const minutes)
|
||||
{
|
||||
bool next = false;
|
||||
|
||||
// check 24/7
|
||||
if (r.weekdays.empty() && r.timespan.empty() && r.state.state == osmoh::State::eOpen)
|
||||
return true;
|
||||
|
||||
boost::gregorian::date date = boost::gregorian::date_from_tm(stm);
|
||||
boost::posix_time::ptime pt = boost::posix_time::ptime_from_tm(stm);
|
||||
|
||||
next = r.weekdays.empty();
|
||||
for (auto const & wd : r.weekdays)
|
||||
{
|
||||
if (check_weekday(wd, date))
|
||||
{
|
||||
if (hitcontext)
|
||||
*hitcontext << wd << " ";
|
||||
next = true;
|
||||
}
|
||||
}
|
||||
if (!next)
|
||||
return next;
|
||||
|
||||
next = r.timespan.empty();
|
||||
for (auto const & ts : r.timespan)
|
||||
{
|
||||
if (check_timespan(ts, date, pt))
|
||||
{
|
||||
if (hitcontext)
|
||||
*hitcontext << ts << " ";
|
||||
next = true;
|
||||
}
|
||||
}
|
||||
return next && !(r.timespan.empty() && r.weekdays.empty());
|
||||
}
|
||||
} // anonymouse namespace
|
||||
|
||||
OSMTimeRange OSMTimeRange::FromString(std::string const & rules)
|
||||
{
|
||||
OSMTimeRange timeRange;
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; // could not work on android
|
||||
std::wstring src = converter.from_bytes(rules); // rules should be wstring
|
||||
timeRange.m_valid = osmoh::parsing::parse_timerange(src.begin(), src.end(), timeRange.m_rules);
|
||||
return timeRange;
|
||||
m_state |= eHaveMinutes;
|
||||
if (minutes > THours(1))
|
||||
m_state |= eHaveHours;
|
||||
m_duration += minutes;
|
||||
}
|
||||
|
||||
OSMTimeRange & OSMTimeRange::UpdateState(time_t timestamp)
|
||||
void Time::SetEvent(EEvent const event)
|
||||
{
|
||||
std::tm stm = *localtime(×tamp);
|
||||
m_event = event;
|
||||
}
|
||||
|
||||
osmoh::State::EState true_state[3][3] = {
|
||||
{osmoh::State::eUnknown, osmoh::State::eClosed, osmoh::State::eOpen},
|
||||
{osmoh::State::eClosed , osmoh::State::eClosed, osmoh::State::eOpen},
|
||||
{osmoh::State::eOpen , osmoh::State::eClosed, osmoh::State::eOpen}
|
||||
};
|
||||
bool Time::IsEvent() const
|
||||
{
|
||||
return m_event != EEvent::eNotEvent;
|
||||
}
|
||||
|
||||
osmoh::State::EState false_state[3][3] = {
|
||||
{osmoh::State::eUnknown, osmoh::State::eOpen , osmoh::State::eClosed},
|
||||
{osmoh::State::eClosed , osmoh::State::eClosed , osmoh::State::eClosed},
|
||||
{osmoh::State::eOpen , osmoh::State::eOpen , osmoh::State::eOpen}
|
||||
};
|
||||
bool Time::IsEventOffset() const
|
||||
{
|
||||
return IsEvent() && m_state != eIsNotTime;
|
||||
}
|
||||
|
||||
m_state = osmoh::State::eUnknown;
|
||||
m_comment = std::string();
|
||||
bool Time::IsHoursMinutes() const
|
||||
{
|
||||
return !IsEvent() && (m_state & (eHaveHours | eHaveMinutes));
|
||||
}
|
||||
|
||||
for (auto const & el : m_rules)
|
||||
{
|
||||
bool hit = false;
|
||||
if ((hit = check_rule(el, stm)))
|
||||
{
|
||||
m_state = true_state[m_state][el.state.state];
|
||||
m_comment = el.state.comment;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state = false_state[m_state][el.state.state];
|
||||
}
|
||||
/* very useful in debug */
|
||||
// char const * st[] = {"unknown", "closed", "open"};
|
||||
// std::cout << "-[" << hit << "]-------------------[" << el << "]: " << st[m_state] << "--------------------" << std::endl;
|
||||
}
|
||||
bool Time::IsMinutes() const
|
||||
{
|
||||
return !IsEvent() && ((m_state & eHaveMinutes) && !(m_state & eHaveHours));
|
||||
}
|
||||
|
||||
bool Time::IsTime() const
|
||||
{
|
||||
return IsHoursMinutes() || IsEvent();
|
||||
}
|
||||
|
||||
bool Time::HasValue() const
|
||||
{
|
||||
return IsEvent() || IsTime() || IsMinutes();
|
||||
}
|
||||
|
||||
Time & Time::operator-(Time const & time)
|
||||
{
|
||||
m_duration -= time.m_duration;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OSMTimeRange & OSMTimeRange::UpdateState(std::string const & timestr, char const * timefmt)
|
||||
Time & Time::operator-()
|
||||
{
|
||||
std::tm when = {};
|
||||
std::stringstream ss(timestr);
|
||||
ss >> std::get_time(&when, timefmt);
|
||||
return UpdateState(std::mktime(&when));
|
||||
m_duration = -m_duration;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Time Time::GetEventTime() const {return {};}; // TODO(mgsergio): get real time
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, Time::EEvent const event)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case Time::EEvent::eNotEvent:
|
||||
ost << "NotEvent";
|
||||
break;
|
||||
case Time::EEvent::eSunrise:
|
||||
ost << "sunrise";
|
||||
break;
|
||||
case Time::EEvent::eSunset:
|
||||
ost << "sunset";
|
||||
break;
|
||||
case Time::EEvent::eDawn:
|
||||
ost << "dawn";
|
||||
break;
|
||||
case Time::EEvent::eDusk:
|
||||
ost << "dusk";
|
||||
break;
|
||||
}
|
||||
return ost;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, Time const & time)
|
||||
{
|
||||
std::ios_base::fmtflags backupFlags = ost.flags();
|
||||
if (!time.IsTime() && !time.IsEvent())
|
||||
{
|
||||
ost << "hh:mm";
|
||||
return ost;
|
||||
}
|
||||
|
||||
auto const minutes = time.GetMinutesCount();
|
||||
auto const hours = time.GetHoursCount();
|
||||
if (time.IsEvent())
|
||||
{
|
||||
if (time.IsEventOffset())
|
||||
{
|
||||
ost << '(' << hours;
|
||||
if (hours < 0)
|
||||
ost << '-';
|
||||
else
|
||||
ost << '+';
|
||||
ost << std::setw(2) << std::setfill('0')
|
||||
<< std::abs(hours)
|
||||
<< ':' << std::setw(2)
|
||||
<< std::abs(minutes) << ')';
|
||||
}
|
||||
ost << time.GetEvent();
|
||||
}
|
||||
if (time.IsMinutes())
|
||||
{
|
||||
ost << std::setw(2) << std::setfill('0')
|
||||
<< std::abs(minutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
ost << std::setw(2) << std::setfill('0')
|
||||
<< std::abs(hours)
|
||||
<< ':' << std::setw(2)
|
||||
<< std::abs(minutes);
|
||||
}
|
||||
ost.flags(backupFlags);
|
||||
return ost;
|
||||
}
|
||||
|
||||
|
||||
bool Timespan::IsOpen() const
|
||||
{
|
||||
return !m_end.HasValue();
|
||||
}
|
||||
|
||||
bool Timespan::HasPlus() const
|
||||
{
|
||||
return m_plus;
|
||||
}
|
||||
|
||||
bool Timespan::HasPeriod() const
|
||||
{
|
||||
return m_period.HasValue();
|
||||
}
|
||||
|
||||
Time const & Timespan::GetStart() const
|
||||
{
|
||||
return m_start;
|
||||
}
|
||||
|
||||
Time const & Timespan::GetEnd() const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
Time const & Timespan::GetPeriod() const
|
||||
{
|
||||
return m_period;
|
||||
}
|
||||
|
||||
void Timespan::SetStart(Time const & start)
|
||||
{
|
||||
m_start = start;
|
||||
}
|
||||
|
||||
void Timespan::SetEnd(Time const & end)
|
||||
{
|
||||
m_end = end;
|
||||
}
|
||||
|
||||
void Timespan::SetPeriod(Time const & period)
|
||||
{
|
||||
m_period = period;
|
||||
}
|
||||
|
||||
void Timespan::SetPlus(bool const plus)
|
||||
{
|
||||
m_plus = plus;
|
||||
}
|
||||
|
||||
bool Timespan::IsValid() const
|
||||
{
|
||||
return false; // TODO(mgsergio): implement validator
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, Timespan const & span)
|
||||
{
|
||||
ost << span.GetStart();
|
||||
if (!span.IsOpen())
|
||||
{
|
||||
ost << '-' << span.GetEnd();
|
||||
if (span.HasPeriod())
|
||||
ost << '/' << span.GetPeriod();
|
||||
}
|
||||
if (span.HasPlus())
|
||||
ost << '+';
|
||||
return ost;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, osmoh::TTimespans const & timespans)
|
||||
{
|
||||
auto it = begin(timespans);
|
||||
ost << *it++;
|
||||
while(it != end(timespans))
|
||||
{
|
||||
ost << ',' << *it++;
|
||||
}
|
||||
return ost;
|
||||
}
|
||||
|
||||
// std::ostream & operator << (std::ostream & s, Weekday const & w)
|
||||
// {
|
||||
// static char const * wdays[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"};
|
||||
// static uint8_t const kDaysInWeek = 7;
|
||||
// static uint8_t const kWeeksInMonth = 5;
|
||||
|
||||
// for (size_t i = 0; i < kDaysInWeek; ++i)
|
||||
// {
|
||||
// if (w.weekdays & (1 << i))
|
||||
// {
|
||||
// if (w.weekdays & ((1 << i) - 1))
|
||||
// s << ',';
|
||||
// s << wdays[i];
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (w.nth)
|
||||
// {
|
||||
// s << "[";
|
||||
|
||||
// uint8_t a = w.nth & 0xFF;
|
||||
// for (size_t i = 0; i < kWeeksInMonth; ++i)
|
||||
// {
|
||||
// if (a & (1 << i))
|
||||
// {
|
||||
// if (a & ((1 << i) - 1))
|
||||
// s << ',';
|
||||
// s << (i + 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// a = (w.nth >> 8) & 0xFF;
|
||||
// for (size_t i = 0; i < kWeeksInMonth; ++i)
|
||||
// {
|
||||
// if (a & (1 << i))
|
||||
// {
|
||||
// if (a & ((1 << i) - 1))
|
||||
// s << ',';
|
||||
// s << '-' << (i + 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// s << "]";
|
||||
// }
|
||||
|
||||
// if (w.offset)
|
||||
// s << ' ' << w.offset << " day(s)";
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// std::ostream & operator << (std::ostream & s, State const & w)
|
||||
// {
|
||||
// static char const * st[] = {"unknown", "closed", "open"};
|
||||
// s << ' ' << st[w.state] << " " << w.comment;
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// std::ostream & operator << (std::ostream & s, TimeRule const & w)
|
||||
// {
|
||||
// for (auto const & e : w.weekdays)
|
||||
// s << e;
|
||||
// if (!w.weekdays.empty() && !w.timespan.empty())
|
||||
// s << ' ';
|
||||
// for (auto const & e : w.timespan)
|
||||
// s << e;
|
||||
|
||||
// std::cout << "Weekdays size " << w.weekdays.size() <<
|
||||
// " Timespan size " << w.timespan.size() << std::endl;
|
||||
// return s << w.state;
|
||||
// }
|
||||
} // namespace osmoh
|
||||
|
||||
|
||||
// namespace
|
||||
// {
|
||||
// bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p)
|
||||
// {
|
||||
// using boost::gregorian::days;
|
||||
// using boost::posix_time::ptime;
|
||||
// using boost::posix_time::hours;
|
||||
// using boost::posix_time::minutes;
|
||||
// using boost::posix_time::time_period;
|
||||
|
||||
// time_period tp1 = osmoh::make_time_period(d-days(1), ts);
|
||||
// time_period tp2 = osmoh::make_time_period(d, ts);
|
||||
// /* very useful in debug */
|
||||
// // std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl;
|
||||
// // std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl;
|
||||
// return tp1.contains(p) || tp2.contains(p);
|
||||
// }
|
||||
|
||||
// bool check_weekday(osmoh::Weekday const & wd, boost::gregorian::date const & d)
|
||||
// {
|
||||
// using namespace boost::gregorian;
|
||||
|
||||
// bool hit = false;
|
||||
// typedef nth_day_of_the_week_in_month nth_dow;
|
||||
// if (wd.nth)
|
||||
// {
|
||||
// for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i)
|
||||
// {
|
||||
// if (!(wd.weekdays & (1 << i)))
|
||||
// continue;
|
||||
|
||||
// uint8_t a = wd.nth & 0xFF;
|
||||
// for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j)
|
||||
// {
|
||||
// if (a & (1 << j))
|
||||
// {
|
||||
// nth_dow ndm(nth_dow::week_num(j + 1), nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month());
|
||||
// hit |= (d == ndm.get_date(d.year()));
|
||||
// }
|
||||
// }
|
||||
// a = (wd.nth >> 8) & 0xFF;
|
||||
// for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j)
|
||||
// {
|
||||
// if (a & (1 << j))
|
||||
// {
|
||||
// last_day_of_the_week_in_month lwdm(nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month());
|
||||
// hit |= (d == ((lwdm.get_date(d.year()) - weeks(j)) + days(wd.offset)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i)
|
||||
// {
|
||||
// if (!(wd.weekdays & (1 << i)))
|
||||
// continue;
|
||||
// hit |= (d.day_of_week() == ((i + 1 == 7) ? 0 : (i + 1)));
|
||||
// }
|
||||
// }
|
||||
// /* very useful in debug */
|
||||
// // std::cout << d.day_of_week() << " " << d << " --> " << wd << (hit ? " hit" : " miss") << std::endl;
|
||||
// return hit;
|
||||
// }
|
||||
|
||||
// bool check_rule(osmoh::TimeRule const & r, std::tm const & stm,
|
||||
// std::ostream * hitcontext = nullptr)
|
||||
// {
|
||||
// bool next = false;
|
||||
|
||||
// // check 24/7
|
||||
// if (r.weekdays.empty() && r.timespan.empty() && r.state.state == osmoh::State::eOpen)
|
||||
// return true;
|
||||
|
||||
// boost::gregorian::date date = boost::gregorian::date_from_tm(stm);
|
||||
// boost::posix_time::ptime pt = boost::posix_time::ptime_from_tm(stm);
|
||||
|
||||
// next = r.weekdays.empty();
|
||||
// for (auto const & wd : r.weekdays)
|
||||
// {
|
||||
// if (check_weekday(wd, date))
|
||||
// {
|
||||
// if (hitcontext)
|
||||
// *hitcontext << wd << " ";
|
||||
// next = true;
|
||||
// }
|
||||
// }
|
||||
// if (!next)
|
||||
// return next;
|
||||
|
||||
// next = r.timespan.empty();
|
||||
// for (auto const & ts : r.timespan)
|
||||
// {
|
||||
// if (check_timespan(ts, date, pt))
|
||||
// {
|
||||
// if (hitcontext)
|
||||
// *hitcontext << ts << " ";
|
||||
// next = true;
|
||||
// }
|
||||
// }
|
||||
// return next && !(r.timespan.empty() && r.weekdays.empty());
|
||||
// }
|
||||
// } // anonymouse namespace
|
||||
|
||||
// OSMTimeRange OSMTimeRange::FromString(std::string const & rules)
|
||||
// {
|
||||
// OSMTimeRange timeRange;
|
||||
// std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; // could not work on android
|
||||
// std::wstring src = converter.from_bytes(rules); // rules should be wstring
|
||||
// timeRange.m_valid = osmoh::parsing::parse_timerange(src.begin(), src.end(), timeRange.m_rules);
|
||||
// return timeRange;
|
||||
// }
|
||||
|
||||
// OSMTimeRange & OSMTimeRange::UpdateState(time_t timestamp)
|
||||
// {
|
||||
// std::tm stm = *localtime(×tamp);
|
||||
|
||||
// osmoh::State::EState true_state[3][3] = {
|
||||
// {osmoh::State::eUnknown, osmoh::State::eClosed, osmoh::State::eOpen},
|
||||
// {osmoh::State::eClosed , osmoh::State::eClosed, osmoh::State::eOpen},
|
||||
// {osmoh::State::eOpen , osmoh::State::eClosed, osmoh::State::eOpen}
|
||||
// };
|
||||
|
||||
// osmoh::State::EState false_state[3][3] = {
|
||||
// {osmoh::State::eUnknown, osmoh::State::eOpen , osmoh::State::eClosed},
|
||||
// {osmoh::State::eClosed , osmoh::State::eClosed , osmoh::State::eClosed},
|
||||
// {osmoh::State::eOpen , osmoh::State::eOpen , osmoh::State::eOpen}
|
||||
// };
|
||||
|
||||
// m_state = osmoh::State::eUnknown;
|
||||
// m_comment = std::string();
|
||||
|
||||
// for (auto const & el : m_rules)
|
||||
// {
|
||||
// bool hit = false;
|
||||
// if ((hit = check_rule(el, stm)))
|
||||
// {
|
||||
// m_state = true_state[m_state][el.state.state];
|
||||
// m_comment = el.state.comment;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_state = false_state[m_state][el.state.state];
|
||||
// }
|
||||
// /* very useful in debug */
|
||||
// // char const * st[] = {"unknown", "closed", "open"};
|
||||
// // std::cout << "-[" << hit << "]-------------------[" << el << "]: " << st[m_state] << "--------------------" << std::endl;
|
||||
// }
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
// OSMTimeRange & OSMTimeRange::UpdateState(std::string const & timestr, char const * timefmt)
|
||||
// {
|
||||
// std::tm when = {};
|
||||
// std::stringstream ss(timestr);
|
||||
// ss >> std::get_time(&when, timefmt);
|
||||
// return UpdateState(std::mktime(&when));
|
||||
// }
|
||||
|
|
|
@ -27,123 +27,237 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
namespace osmoh
|
||||
{
|
||||
class Weekday;
|
||||
class TimeSpan;
|
||||
class Timespan;
|
||||
class TimeRule;
|
||||
|
||||
using TWeekdays = std::vector<Weekday>;
|
||||
using TTimeSpans = std::vector<TimeSpan>;
|
||||
using TTimeRules = std::vector<TimeRule>;
|
||||
using TTimespans = std::vector<Timespan>;
|
||||
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
enum EFlags
|
||||
enum EState
|
||||
{
|
||||
eNone = 0,
|
||||
eHours = 1,
|
||||
eMinutes = 2,
|
||||
ePlus = 4,
|
||||
eMinus = 8,
|
||||
eExt = 16,
|
||||
eSunrise = 32,
|
||||
eSunset = 64
|
||||
eIsNotTime = 0,
|
||||
eHaveHours = 1,
|
||||
eHaveMinutes = 2,
|
||||
};
|
||||
|
||||
uint8_t hours;
|
||||
uint8_t minutes;
|
||||
uint8_t flags;
|
||||
|
||||
Time() : hours(0), minutes(0), flags(eNone) {}
|
||||
Time & Hours(uint8_t h) { hours = h; flags |= eHours; return *this; }
|
||||
Time & Minutes(uint8_t m) { minutes = m; flags |= eMinutes; return *this; }
|
||||
Time & Sunset() { flags = eSunset; return *this; }
|
||||
Time & Sunrise() { flags = eSunrise; return *this; }
|
||||
|
||||
std::string ToString() const;
|
||||
friend std::ostream & operator << (std::ostream & s, Time const & t);
|
||||
};
|
||||
|
||||
class TimeSpan
|
||||
{
|
||||
public:
|
||||
Time from;
|
||||
Time to;
|
||||
uint8_t flags;
|
||||
Time period;
|
||||
|
||||
TimeSpan() : flags(Time::eNone) {}
|
||||
|
||||
std::string ToString() const;
|
||||
friend std::ostream & operator << (std::ostream & s, TimeSpan const & span);
|
||||
};
|
||||
|
||||
class Weekday
|
||||
{
|
||||
public:
|
||||
uint8_t weekdays;
|
||||
uint16_t nth;
|
||||
int32_t offset;
|
||||
|
||||
Weekday() : weekdays(0), nth(0), offset(0) {}
|
||||
|
||||
std::string ToString() const;
|
||||
friend std::ostream & operator << (std::ostream & s, Weekday const & w);
|
||||
};
|
||||
|
||||
class State
|
||||
{
|
||||
public:
|
||||
enum EState {
|
||||
eUnknown = 0,
|
||||
eClosed = 1,
|
||||
eOpen = 2
|
||||
enum class EEvent
|
||||
{
|
||||
eNotEvent,
|
||||
eDawn,
|
||||
eSunrise,
|
||||
eSunset,
|
||||
eDusk
|
||||
};
|
||||
|
||||
uint8_t state;
|
||||
std::string comment;
|
||||
using THours = std::chrono::hours;
|
||||
using TMinutes = std::chrono::minutes;
|
||||
|
||||
State() : state(eUnknown) {}
|
||||
};
|
||||
|
||||
class TimeRule
|
||||
{
|
||||
public:
|
||||
TWeekdays weekdays;
|
||||
TTimeSpans timespan; // TODO(mgsergio) rename to timespans
|
||||
State state;
|
||||
uint8_t int_flags = 0;
|
||||
Time() = default;
|
||||
Time(Time const &) = default;
|
||||
Time(TMinutes const minutes);
|
||||
Time(THours const hours, TMinutes const minutes);
|
||||
Time(EEvent const event);
|
||||
|
||||
friend std::ostream & operator <<(std::ostream & s, TimeRule const & r);
|
||||
};
|
||||
} // namespace osmoh
|
||||
THours::rep GetHoursCount() const;
|
||||
TMinutes::rep GetMinutesCount() const;
|
||||
|
||||
class OSMTimeRange
|
||||
{
|
||||
public:
|
||||
OSMTimeRange() = default;
|
||||
THours GetHours() const;
|
||||
TMinutes GetMinutes() const;
|
||||
|
||||
bool IsValid() const { return m_valid; }
|
||||
bool IsOpen() const { return m_state == osmoh::State::eOpen; }
|
||||
bool IsClosed() const { return m_state == osmoh::State::eClosed; }
|
||||
bool IsUnknown() const { return m_state == osmoh::State::eUnknown; }
|
||||
std::string const & Comment() const { return m_comment; }
|
||||
void SetHours(THours const hours);
|
||||
void SetMinutes(TMinutes const minutes);
|
||||
|
||||
OSMTimeRange & UpdateState(time_t timestamp);
|
||||
OSMTimeRange & UpdateState(std::string const & timestr,
|
||||
char const * timefmt="%d-%m-%Y %R");
|
||||
EEvent GetEvent() const {return m_event;}
|
||||
void SetEvent(EEvent const event);
|
||||
|
||||
std::string ToString() const;
|
||||
bool IsEvent() const;
|
||||
bool IsEventOffset() const;
|
||||
bool IsHoursMinutes() const;
|
||||
bool IsMinutes() const;
|
||||
bool IsTime() const;
|
||||
bool HasValue() const;
|
||||
|
||||
static OSMTimeRange FromString(std::string const & rules);
|
||||
Time & operator-(Time const & time);
|
||||
Time & operator-();
|
||||
|
||||
private:
|
||||
bool m_valid{false};
|
||||
osmoh::State::EState m_state{osmoh::State::eUnknown};
|
||||
Time GetEventTime() const;
|
||||
|
||||
osmoh::TTimeRules m_rules;
|
||||
std::string m_comment;
|
||||
private:
|
||||
EEvent m_event{EEvent::eNotEvent};
|
||||
TMinutes m_duration{TMinutes::zero()};
|
||||
std::underlying_type<EState>::type m_state{EState::eIsNotTime};
|
||||
};
|
||||
|
||||
inline constexpr Time::THours operator ""_h(unsigned long long h)
|
||||
{
|
||||
return Time::THours(h);
|
||||
}
|
||||
|
||||
inline constexpr Time::TMinutes operator ""_min(unsigned long long m)
|
||||
{
|
||||
return Time::TMinutes(m);
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, Time::EEvent const event);
|
||||
std::ostream & operator<<(std::ostream & ost, Time const & time);
|
||||
|
||||
class Timespan
|
||||
{
|
||||
public:
|
||||
Timespan() = default;
|
||||
Timespan(Timespan const &) = default;
|
||||
Timespan(Time const & start, bool plus = false);
|
||||
Timespan(Time const & start, Time const & end, bool plus = false);
|
||||
Timespan(Time const & start, Time const & end, Time const & period);
|
||||
|
||||
bool IsOpen() const;
|
||||
bool HasPlus() const;
|
||||
bool HasPeriod() const;
|
||||
|
||||
Time const & GetStart() const;
|
||||
Time const & GetEnd() const;
|
||||
Time const & GetPeriod() const;
|
||||
|
||||
void SetStart(Time const & start);
|
||||
void SetEnd(Time const & end);
|
||||
void SetPeriod(Time const & period);
|
||||
void SetPlus(bool const plus);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
private:
|
||||
Time m_start;
|
||||
Time m_end;
|
||||
Time m_period;
|
||||
bool m_plus{false};
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream & ost, Timespan const & span);
|
||||
std::ostream & operator<<(std::ostream & ost, osmoh::TTimespans const & timespans);
|
||||
} // namespace osmoh
|
||||
|
||||
// class Weekday
|
||||
// {
|
||||
// public:
|
||||
// uint8_t weekdays;
|
||||
// uint16_t nth;
|
||||
// int32_t offset;
|
||||
|
||||
// Weekday() : weekdays(0), nth(0), offset(0) {}
|
||||
|
||||
// std::string ToString() const;
|
||||
// friend std::ostream & operator << (std::ostream & s, Weekday const & w);
|
||||
// };
|
||||
|
||||
// class State
|
||||
// {
|
||||
// public:
|
||||
// enum EState {
|
||||
// eUnknown = 0,
|
||||
// eClosed = 1,
|
||||
// eOpen = 2
|
||||
// };
|
||||
|
||||
// uint8_t state;
|
||||
// std::string comment;
|
||||
|
||||
// State() : state(eUnknown) {}
|
||||
// };
|
||||
|
||||
// class TimeRule
|
||||
// {
|
||||
// public:
|
||||
// TWeekdays weekdays;
|
||||
// TTimeSpans timespan; // TODO(mgsergio) rename to timespans
|
||||
// State state;
|
||||
// uint8_t int_flags = 0;
|
||||
|
||||
// friend std::ostream & operator <<(std::ostream & s, TimeRule const & r);
|
||||
// };
|
||||
// } // namespace osmoh
|
||||
|
||||
// class OSMTimeRange
|
||||
// {
|
||||
// public:
|
||||
// OSMTimeRange() = default;
|
||||
|
||||
// bool IsValid() const { return m_valid; }
|
||||
// bool IsOpen() const { return m_state == osmoh::State::eOpen; }
|
||||
// bool IsClosed() const { return m_state == osmoh::State::eClosed; }
|
||||
// bool IsUnknown() const { return m_state == osmoh::State::eUnknown; }
|
||||
// std::string const & Comment() const { return m_comment; }
|
||||
|
||||
// OSMTimeRange & UpdateState(time_t timestamp);
|
||||
// OSMTimeRange & UpdateState(std::string const & timestr,
|
||||
// char const * timefmt="%d-%m-%Y %R");
|
||||
|
||||
// std::string ToString() const;
|
||||
|
||||
// static OSMTimeRange FromString(std::string const & rules);
|
||||
|
||||
// private:
|
||||
// bool m_valid{false};
|
||||
// osmoh::State::EState m_state{osmoh::State::eUnknown};
|
||||
|
||||
// osmoh::TTimeRules m_rules;
|
||||
// std::string m_comment;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
/// Trash
|
||||
|
||||
// class TimeEx
|
||||
// {
|
||||
// public:
|
||||
// enum EFlags
|
||||
// {
|
||||
// eNone = 0,
|
||||
// eHours = 1,
|
||||
// eMinutes = 2,
|
||||
// ePlus = 4,
|
||||
// eMinus = 8,
|
||||
// eExt = 16,
|
||||
// eSunrise = 32,
|
||||
// eSunset = 64
|
||||
// };
|
||||
|
||||
// uint8_t hours;
|
||||
// uint8_t minutes;
|
||||
// uint8_t flags;
|
||||
|
||||
// Time() : hours(0), minutes(0), flags(eNone) {}
|
||||
// Time & Hours(uint8_t h) { hours = h; flags |= eHours; return *this; }
|
||||
// Time & Minutes(uint8_t m) { minutes = m; flags |= eMinutes; return *this; }
|
||||
// Time & Sunset() { flags = eSunset; return *this; }
|
||||
// Time & Sunrise() { flags = eSunrise; return *this; }
|
||||
|
||||
// std::string ToString() const;
|
||||
// friend std::ostream & operator << (std::ostream & s, Time const & t);
|
||||
// };
|
||||
|
||||
// class TimeSpanEx
|
||||
// {
|
||||
// public:
|
||||
// Time from;
|
||||
// Time to;
|
||||
// uint8_t flags;
|
||||
// Time period;
|
||||
|
||||
// TimeSpan() : flags(Time::eNone) {}
|
||||
|
||||
// std::string ToString() const;
|
||||
// friend std::ostream & operator << (std::ostream & s, TimeSpan const & span);
|
||||
// };
|
||||
|
|
Loading…
Add table
Reference in a new issue