Rewrite electricity-logger to use an sqlite3 database
This commit is contained in:
151
include/util/date.hpp
Normal file
151
include/util/date.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#pragma once
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
namespace Util
|
||||
{
|
||||
inline bool IsValidYear(int const year) { return year > 1900 && year < 9999; }
|
||||
|
||||
inline bool IsValidMonth(int const month) { return month > 0 && month < 13; }
|
||||
|
||||
inline bool IsValidDay(int const day) { return day > 0 && day < 32; }
|
||||
|
||||
inline long GetEpoch(long year, unsigned month, unsigned day)
|
||||
{
|
||||
year -= month <= 2;
|
||||
const long era = (year >= 0 ? year : year - 399) / 400;
|
||||
const unsigned yoe = static_cast<unsigned>(year - era * 400); // [0, 399]
|
||||
const unsigned doy = (153 * (month + (month > 2 ? -3 : 9)) + 2) / 5 + day - 1; // [0, 365]
|
||||
const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
|
||||
|
||||
// Multiply by the day length in seconds
|
||||
return (era * 146097 + doe - 719468) * (24l * 60l * 60l);
|
||||
}
|
||||
|
||||
inline long ToEpoch(std::string const & date)
|
||||
{
|
||||
int year, month, day;
|
||||
if(std::sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return GetEpoch(year, month, day);
|
||||
}
|
||||
|
||||
inline unsigned ToSeconds(unsigned hours, unsigned minutes, unsigned seconds)
|
||||
{
|
||||
return (hours * 60 * 60) + (minutes * 60) + seconds;
|
||||
}
|
||||
|
||||
inline int ToSecondsFromTimeString(char const * string)
|
||||
{
|
||||
int hour, minute, second;
|
||||
if(std::sscanf(string, "%d:%d:%d", &hour, &minute, &second) != 3)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ToSeconds(hour, minute, second);
|
||||
}
|
||||
|
||||
inline std::string GetSqliteDate(time_t const epochTime)
|
||||
{
|
||||
auto const dateTime = *std::gmtime(&epochTime);
|
||||
|
||||
char dateStringBuffer[64];
|
||||
std::sprintf(dateStringBuffer, "%i-%02i-%02i", dateTime.tm_year + 1900, dateTime.tm_mon + 1, dateTime.tm_mday);
|
||||
|
||||
return std::string(dateStringBuffer);
|
||||
}
|
||||
|
||||
inline std::string GetSqliteUtcTime(time_t const epochTime)
|
||||
{
|
||||
auto const dateTime = *std::gmtime(&epochTime);
|
||||
|
||||
char timeStringBuffer[64];
|
||||
std::sprintf(timeStringBuffer, "%02i:%02i:%02i", dateTime.tm_hour, dateTime.tm_min, dateTime.tm_sec);
|
||||
|
||||
return std::string(timeStringBuffer);
|
||||
}
|
||||
|
||||
class Date {
|
||||
private:
|
||||
unsigned year;
|
||||
unsigned month;
|
||||
unsigned day;
|
||||
|
||||
public:
|
||||
unsigned Year() const { return year; }
|
||||
unsigned Month() const { return month; }
|
||||
unsigned Day() const { return day; }
|
||||
|
||||
void AddMonth()
|
||||
{
|
||||
++month;
|
||||
if(month > 12)
|
||||
{
|
||||
month = 1;
|
||||
++year;
|
||||
}
|
||||
}
|
||||
|
||||
void SetDayToEndOfMonth() { day = 31; }
|
||||
|
||||
bool IsValid() const { return IsValidYear(year) && IsValidMonth(month) && IsValidDay(day); }
|
||||
|
||||
long ToEpoch() const { return GetEpoch(year, month, day); }
|
||||
|
||||
bool IsBefore(unsigned const otherYear, unsigned const otherMonth, unsigned const otherDay) const
|
||||
{
|
||||
return (year < otherYear) || (year == otherYear && month < otherMonth)
|
||||
|| (year == otherYear && month == otherMonth && day < otherDay);
|
||||
}
|
||||
|
||||
bool IsBefore(Date const & other) const { return IsBefore(other.year, other.month, other.day); }
|
||||
|
||||
bool IsAfter(unsigned const otherYear, unsigned const otherMonth, unsigned const otherDay) const
|
||||
{
|
||||
return (year > otherYear) || (year == otherYear && month > otherMonth)
|
||||
|| (year == otherYear && month == otherMonth && day > otherDay);
|
||||
}
|
||||
|
||||
std::string ToISOString() const
|
||||
{
|
||||
char buffer[11];
|
||||
std::sprintf(buffer, "%04i-%02i-%02i", year, month, day);
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
bool TryParse(std::string const & date)
|
||||
{
|
||||
Date result;
|
||||
|
||||
if(sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3)
|
||||
{
|
||||
result.year = 0;
|
||||
result.month = 0;
|
||||
result.day = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Date() : year(0), month(0), day(0) { }
|
||||
|
||||
Date(std::string const & date) : year(0), month(0), day(0) { TryParse(date); }
|
||||
|
||||
Date(long const epoch)
|
||||
{
|
||||
std::tm dateTime = *std::gmtime(&epoch);
|
||||
year = 1900 + dateTime.tm_year;
|
||||
month = 1 + dateTime.tm_mon;
|
||||
day = dateTime.tm_mday;
|
||||
}
|
||||
|
||||
static Date UtcNow() { return Date(std::time(nullptr)); }
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user