【发布时间】:2014-10-18 15:44:26
【问题描述】:
来自关于类 boost::gregorian::date here:
的 boost 文档"boost::gregorian::date 内部存储为 32 位整数类型"
现在,这将是一种很好、紧凑的方式,例如,将此日期存储在文件中。但是文档没有指定任何从对象中提取它的方法。
问题是:有没有办法获得这个整数表示,然后构造另一个相同类的相等对象?
【问题讨论】:
来自关于类 boost::gregorian::date here:
的 boost 文档"boost::gregorian::date 内部存储为 32 位整数类型"
现在,这将是一种很好、紧凑的方式,例如,将此日期存储在文件中。但是文档没有指定任何从对象中提取它的方法。
问题是:有没有办法获得这个整数表示,然后构造另一个相同类的相等对象?
【问题讨论】:
day_number() 成员函数返回 this。
boost::gregorian::date d(2014, 10, 18);
uint32_t number = d.day_number();
逆可以实现:
gregorian_calendar::ymd_type ymd = gregorian_calendar::from_day_number(dn);
d = { ymd.year, ymd.month, ymd.day };
你当然可以使用 Boost Serialization 来进行序列化,它会使用最紧凑的表示。见http://www.boost.org/doc/libs/1_56_0/doc/html/date_time/serialization.html
查看完整演示:Live On Coliru
#include <boost/date_time/gregorian/greg_date.hpp>
#include <boost/date_time/gregorian/gregorian_io.hpp>
#include <iostream>
using namespace boost::gregorian;
int main()
{
date d(2014, 10, 17);
static_assert(sizeof(d) == sizeof(int32_t), "truth");
std::cout << d << "\n";
uint32_t dn = d.day_number();
dn += 1;
gregorian_calendar::ymd_type ymd = gregorian_calendar::from_day_number(dn);
d = { ymd.year, ymd.month, ymd.day };
std::cout << d << "\n";
}
【讨论】:
一个便宜的把戏是做
tm to_tm(日期)
和
日期 date_from_tm(tm datetm)
并使用
将 tm 从/转换为 time_tstruct tm *localtime(const time_t *timep); time_t mktime(struct tm *tm)
然而,time_t 通常是 64 位,而旧的 32 位将在 2038 年失效。
将日期编码/解码为并不复杂
int32_t ye = d.year();
uint32_t mo = d.month();
uint32_t da = d.day();
// encode
int32_t l = ((ye << 9) & 0xfffffe00) | ((mo << 5) & 0x0000001d0) | (da & 0x0000001f);
// decode
ye = (l >> 9);
mo = ((l >> 5) & 0x0000000f);
da = (l & 0x0000001f);
【讨论】: