Commit 1dacb529 authored by Axel Auweter's avatar Axel Auweter
Browse files

Add support for time input/output in local timezone (#31)

parent 9d874e82
......@@ -67,6 +67,16 @@ public:
*/
void setNow(void);
/**
* @brief Convert from local time to UTC
*/
void convertFromLocal(void);
/**
* @brief Convert from UTC to local time
*/
void convertToLocal(void);
/**
* @brief Returns the raw time stamp value.
* @return The object's value as uint64_t.
......
......@@ -9,9 +9,13 @@
#include <cinttypes>
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/local_time/local_time.hpp"
#include "boost/date_time/c_local_time_adjustor.hpp"
#include "timestamp.h"
/* Use this as our local to utc adjustor */
typedef boost::date_time::c_local_adjustor<boost::posix_time::ptime> local_adj;
/**
* This function parses a string and tries to do a best guess at the contained
......@@ -90,6 +94,49 @@ void DCDBTimeStamp::setNow(void)
raw = diff.total_nanoseconds();
}
/**
*
*/
void DCDBTimeStamp::convertFromLocal()
{
/*
* Unfortunately BOOST c_local_adjustor doesn't support local-to-utc conversion.
* Therfore, we first check the offset of "raw" during utc-to-local conversion
* and then apply this offset in the other direction.
*/
/* Construct ptime object t from raw */
boost::posix_time::ptime t(boost::gregorian::date(1970,1,1));
t += boost::posix_time::nanoseconds(raw);
/* Convert t to UTC */
boost::posix_time::ptime t2 = local_adj::utc_to_local(t);
/* Check the difference of the two times */
boost::posix_time::time_duration diff = t - t2;
/* Write back adjusted value to raw */
raw += diff.total_nanoseconds();
}
/**
*
*/
void DCDBTimeStamp::convertToLocal()
{
/* Construct ptime object t from raw */
boost::posix_time::ptime t(boost::gregorian::date(1970,1,1));
t += boost::posix_time::nanoseconds(raw);
/* Convert t to Local */
t = local_adj::utc_to_local(t);
/* Write back to raw */
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration diff = t - epoch;
raw = diff.total_nanoseconds();
}
/**
*
*/
......
......@@ -21,7 +21,7 @@ void usage(void)
{
/* 0---------1---------2---------3---------4---------5---------6---------7--------- */
std::cout << "Usage:" << std::endl
<< "dcdbquery [-h <hostname>] [-r] <Sensor 1> [<Sensor 2> ...] <Start> <End>" << std::endl
<< "dcdbquery [-h <hostname>] [-r] [-l] <Sensor 1> [<Sensor 2> ...] <Start> <End>" << std::endl
<< "where" << std::endl
<< " <hostname> - the name of the DB server" << std::endl
<< " <Sensor n> - a public sensor name" << std::endl
......@@ -31,7 +31,9 @@ void usage(void)
<< "<Start> and <End> times should be supplied as 'yyyy-mm-dd hh:mm:ss' or unix" << std::endl
<< "timestamps." << std::endl
<< "When the -r option is specified, timestamps will be reported in internal (raw)" << std::endl
<< "format (nanoseconds since epoch) insted of ISO human readable form." << std::endl;
<< "format (nanoseconds since epoch) insted of ISO human readable form." << std::endl
<< "When the -l option is specified, times for <Start>, <End>, and in the generated" << std::endl
<< "output will be interpreted / printed in the local time zone." << std::endl;
exit(EXIT_SUCCESS);
}
......@@ -46,7 +48,8 @@ int main(int argc, char* argv[])
int ret;
const char *host = "localhost";
bool raw = false;
while ((ret=getopt(argc, argv, "+h:r"))!=-1) {
bool localtime = false;
while ((ret=getopt(argc, argv, "+h:rl"))!=-1) {
switch(ret) {
case 'h':
host = optarg;
......@@ -54,6 +57,9 @@ int main(int argc, char* argv[])
case 'r':
raw = true;
break;
case 'l':
localtime = true;
break;
default:
usage();
exit(EXIT_FAILURE);
......@@ -65,6 +71,10 @@ int main(int argc, char* argv[])
try {
start = DCDBTimeStamp(argv[argc-2]);
end = DCDBTimeStamp(argv[argc-1]);
if (localtime) {
start.convertFromLocal();
end.convertFromLocal();
}
}
catch (std::exception& e) {
std::cout << "Wrong time format." << std::endl;
......@@ -83,7 +93,7 @@ int main(int argc, char* argv[])
sensors.push_back(argv[arg]);
}
DCDBQuery::doQuery(host, sensors, start, end, raw);
DCDBQuery::doQuery(host, sensors, start, end, raw, localtime);
return 0;
}
......@@ -22,7 +22,7 @@
#include "casshelper.h"
/* Lovely spaghetti code coming up next. Be aware... */
void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end, bool raw)
void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end, bool raw, bool localtime)
{
/* Connect to db */
CassCluster *cluster = CassHelper::create_cluster(hostname);
......@@ -54,7 +54,7 @@ void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DC
}
#endif
querySensorsCSV(session, *it, sidList, start, end, raw);
querySensorsCSV(session, *it, sidList, start, end, raw, localtime);
}
/* Clean up */
......@@ -279,7 +279,7 @@ bool DCDBQuery::sidPatternMatch(SensorId& sid, std::string pattern)
return true;
}
void DCDBQuery::querySensorsCSV(CassSession* session, std::string sensorName, std::list<SensorId>& sidList, DCDBTimeStamp& start, DCDBTimeStamp& end, bool raw)
void DCDBQuery::querySensorsCSV(CassSession* session, std::string sensorName, std::list<SensorId>& sidList, DCDBTimeStamp& start, DCDBTimeStamp& end, bool raw, bool localtime)
{
/* Since everything has been mangled until here, we assume parameter safety and do a non-prepared statement... Oh oh... */
std::stringstream query;
......@@ -313,11 +313,14 @@ void DCDBQuery::querySensorsCSV(CassSession* session, std::string sensorName, st
cass_value_get_int64(cass_row_get_column_by_name(row, "ts"), &ts);
cass_value_get_int64(cass_row_get_column_by_name(row, "value"), &value);
DCDBTimeStamp t((uint64_t)ts);
if (localtime) {
t.convertToLocal();
}
if (raw) {
std::cout << sensorName << "," << std::dec << ts << "," << std::dec << value << std::endl;
std::cout << sensorName << "," << std::dec << t.getRaw() << "," << std::dec << value << std::endl;
}
else {
DCDBTimeStamp t((uint64_t)ts);
std::cout << sensorName << "," << t.getString() << "," << std::dec << value << std::endl;
}
}
......
......@@ -20,7 +20,7 @@
class DCDBQuery
{
public:
static void doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end, bool raw);
static void doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end, bool raw, bool localtime);
protected:
static void lookupPublishedSensorPattern(CassSession* session, std::string name, std::string& pattern);
......@@ -28,7 +28,7 @@ protected:
static bool topicToSid(SensorId& sid, std::string topic);
static std::string sidConvert(SensorId& sid);
static bool sidPatternMatch(SensorId& sid, std::string pattern);
static void querySensorsCSV(CassSession* session, std::string sensorName, std::list<SensorId>& sidList, DCDBTimeStamp& start, DCDBTimeStamp& end, bool raw);
static void querySensorsCSV(CassSession* session, std::string sensorName, std::list<SensorId>& sidList, DCDBTimeStamp& start, DCDBTimeStamp& end, bool raw, bool localtime);
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment