I have to store an age (years, months, days....possibly hours, minutes, seconds) of the user. I'm working with C++ and boost.
I'm not sure wich class of boost::posix_time
(or boost::date_time
) I should use.
I tried boost::posix_time::time_duration
, but it's not obvious because there is no constructor taking a year count, it's only hours, so I did:
boost::posix_time::time_duration age = boost::posix_time::hours(24*365*ageInYears);
But I'm not sure that's a good strategy because all years does not have 365 days ;-)
I also tried boost::gregorian::date
, but that's tricky because this one does not allow to store a year
before 1400 (and this stores a date, not a duration).
int
because it's not accurate enough (24 years old + 11 months is almost 25).float
because I don't want to reinvent the wheel with float to age conversion I would have to do...Is there really no class making it easy to store a number of years and optionally a number of month and days in boost?
Ideally, for a guy of 30 years old and a half, I'd like to be able to create an object like that: boost::....... theAge( 30, 6, 0 );
and then:
There are indeed duration types in boost::gregorian
, specifically:
boost::gregorian::date_duration
(aka boost::gregorian::days
) - a count of daysboost::gregorian::months
- a count of calendar monthsboost::gregorian::years
- a count of calendar yearsboost::gregorian::weeks
- a count of 7 daysThese would be ideal for storage i.e. store a tuple of (years, months, days).
Note though that arithmetic using in particular months
and years
can have unexpected results, as they provide a snap-to-end-of-month behavior:
months single(1); // 1 month duration
date(2005,Feb,28) + single; // => 2005-Mar-31
Edit from OP owner: There's actually a an existing boost struct to store year/month/day objects (boost::date_time::date_time::year_month_day_base
).
Here is an implementation perfect to answer the OP:
class age : public date_time::year_month_day_base<years, months, days>
{
typedef date_time::year_month_day_base<years, months, days> baseClass;
public:
age( int yearsCount, int monthsCount = 0, int daysCount = 0 ) :
baseClass( boost::gregorian::years(yearsCount),
boost::gregorian::months(monthsCount),
boost::gregorian::days(daysCount) )
{
}
inline int years() const { return year.number_of_years().as_number(); }
inline int months() const { return month.number_of_months().as_number(); }
inline int days() const { return day.days(); }
float getAsFloat() const
{
float age = static_cast<float>(years());
age += months()/12.0f;
age += days()/365.25f;
return age;
}
};
Then, age(30).years() == 30
and age(30,6,8).getAsFloat() == 30.521902
boost::posix_time::time_duration
really is one way to do this properly. Another way (which I personally would prefer) is to store the birth date and the "as-of date" both, and subtract them when you need to find the age as-of that date.
In any case you don't need a constructor taking a number of years--you can simply subtract birth_date from today--if you do that using date_time objects, you'll get a time_duration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With