A helper to find the bounds of a day.

This commit is contained in:
Scott Lamb 2016-05-01 22:12:55 -07:00
parent 292bcbaad5
commit 28fa458982
3 changed files with 61 additions and 4 deletions

View File

@ -291,6 +291,31 @@ TEST(AdjustDaysMapTest, Basic) {
EXPECT_THAT(days, testing::ElementsAre());
}
TEST(GetDayBoundsTest, Basic) {
int64_t start_90k;
int64_t end_90k;
std::string error_msg;
// Normal day.
EXPECT_TRUE(GetDayBounds("2015-12-31", &start_90k, &end_90k, &error_msg))
<< error_msg;
EXPECT_EQ(INT64_C(130639392000000), start_90k);
EXPECT_EQ(INT64_C(130647168000000), end_90k);
// Spring forward (23-hour day).
EXPECT_TRUE(GetDayBounds("2016-03-13", &start_90k, &end_90k, &error_msg));
EXPECT_EQ(INT64_C(131207040000000), start_90k);
EXPECT_EQ(INT64_C(131214492000000), end_90k);
// Fall back (25-hour day).
EXPECT_TRUE(GetDayBounds("2016-11-06", &start_90k, &end_90k, &error_msg));
EXPECT_EQ(INT64_C(133057404000000), start_90k);
EXPECT_EQ(INT64_C(133065504000000), end_90k);
// Unparseable day.
EXPECT_FALSE(GetDayBounds("xxxx-xx-xx", &start_90k, &end_90k, &error_msg));
}
// Basic test of running some queries on an empty database.
TEST_F(MoonfireDbTest, EmptyDatabase) {
std::string error_message;

View File

@ -47,6 +47,9 @@ namespace moonfire_nvr {
namespace {
const char kDayFmt[] = "%Y-%m-%d";
constexpr size_t kDayFmtBufSize = sizeof("YYYY-mm-DD");
// Helper for AdjustDaysMap.
void AdjustDay(const std::string &day, int64_t delta,
std::map<std::string, int64_t> *days) {
@ -80,9 +83,8 @@ void AdjustDaysMap(int64_t start_time_90k, int64_t end_time_90k, int sign,
memset(&mytm, 0, sizeof(mytm));
time_t start_ts = start_time_90k / kTimeUnitsPerSecond;
localtime_r(&start_ts, &mytm);
const char kFmt[] = "%Y-%m-%d";
char buf[sizeof("YYYY-mm-DD")];
strftime(buf, sizeof(buf), kFmt, &mytm);
char buf[kDayFmtBufSize];
strftime(buf, sizeof(buf), kDayFmt, &mytm);
// Determine the start of the next day.
// Note that mktime(3) normalizes tm_mday, so this should work on the last
@ -106,7 +108,7 @@ void AdjustDaysMap(int64_t start_time_90k, int64_t end_time_90k, int sign,
}
// Fill |buf| with the second day.
strftime(buf, sizeof(buf), kFmt, &mytm);
strftime(buf, sizeof(buf), kDayFmt, &mytm);
// Adjust the second day.
auto second_day_delta = sign * (end_time_90k - boundary_90k);
@ -117,6 +119,30 @@ void AdjustDaysMap(int64_t start_time_90k, int64_t end_time_90k, int sign,
} // namespace internal
bool GetDayBounds(const std::string &day, int64_t *start_time_90k,
int64_t *end_time_90k, std::string *error_message) {
struct tm mytm;
memset(&mytm, 0, sizeof(mytm));
if (strptime(day.c_str(), kDayFmt, &mytm) != day.c_str() + day.size()) {
*error_message = StrCat("Unparseable day: ", day);
return false;
}
mytm.tm_isdst = -1;
mytm.tm_hour = 0;
mytm.tm_min = 0;
mytm.tm_sec = 0;
*start_time_90k = kTimeUnitsPerSecond * static_cast<int64_t>(mktime(&mytm));
mytm.tm_isdst = -1;
mytm.tm_hour = 0;
mytm.tm_min = 0;
mytm.tm_sec = 0;
++mytm.tm_mday;
*end_time_90k = kTimeUnitsPerSecond * static_cast<int64_t>(mktime(&mytm));
return true;
}
bool MoonfireDatabase::Init(Database *db, std::string *error_message) {
CHECK(db_ == nullptr);
db_ = db;

View File

@ -259,6 +259,12 @@ class MoonfireDatabase {
std::map<int64_t, VideoSampleEntry> video_sample_entries_;
};
// Given a key in the day-to-duration map, produce the start and end times of
// the day. (Typically the end time is 24 hours later than the start; but it's
// 23 or 25 hours for the days of spring forward and fall back, respectively.)
bool GetDayBounds(const std::string &day, int64_t *start_time_90k,
int64_t *end_time_90k, std::string *error_message);
namespace internal {
// Adjust a day-to-duration map (see MoonfireDatabase::CameraData::days_)