简要背景:
我正在尝试使用QCustomPlot 1.3测试版绘制股票的蜡烛图。我跳过了库的代码,发现对于时间序列,它使用了一个类型def(qcustomplot.h:line3140)
typedef QMap<double, QCPFinancialData> QCPFinancialDataMap;
其中QCPFinancialData是(qcustomplot.h:第3124行)
class QCP_LIB_DECL QCPFinancialData
{
public:
QCPFinancialData();
QCPFinancialData(double key, double open, double high, double low, double close);
double key, open, high, low, close;
};
因此,OHLC数据显然存在,并且类使用QMap中使用的键来索引时间序列条目。
因此,显而易见的关键是日期-时间(我正在绘制一天结束图,所以每个条目都只是一个日期,没有使用时间)。在我的解析代码中,我使用了
boost::gregorian::date
因为它有很多优点(从字符串转换、计算经过的日期和时间等)。
问题是,我是否应该继续简单地将boost::gregori::date转换为unix时间戳,然后将该时间戳记录为double?我在github上发现了一个小模板函数,它可以将其转换为time_t类型,但我认为在这种情况下,double应该不是问题,或者这是一个潜在的错误吗?AFAIK,Unix时间戳表示自1970年1月1日以来的秒数,当用双精度表示时,对于一个键来说应该绰绰有余?
在QCustomPlot的示例中,它们使用从时间序列开始(例如,开始日期)起的累加器/计数器,而不是时间戳。
由于您有足够的空间存储自epoch(即1970年1月1日)以来的秒数,因此自epoch以来的时间戳可以非常常规地存储在一倍中和仍然有足够的分辨率存储一微秒多一点。
例如R这样做:
R> now <- Sys.time() # get current date and time
R> now # default format to test
[1] "2014-11-11 20:38:27.307228 CST" # NB I have an option set for subsec.
R> as.integer(now) # as integer: seconds since epoch
[1] 1415759907
R> as.double(now) # as double under default precision
[1] 1415759907
R> print(as.double(now), digits=16) # as double with forced higher prec.
[1] 1415759907.307228
R>
我一直在C/C++层使用这些作为double
。如果我没有错的话,你可以让Boost为你做转换。
编辑:我知道我在某个地方有它:
boost::posix_time::ptime pt;
// ... in what follows dt has subcomponents we can access
pt = boost::posix_time::ptime(boost::gregorian::date(dt.getYear(),
dt.getMonth(),
dt.getDay()),
boost::posix_time::time_duration(dt.getHours(),
dt.getMinutes(),
dt.getSeconds(),
dt.getMicroSeconds()/1000.0));
转换为time_t
,包括子条件:
boost::posix_time::ptime dt = ....
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration x = dt - epoch; // needs UTC to local corr.,
// but we get the fract. sec.
struct tm t = boost::posix_time::to_tm(dt); // this helps with UTC conve.
time_t tt = mktime(&t) + 1.0 * x.fractional_seconds() / x.ticks_per_second()));