diff --git a/include/hueplusplus/TimePattern.h b/include/hueplusplus/TimePattern.h
index 9a3f051..a69d5a9 100644
--- a/include/hueplusplus/TimePattern.h
+++ b/include/hueplusplus/TimePattern.h
@@ -55,7 +55,6 @@ std::chrono::system_clock::time_point parseTimestamp(const std::string& timestam
//! \throws HueException when time cannot be represented as time_point
std::chrono::system_clock::time_point parseUTCTimestamp(const std::string& timestamp);
-
//! \brief Converts duration to a time string
//! \param duration Duration or time of day to format. Must be less than 24 hours
//! \returns Duration string in the format hh:mm:ss
@@ -68,10 +67,7 @@ std::string durationTo_hh_mm_ss(std::chrono::system_clock::duration duration);
//! \throws std::invalid_argument when integer conversion fails
std::chrono::system_clock::duration parseDuration(const std::string& hourMinSec);
-//! \brief One-time, absolute time point with possible random variation
-//!
-//! Can be either used to represent a specific date and time,
-//! or a date and time with a random variation.
+//! \brief One-time, absolute time point
class AbsoluteTime
{
using clock = std::chrono::system_clock;
@@ -79,15 +75,46 @@ class AbsoluteTime
public:
//! \brief Create absolute time point
//! \param baseTime Absolute time point
- //! \param variation Random variation, optional. When not zero, the time is randomly chosen between
- //! baseTime - variation and baseTime + variation
- explicit AbsoluteTime(clock::time_point baseTime, clock::duration variation = std::chrono::seconds(0));
+ explicit AbsoluteTime(clock::time_point baseTime);
//! \brief Get base time point
//!
//! Can be used for calculation with other system_clock time_points
clock::time_point getBaseTime() const;
+ //! \brief Get formatted string as expected by Hue API
+ //! \returns Timestamp in the format
+ //! YYYY-MM-DDThh:mm:ss
+ std::string toString() const;
+
+ //! \brief Parse AbsoluteTime from formatted string in local timezone
+ //! \param s Timestamp in the same format as returned by \ref toString()
+ //! \returns AbsoluteTime with base time and variation from \c s
+ static AbsoluteTime parse(const std::string& s);
+
+ //! \brief Parse AbsoluteTime from formatted UTC string
+ //! \param s Timestamp in the same format as returned by \ref toString()
+ //! \returns AbsoluteTime with base time and variation from \c s
+ static AbsoluteTime parseUTC(const std::string& s);
+
+private:
+ clock::time_point base;
+};
+//! One-time, absolute time point with possible random variation
+//!
+//! Can be either used to represent a specific date and time,
+//! or a date and time with a random variation.
+class AbsoluteVariedTime : public AbsoluteTime
+{
+ using clock = std::chrono::system_clock;
+
+public:
+ //! \brief Create absolute time point
+ //! \param baseTime Absolute time point
+ //! \param variation Random variation, optional. When not zero, the time is randomly chosen between
+ //! baseTime - variation and baseTime + variation
+ explicit AbsoluteVariedTime(clock::time_point baseTime, clock::duration variation = std::chrono::seconds(0));
+
//! \brief Get random variation or zero
//!
//! The time can vary up to this amount in both directions.
@@ -103,15 +130,10 @@ public:
//! \brief Parse AbsoluteTime from formatted string in local timezone
//! \param s Timestamp in the same format as returned by \ref toString()
- //! \returns AbsoluteTime with base time and variation from \c s
- static AbsoluteTime parse(const std::string& s);
+ //! \returns AbsoluteVariedTime with base time and variation from \c s
+ static AbsoluteVariedTime parse(const std::string& s);
- //! \brief Parse AbsoluteTime from formatted UTC string
- //! \param s Timestamp in the same format as returned by \ref toString()
- //! \returns AbsoluteTime with base time and variation from \c s
- static AbsoluteTime parseUTC(const std::string& s);
private:
- clock::time_point base;
clock::duration variation;
};
@@ -122,10 +144,10 @@ class Weekdays
{
public:
//! \brief Create with no days
- Weekdays() : bitmask(0) {}
+ Weekdays() : bitmask(0) { }
//! \brief Create with the day \c num
//! \param num Day of the week, from monday (0) to sunday (6)
- explicit Weekdays(int num) : bitmask(1 << num) {}
+ explicit Weekdays(int num) : bitmask(1 << num) { }
//! \brief Check if no days are set
bool isNone() const;
@@ -332,7 +354,7 @@ public:
enum class Type
{
undefined, //!< \brief No active type
- absolute, //!< \brief Active type is AbsoluteTime
+ absolute, //!< \brief Active type is AbsoluteVariedTime
recurring, //!< \brief Active type is RecurringTime
interval, //!< \brief Active type is TimeInterval
timer //!< \brief Active type is Timer
@@ -342,8 +364,8 @@ public:
TimePattern();
//! \brief Destructor for union.
~TimePattern();
- //! \brief Create TimePattern from AbsoluteTime
- explicit TimePattern(const AbsoluteTime& absolute);
+ //! \brief Create TimePattern from AbsoluteVariedTime
+ explicit TimePattern(const AbsoluteVariedTime& absolute);
//! \brief Create TimePattern from RecurringTime
explicit TimePattern(const RecurringTime& recurring);
//! \brief Create TimePattern from TimeInterval
@@ -364,7 +386,7 @@ public:
//! \brief Get contained absolute time
//! \pre getType() == Type::absolute
- AbsoluteTime asAbsolute() const;
+ AbsoluteVariedTime asAbsolute() const;
//! \brief Get contained recurring time
//! \pre getType() == Type::recurring
@@ -401,7 +423,7 @@ private:
union
{
nullptr_t undefined;
- AbsoluteTime absolute;
+ AbsoluteVariedTime absolute;
RecurringTime recurring;
TimeInterval interval;
Timer timer;
diff --git a/src/TimePattern.cpp b/src/TimePattern.cpp
index 3622afa..4c54e3d 100644
--- a/src/TimePattern.cpp
+++ b/src/TimePattern.cpp
@@ -143,52 +143,62 @@ system_clock::duration parseDuration(const std::string& s)
return hour + min + sec;
}
-AbsoluteTime::AbsoluteTime(clock::time_point baseTime, clock::duration variation) : base(baseTime), variation(variation)
-{}
+AbsoluteTime::AbsoluteTime(clock::time_point baseTime) : base(baseTime) { }
system_clock::time_point AbsoluteTime::getBaseTime() const
{
return base;
}
-system_clock::duration AbsoluteTime::getRandomVariation() const
-{
- return variation;
-}
std::string AbsoluteTime::toString() const
{
- std::string result = timepointToTimestamp(base);
- if (variation.count() != 0)
- {
- result.push_back('A');
- result.append(durationTo_hh_mm_ss(variation));
- }
- return result;
+ return timepointToTimestamp(base);
}
AbsoluteTime AbsoluteTime::parse(const std::string& s)
{
// Absolute time
clock::time_point time = parseTimestamp(s);
- clock::duration variation {0};
- if (s.size() > 19 && s[19] == 'A')
- {
- // Random variation
- variation = parseDuration(s.substr(20));
- }
- return AbsoluteTime(time, variation);
+ return AbsoluteTime(time);
}
AbsoluteTime AbsoluteTime::parseUTC(const std::string& s)
{
// Absolute time
clock::time_point time = parseUTCTimestamp(s);
+ return AbsoluteTime(time);
+}
+
+AbsoluteVariedTime::AbsoluteVariedTime(clock::time_point baseTime, clock::duration variation)
+ : AbsoluteTime(baseTime), variation(variation)
+{ }
+
+system_clock::duration AbsoluteVariedTime::getRandomVariation() const
+{
+ return variation;
+}
+
+AbsoluteVariedTime AbsoluteVariedTime::parse(const std::string& s)
+{
+ // Absolute time
+ clock::time_point time = parseTimestamp(s);
clock::duration variation {0};
if (s.size() > 19 && s[19] == 'A')
{
// Random variation
variation = parseDuration(s.substr(20));
}
- return AbsoluteTime(time, variation);
+ return AbsoluteVariedTime(time, variation);
+}
+
+std::string AbsoluteVariedTime::toString() const
+{
+ std::string result = timepointToTimestamp(getBaseTime());
+ if (variation.count() != 0)
+ {
+ result.push_back('A');
+ result.append(durationTo_hh_mm_ss(variation));
+ }
+ return result;
}
bool Weekdays::isNone() const
@@ -309,7 +319,7 @@ Weekdays Weekdays::parse(const std::string& s)
RecurringTime::RecurringTime(clock::duration daytime, Weekdays days, clock::duration variation)
: time(daytime), variation(variation), days(days)
-{}
+{ }
system_clock::duration RecurringTime::getDaytime() const
{
@@ -342,7 +352,7 @@ std::string RecurringTime::toString() const
TimeInterval::TimeInterval(clock::duration start, clock::duration end, Weekdays days)
: start(start), end(end), days(days)
-{}
+{ }
system_clock::duration TimeInterval::getStartTime() const
{
@@ -378,11 +388,11 @@ std::string TimeInterval::toString() const
Timer::Timer(clock::duration duration, clock::duration variation)
: expires(duration), variation(variation), numExecutions(1)
-{}
+{ }
Timer::Timer(clock::duration duration, int numExecutions, clock::duration variation)
: expires(duration), variation(variation), numExecutions(numExecutions)
-{}
+{ }
bool Timer::isRecurring() const
{
@@ -432,20 +442,20 @@ std::string Timer::toString() const
return result;
}
-TimePattern::TimePattern() : type(Type::undefined), undefined(nullptr) {}
+TimePattern::TimePattern() : type(Type::undefined), undefined(nullptr) { }
TimePattern::~TimePattern()
{
destroy();
}
-TimePattern::TimePattern(const AbsoluteTime& absolute) : type(Type::absolute), absolute(absolute) {}
+TimePattern::TimePattern(const AbsoluteVariedTime& absolute) : type(Type::absolute), absolute(absolute) { }
-TimePattern::TimePattern(const RecurringTime& recurring) : type(Type::recurring), recurring(recurring) {}
+TimePattern::TimePattern(const RecurringTime& recurring) : type(Type::recurring), recurring(recurring) { }
-TimePattern::TimePattern(const TimeInterval& interval) : type(Type::interval), interval(interval) {}
+TimePattern::TimePattern(const TimeInterval& interval) : type(Type::interval), interval(interval) { }
-TimePattern::TimePattern(const Timer& timer) : type(Type::timer), timer(timer) {}
+TimePattern::TimePattern(const Timer& timer) : type(Type::timer), timer(timer) { }
TimePattern::TimePattern(const TimePattern& other) : type(Type::undefined), undefined(nullptr)
{
@@ -496,7 +506,7 @@ TimePattern::Type TimePattern::getType() const
return type;
}
-AbsoluteTime TimePattern::asAbsolute() const
+AbsoluteVariedTime TimePattern::asAbsolute() const
{
return absolute;
}
@@ -543,7 +553,7 @@ TimePattern TimePattern::parse(const std::string& s)
}
else if (std::isdigit(s.front()))
{
- return TimePattern(AbsoluteTime::parse(s));
+ return TimePattern(AbsoluteVariedTime::parse(s));
}
else if (s.front() == 'R' || s.front() == 'P')
{
@@ -606,7 +616,7 @@ void TimePattern::destroy()
switch (type)
{
case Type::absolute:
- absolute.~AbsoluteTime();
+ absolute.~AbsoluteVariedTime();
break;
case Type::recurring:
recurring.~RecurringTime();
diff --git a/test/test_Scene.cpp b/test/test_Scene.cpp
index 3be19c9..96d06de 100644
--- a/test/test_Scene.cpp
+++ b/test/test_Scene.cpp
@@ -272,7 +272,7 @@ TEST_F(SceneTest, getLastUpdated)
expectGetState(id);
const Scene scene(id, commands, std::chrono::seconds(0));
const time::AbsoluteTime lastUpdated = scene.getLastUpdated();
- EXPECT_EQ(std::chrono::seconds(0), lastUpdated.getRandomVariation());
+ EXPECT_EQ(time::parseUTCTimestamp("2020-04-23T12:00:04"), lastUpdated.getBaseTime());
}
TEST_F(SceneTest, getVersion)
diff --git a/test/test_Schedule.cpp b/test/test_Schedule.cpp
index 9d8c440..c10d5ac 100644
--- a/test/test_Schedule.cpp
+++ b/test/test_Schedule.cpp
@@ -239,7 +239,7 @@ TEST_F(ScheduleTest, setTime)
const int id = 1;
expectGetState(id);
Schedule schedule(id, commands, std::chrono::steady_clock::duration::max());
- time::TimePattern time {time::AbsoluteTime(std::chrono::system_clock::now())};
+ time::TimePattern time {time::AbsoluteVariedTime(std::chrono::system_clock::now())};
nlohmann::json request = {{"localtime", time.toString()}};
nlohmann::json response = {{"success", {"/schedules/1/localtime", time.toString()}}};
EXPECT_CALL(
@@ -320,7 +320,7 @@ TEST(CreateSchedule, setCommand)
TEST(CreateSchedule, setTime)
{
- const time::AbsoluteTime time(std::chrono::system_clock::now());
+ const time::AbsoluteVariedTime time(std::chrono::system_clock::now());
const nlohmann::json request = {{"localtime", time.toString()}};
EXPECT_EQ(request, CreateSchedule().setTime(time::TimePattern(time)).getRequest());
}
diff --git a/test/test_TimePattern.cpp b/test/test_TimePattern.cpp
index 1bef75c..fc2df23 100644
--- a/test/test_TimePattern.cpp
+++ b/test/test_TimePattern.cpp
@@ -78,33 +78,33 @@ TEST(Time, durationTo_hh_mm_ss)
EXPECT_EQ(duration, parseDuration(durationTo_hh_mm_ss(duration)));
}
-TEST(AbsoluteTime, Constructor)
+TEST(AbsoluteVariedTime, Constructor)
{
system_clock::time_point now = system_clock::now();
{
- AbsoluteTime time(now);
+ AbsoluteVariedTime time(now);
EXPECT_EQ(now, time.getBaseTime());
EXPECT_EQ(0s, time.getRandomVariation());
}
system_clock::duration variation = 4h + 2min;
{
- AbsoluteTime time(now, variation);
+ AbsoluteVariedTime time(now, variation);
EXPECT_EQ(now, time.getBaseTime());
EXPECT_EQ(variation, time.getRandomVariation());
}
}
-TEST(AbsoluteTime, toString)
+TEST(AbsoluteVariedTime, toString)
{
const system_clock::time_point timePoint = parseTimestamp("2020-03-03T20:53:03");
- EXPECT_EQ("2020-03-03T20:53:03", AbsoluteTime(timePoint).toString());
+ EXPECT_EQ("2020-03-03T20:53:03", AbsoluteVariedTime(timePoint).toString());
const system_clock::duration noVariation = 0s;
- EXPECT_EQ("2020-03-03T20:53:03", AbsoluteTime(timePoint, noVariation).toString());
+ EXPECT_EQ("2020-03-03T20:53:03", AbsoluteVariedTime(timePoint, noVariation).toString());
const system_clock::duration variation = 1h + 2min + 1s;
- EXPECT_EQ("2020-03-03T20:53:03A01:02:01", AbsoluteTime(timePoint, variation).toString());
+ EXPECT_EQ("2020-03-03T20:53:03A01:02:01", AbsoluteVariedTime(timePoint, variation).toString());
}
TEST(AbsoluteTime, parseUTC)
@@ -361,7 +361,7 @@ TEST(TimePattern, CopyConstructor)
EXPECT_EQ(TimePattern::Type::undefined, copy.getType());
}
{
- const AbsoluteTime abs(system_clock::now());
+ const AbsoluteVariedTime abs(system_clock::now());
const TimePattern pattern(abs);
const TimePattern copy(pattern);
ASSERT_EQ(TimePattern::Type::absolute, copy.getType());
@@ -399,7 +399,7 @@ TEST(TimePattern, CopyConstructor)
TEST(TimePattern, Absolute)
{
{
- const AbsoluteTime abs(system_clock::now(), 20s);
+ const AbsoluteVariedTime abs(system_clock::now(), 20s);
const TimePattern pattern(abs);
ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
EXPECT_EQ(abs.getBaseTime(), pattern.asAbsolute().getBaseTime());
@@ -409,7 +409,7 @@ TEST(TimePattern, Absolute)
const system_clock::time_point timePoint = parseTimestamp("2020-03-03T20:53:03");
{
const TimePattern pattern = TimePattern::parse("2020-03-03T20:53:03");
- const AbsoluteTime expected(timePoint);
+ const AbsoluteVariedTime expected(timePoint);
ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
EXPECT_EQ(expected.getBaseTime(), pattern.asAbsolute().getBaseTime());
EXPECT_EQ(expected.getRandomVariation(), pattern.asAbsolute().getRandomVariation());
@@ -417,7 +417,7 @@ TEST(TimePattern, Absolute)
{
const system_clock::duration variation = 1h + 2min + 1s;
const TimePattern pattern = TimePattern::parse("2020-03-03T20:53:03A01:02:01");
- const AbsoluteTime expected(timePoint, variation);
+ const AbsoluteVariedTime expected(timePoint, variation);
ASSERT_EQ(TimePattern::Type::absolute, pattern.getType());
EXPECT_EQ(expected.getBaseTime(), pattern.asAbsolute().getBaseTime());
EXPECT_EQ(expected.getRandomVariation(), pattern.asAbsolute().getRandomVariation());