Commit 1721da0d33410e4d8970d34d3c8ce5221d78e93d

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent 2f287834

Separate AbsoluteTime and AbsoluteVariedTime.

include/hueplusplus/TimePattern.h
... ... @@ -55,7 +55,6 @@ std::chrono::system_clock::time_point parseTimestamp(const std::string& timestam
55 55 //! \throws HueException when time cannot be represented as time_point
56 56 std::chrono::system_clock::time_point parseUTCTimestamp(const std::string& timestamp);
57 57  
58   -
59 58 //! \brief Converts duration to a time string
60 59 //! \param duration Duration or time of day to format. Must be less than 24 hours
61 60 //! \returns Duration string in the format <code>hh:mm:ss</code>
... ... @@ -68,10 +67,7 @@ std::string durationTo_hh_mm_ss(std::chrono::system_clock::duration duration);
68 67 //! \throws std::invalid_argument when integer conversion fails
69 68 std::chrono::system_clock::duration parseDuration(const std::string& hourMinSec);
70 69  
71   -//! \brief One-time, absolute time point with possible random variation
72   -//!
73   -//! Can be either used to represent a specific date and time,
74   -//! or a date and time with a random variation.
  70 +//! \brief One-time, absolute time point
75 71 class AbsoluteTime
76 72 {
77 73 using clock = std::chrono::system_clock;
... ... @@ -79,15 +75,46 @@ class AbsoluteTime
79 75 public:
80 76 //! \brief Create absolute time point
81 77 //! \param baseTime Absolute time point
82   - //! \param variation Random variation, optional. When not zero, the time is randomly chosen between
83   - //! <code>baseTime - variation</code> and <code>baseTime + variation</code>
84   - explicit AbsoluteTime(clock::time_point baseTime, clock::duration variation = std::chrono::seconds(0));
  78 + explicit AbsoluteTime(clock::time_point baseTime);
85 79  
86 80 //! \brief Get base time point
87 81 //!
88 82 //! Can be used for calculation with other system_clock time_points
89 83 clock::time_point getBaseTime() const;
90 84  
  85 + //! \brief Get formatted string as expected by Hue API
  86 + //! \returns Timestamp in the format
  87 + //! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code>
  88 + std::string toString() const;
  89 +
  90 + //! \brief Parse AbsoluteTime from formatted string in local timezone
  91 + //! \param s Timestamp in the same format as returned by \ref toString()
  92 + //! \returns AbsoluteTime with base time and variation from \c s
  93 + static AbsoluteTime parse(const std::string& s);
  94 +
  95 + //! \brief Parse AbsoluteTime from formatted UTC string
  96 + //! \param s Timestamp in the same format as returned by \ref toString()
  97 + //! \returns AbsoluteTime with base time and variation from \c s
  98 + static AbsoluteTime parseUTC(const std::string& s);
  99 +
  100 +private:
  101 + clock::time_point base;
  102 +};
  103 +//! One-time, absolute time point with possible random variation
  104 +//!
  105 +//! Can be either used to represent a specific date and time,
  106 +//! or a date and time with a random variation.
  107 +class AbsoluteVariedTime : public AbsoluteTime
  108 +{
  109 + using clock = std::chrono::system_clock;
  110 +
  111 +public:
  112 + //! \brief Create absolute time point
  113 + //! \param baseTime Absolute time point
  114 + //! \param variation Random variation, optional. When not zero, the time is randomly chosen between
  115 + //! <code>baseTime - variation</code> and <code>baseTime + variation</code>
  116 + explicit AbsoluteVariedTime(clock::time_point baseTime, clock::duration variation = std::chrono::seconds(0));
  117 +
91 118 //! \brief Get random variation or zero
92 119 //!
93 120 //! The time can vary up to this amount in both directions.
... ... @@ -103,15 +130,10 @@ public:
103 130  
104 131 //! \brief Parse AbsoluteTime from formatted string in local timezone
105 132 //! \param s Timestamp in the same format as returned by \ref toString()
106   - //! \returns AbsoluteTime with base time and variation from \c s
107   - static AbsoluteTime parse(const std::string& s);
  133 + //! \returns AbsoluteVariedTime with base time and variation from \c s
  134 + static AbsoluteVariedTime parse(const std::string& s);
108 135  
109   - //! \brief Parse AbsoluteTime from formatted UTC string
110   - //! \param s Timestamp in the same format as returned by \ref toString()
111   - //! \returns AbsoluteTime with base time and variation from \c s
112   - static AbsoluteTime parseUTC(const std::string& s);
113 136 private:
114   - clock::time_point base;
115 137 clock::duration variation;
116 138 };
117 139  
... ... @@ -122,10 +144,10 @@ class Weekdays
122 144 {
123 145 public:
124 146 //! \brief Create with no days
125   - Weekdays() : bitmask(0) {}
  147 + Weekdays() : bitmask(0) { }
126 148 //! \brief Create with the day \c num
127 149 //! \param num Day of the week, from monday (0) to sunday (6)
128   - explicit Weekdays(int num) : bitmask(1 << num) {}
  150 + explicit Weekdays(int num) : bitmask(1 << num) { }
129 151  
130 152 //! \brief Check if no days are set
131 153 bool isNone() const;
... ... @@ -332,7 +354,7 @@ public:
332 354 enum class Type
333 355 {
334 356 undefined, //!< \brief No active type
335   - absolute, //!< \brief Active type is AbsoluteTime
  357 + absolute, //!< \brief Active type is AbsoluteVariedTime
336 358 recurring, //!< \brief Active type is RecurringTime
337 359 interval, //!< \brief Active type is TimeInterval
338 360 timer //!< \brief Active type is Timer
... ... @@ -342,8 +364,8 @@ public:
342 364 TimePattern();
343 365 //! \brief Destructor for union.
344 366 ~TimePattern();
345   - //! \brief Create TimePattern from AbsoluteTime
346   - explicit TimePattern(const AbsoluteTime& absolute);
  367 + //! \brief Create TimePattern from AbsoluteVariedTime
  368 + explicit TimePattern(const AbsoluteVariedTime& absolute);
347 369 //! \brief Create TimePattern from RecurringTime
348 370 explicit TimePattern(const RecurringTime& recurring);
349 371 //! \brief Create TimePattern from TimeInterval
... ... @@ -364,7 +386,7 @@ public:
364 386  
365 387 //! \brief Get contained absolute time
366 388 //! \pre getType() == Type::absolute
367   - AbsoluteTime asAbsolute() const;
  389 + AbsoluteVariedTime asAbsolute() const;
368 390  
369 391 //! \brief Get contained recurring time
370 392 //! \pre getType() == Type::recurring
... ... @@ -401,7 +423,7 @@ private:
401 423 union
402 424 {
403 425 nullptr_t undefined;
404   - AbsoluteTime absolute;
  426 + AbsoluteVariedTime absolute;
405 427 RecurringTime recurring;
406 428 TimeInterval interval;
407 429 Timer timer;
... ...
src/TimePattern.cpp
... ... @@ -143,52 +143,62 @@ system_clock::duration parseDuration(const std::string&amp; s)
143 143 return hour + min + sec;
144 144 }
145 145  
146   -AbsoluteTime::AbsoluteTime(clock::time_point baseTime, clock::duration variation) : base(baseTime), variation(variation)
147   -{}
  146 +AbsoluteTime::AbsoluteTime(clock::time_point baseTime) : base(baseTime) { }
148 147  
149 148 system_clock::time_point AbsoluteTime::getBaseTime() const
150 149 {
151 150 return base;
152 151 }
153   -system_clock::duration AbsoluteTime::getRandomVariation() const
154   -{
155   - return variation;
156   -}
157 152 std::string AbsoluteTime::toString() const
158 153 {
159   - std::string result = timepointToTimestamp(base);
160   - if (variation.count() != 0)
161   - {
162   - result.push_back('A');
163   - result.append(durationTo_hh_mm_ss(variation));
164   - }
165   - return result;
  154 + return timepointToTimestamp(base);
166 155 }
167 156  
168 157 AbsoluteTime AbsoluteTime::parse(const std::string& s)
169 158 {
170 159 // Absolute time
171 160 clock::time_point time = parseTimestamp(s);
172   - clock::duration variation {0};
173   - if (s.size() > 19 && s[19] == 'A')
174   - {
175   - // Random variation
176   - variation = parseDuration(s.substr(20));
177   - }
178   - return AbsoluteTime(time, variation);
  161 + return AbsoluteTime(time);
179 162 }
180 163  
181 164 AbsoluteTime AbsoluteTime::parseUTC(const std::string& s)
182 165 {
183 166 // Absolute time
184 167 clock::time_point time = parseUTCTimestamp(s);
  168 + return AbsoluteTime(time);
  169 +}
  170 +
  171 +AbsoluteVariedTime::AbsoluteVariedTime(clock::time_point baseTime, clock::duration variation)
  172 + : AbsoluteTime(baseTime), variation(variation)
  173 +{ }
  174 +
  175 +system_clock::duration AbsoluteVariedTime::getRandomVariation() const
  176 +{
  177 + return variation;
  178 +}
  179 +
  180 +AbsoluteVariedTime AbsoluteVariedTime::parse(const std::string& s)
  181 +{
  182 + // Absolute time
  183 + clock::time_point time = parseTimestamp(s);
185 184 clock::duration variation {0};
186 185 if (s.size() > 19 && s[19] == 'A')
187 186 {
188 187 // Random variation
189 188 variation = parseDuration(s.substr(20));
190 189 }
191   - return AbsoluteTime(time, variation);
  190 + return AbsoluteVariedTime(time, variation);
  191 +}
  192 +
  193 +std::string AbsoluteVariedTime::toString() const
  194 +{
  195 + std::string result = timepointToTimestamp(getBaseTime());
  196 + if (variation.count() != 0)
  197 + {
  198 + result.push_back('A');
  199 + result.append(durationTo_hh_mm_ss(variation));
  200 + }
  201 + return result;
192 202 }
193 203  
194 204 bool Weekdays::isNone() const
... ... @@ -309,7 +319,7 @@ Weekdays Weekdays::parse(const std::string&amp; s)
309 319  
310 320 RecurringTime::RecurringTime(clock::duration daytime, Weekdays days, clock::duration variation)
311 321 : time(daytime), variation(variation), days(days)
312   -{}
  322 +{ }
313 323  
314 324 system_clock::duration RecurringTime::getDaytime() const
315 325 {
... ... @@ -342,7 +352,7 @@ std::string RecurringTime::toString() const
342 352  
343 353 TimeInterval::TimeInterval(clock::duration start, clock::duration end, Weekdays days)
344 354 : start(start), end(end), days(days)
345   -{}
  355 +{ }
346 356  
347 357 system_clock::duration TimeInterval::getStartTime() const
348 358 {
... ... @@ -378,11 +388,11 @@ std::string TimeInterval::toString() const
378 388  
379 389 Timer::Timer(clock::duration duration, clock::duration variation)
380 390 : expires(duration), variation(variation), numExecutions(1)
381   -{}
  391 +{ }
382 392  
383 393 Timer::Timer(clock::duration duration, int numExecutions, clock::duration variation)
384 394 : expires(duration), variation(variation), numExecutions(numExecutions)
385   -{}
  395 +{ }
386 396  
387 397 bool Timer::isRecurring() const
388 398 {
... ... @@ -432,20 +442,20 @@ std::string Timer::toString() const
432 442 return result;
433 443 }
434 444  
435   -TimePattern::TimePattern() : type(Type::undefined), undefined(nullptr) {}
  445 +TimePattern::TimePattern() : type(Type::undefined), undefined(nullptr) { }
436 446  
437 447 TimePattern::~TimePattern()
438 448 {
439 449 destroy();
440 450 }
441 451  
442   -TimePattern::TimePattern(const AbsoluteTime& absolute) : type(Type::absolute), absolute(absolute) {}
  452 +TimePattern::TimePattern(const AbsoluteVariedTime& absolute) : type(Type::absolute), absolute(absolute) { }
443 453  
444   -TimePattern::TimePattern(const RecurringTime& recurring) : type(Type::recurring), recurring(recurring) {}
  454 +TimePattern::TimePattern(const RecurringTime& recurring) : type(Type::recurring), recurring(recurring) { }
445 455  
446   -TimePattern::TimePattern(const TimeInterval& interval) : type(Type::interval), interval(interval) {}
  456 +TimePattern::TimePattern(const TimeInterval& interval) : type(Type::interval), interval(interval) { }
447 457  
448   -TimePattern::TimePattern(const Timer& timer) : type(Type::timer), timer(timer) {}
  458 +TimePattern::TimePattern(const Timer& timer) : type(Type::timer), timer(timer) { }
449 459  
450 460 TimePattern::TimePattern(const TimePattern& other) : type(Type::undefined), undefined(nullptr)
451 461 {
... ... @@ -496,7 +506,7 @@ TimePattern::Type TimePattern::getType() const
496 506 return type;
497 507 }
498 508  
499   -AbsoluteTime TimePattern::asAbsolute() const
  509 +AbsoluteVariedTime TimePattern::asAbsolute() const
500 510 {
501 511 return absolute;
502 512 }
... ... @@ -543,7 +553,7 @@ TimePattern TimePattern::parse(const std::string&amp; s)
543 553 }
544 554 else if (std::isdigit(s.front()))
545 555 {
546   - return TimePattern(AbsoluteTime::parse(s));
  556 + return TimePattern(AbsoluteVariedTime::parse(s));
547 557 }
548 558 else if (s.front() == 'R' || s.front() == 'P')
549 559 {
... ... @@ -606,7 +616,7 @@ void TimePattern::destroy()
606 616 switch (type)
607 617 {
608 618 case Type::absolute:
609   - absolute.~AbsoluteTime();
  619 + absolute.~AbsoluteVariedTime();
610 620 break;
611 621 case Type::recurring:
612 622 recurring.~RecurringTime();
... ...
test/test_Scene.cpp
... ... @@ -272,7 +272,7 @@ TEST_F(SceneTest, getLastUpdated)
272 272 expectGetState(id);
273 273 const Scene scene(id, commands, std::chrono::seconds(0));
274 274 const time::AbsoluteTime lastUpdated = scene.getLastUpdated();
275   - EXPECT_EQ(std::chrono::seconds(0), lastUpdated.getRandomVariation());
  275 + EXPECT_EQ(time::parseUTCTimestamp("2020-04-23T12:00:04"), lastUpdated.getBaseTime());
276 276 }
277 277  
278 278 TEST_F(SceneTest, getVersion)
... ...
test/test_Schedule.cpp
... ... @@ -239,7 +239,7 @@ TEST_F(ScheduleTest, setTime)
239 239 const int id = 1;
240 240 expectGetState(id);
241 241 Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
242   - time::TimePattern time {time::AbsoluteTime(std::chrono::system_clock::now())};
  242 + time::TimePattern time {time::AbsoluteVariedTime(std::chrono::system_clock::now())};
243 243 nlohmann::json request = {{"localtime", time.toString()}};
244 244 nlohmann::json response = {{"success", {"/schedules/1/localtime", time.toString()}}};
245 245 EXPECT_CALL(
... ... @@ -320,7 +320,7 @@ TEST(CreateSchedule, setCommand)
320 320  
321 321 TEST(CreateSchedule, setTime)
322 322 {
323   - const time::AbsoluteTime time(std::chrono::system_clock::now());
  323 + const time::AbsoluteVariedTime time(std::chrono::system_clock::now());
324 324 const nlohmann::json request = {{"localtime", time.toString()}};
325 325 EXPECT_EQ(request, CreateSchedule().setTime(time::TimePattern(time)).getRequest());
326 326 }
... ...
test/test_TimePattern.cpp
... ... @@ -78,33 +78,33 @@ TEST(Time, durationTo_hh_mm_ss)
78 78 EXPECT_EQ(duration, parseDuration(durationTo_hh_mm_ss(duration)));
79 79 }
80 80  
81   -TEST(AbsoluteTime, Constructor)
  81 +TEST(AbsoluteVariedTime, Constructor)
82 82 {
83 83 system_clock::time_point now = system_clock::now();
84 84 {
85   - AbsoluteTime time(now);
  85 + AbsoluteVariedTime time(now);
86 86 EXPECT_EQ(now, time.getBaseTime());
87 87 EXPECT_EQ(0s, time.getRandomVariation());
88 88 }
89 89 system_clock::duration variation = 4h + 2min;
90 90 {
91   - AbsoluteTime time(now, variation);
  91 + AbsoluteVariedTime time(now, variation);
92 92 EXPECT_EQ(now, time.getBaseTime());
93 93 EXPECT_EQ(variation, time.getRandomVariation());
94 94 }
95 95 }
96 96  
97   -TEST(AbsoluteTime, toString)
  97 +TEST(AbsoluteVariedTime, toString)
98 98 {
99 99 const system_clock::time_point timePoint = parseTimestamp("2020-03-03T20:53:03");
100 100  
101   - EXPECT_EQ("2020-03-03T20:53:03", AbsoluteTime(timePoint).toString());
  101 + EXPECT_EQ("2020-03-03T20:53:03", AbsoluteVariedTime(timePoint).toString());
102 102  
103 103 const system_clock::duration noVariation = 0s;
104   - EXPECT_EQ("2020-03-03T20:53:03", AbsoluteTime(timePoint, noVariation).toString());
  104 + EXPECT_EQ("2020-03-03T20:53:03", AbsoluteVariedTime(timePoint, noVariation).toString());
105 105  
106 106 const system_clock::duration variation = 1h + 2min + 1s;
107   - EXPECT_EQ("2020-03-03T20:53:03A01:02:01", AbsoluteTime(timePoint, variation).toString());
  107 + EXPECT_EQ("2020-03-03T20:53:03A01:02:01", AbsoluteVariedTime(timePoint, variation).toString());
108 108 }
109 109  
110 110 TEST(AbsoluteTime, parseUTC)
... ... @@ -361,7 +361,7 @@ TEST(TimePattern, CopyConstructor)
361 361 EXPECT_EQ(TimePattern::Type::undefined, copy.getType());
362 362 }
363 363 {
364   - const AbsoluteTime abs(system_clock::now());
  364 + const AbsoluteVariedTime abs(system_clock::now());
365 365 const TimePattern pattern(abs);
366 366 const TimePattern copy(pattern);
367 367 ASSERT_EQ(TimePattern::Type::absolute, copy.getType());
... ... @@ -399,7 +399,7 @@ TEST(TimePattern, CopyConstructor)
399 399 TEST(TimePattern, Absolute)
400 400 {
401 401 {
402   - const AbsoluteTime abs(system_clock::now(), 20s);
  402 + const AbsoluteVariedTime abs(system_clock::now(), 20s);
403 403 const TimePattern pattern(abs);
404 404 ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
405 405 EXPECT_EQ(abs.getBaseTime(), pattern.asAbsolute().getBaseTime());
... ... @@ -409,7 +409,7 @@ TEST(TimePattern, Absolute)
409 409 const system_clock::time_point timePoint = parseTimestamp("2020-03-03T20:53:03");
410 410 {
411 411 const TimePattern pattern = TimePattern::parse("2020-03-03T20:53:03");
412   - const AbsoluteTime expected(timePoint);
  412 + const AbsoluteVariedTime expected(timePoint);
413 413 ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
414 414 EXPECT_EQ(expected.getBaseTime(), pattern.asAbsolute().getBaseTime());
415 415 EXPECT_EQ(expected.getRandomVariation(), pattern.asAbsolute().getRandomVariation());
... ... @@ -417,7 +417,7 @@ TEST(TimePattern, Absolute)
417 417 {
418 418 const system_clock::duration variation = 1h + 2min + 1s;
419 419 const TimePattern pattern = TimePattern::parse("2020-03-03T20:53:03A01:02:01");
420   - const AbsoluteTime expected(timePoint, variation);
  420 + const AbsoluteVariedTime expected(timePoint, variation);
421 421 ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
422 422 EXPECT_EQ(expected.getBaseTime(), pattern.asAbsolute().getBaseTime());
423 423 EXPECT_EQ(expected.getRandomVariation(), pattern.asAbsolute().getRandomVariation());
... ...