1

I'm trying to handle dates and times in my code, and have been pointed in the direction of the boost library - specifically, boost::locale::date_time (in part because this lets me avoid Daylight Saving Time weirdness that was making my previous implementation difficult).

However, I'm getting inconsistent results. When I store a date in the date_time object and later try to get data from it, it is incorrect. Here's an example:

#include <boost\\asio\\error.hpp>
#include <boost\\locale.hpp>
using namespace std;

int main()
{
    // Necessary to avoid bad_cast exception - system default should be fine
    boost::locale::generator gen;
    std::locale::global(gen(""));

    // Create date_time of 12/19/2016
    boost::locale::date_time dt = boost::locale::period::year(2016) + boost::locale::period::month(12) + boost::locale::period::day(19);

    unsigned int month = dt.get(boost::locale::period::month());
    unsigned int day = dt.get(boost::locale::period::day());
    unsigned int year = dt.get(boost::locale::period::year());

    cout << month << "/" << day << "/" << year << endl;

    // Expected output:  12/19/2016
    // Actual output:    0/19/2017
}

What am I doing wrong? I just want to extract the saved days, months, years, hours, etc.

Thank you.

EDIT: It's possible I'm initially setting the date_time in an incorrect manner. Is there a better way to explicitly set a date time (for instance, to 12-19-2016), assuming I have all the relevant data in integer (not string) format?

user3236291
  • 133
  • 7

1 Answers1

1

2016-04-05 + 12 months = 2017-04-05. This makes sense, since 12 months is a whole year.

Try adding 11 months instead, then increment to adjust from a 0-based month to a 1-based month.

boost::locale::date_time dt = boost::locale::period::year(2016) + boost::locale::period::month(11) + boost::locale::period::day(19);

uint month = dt.get(boost::locale::period::month()) + 1;
uint day = dt.get(boost::locale::period::day());
uint year = dt.get(boost::locale::period::year());

cout << month << "/" << day << "/" << year << endl;
Xirema
  • 19,889
  • 4
  • 32
  • 68
  • Ok, how do I initially set the date_time correctly, assuming I have the data in integer format already (i.e., I know I'm talking about 12-19-2016)? That is, how do I know that months are 0-based? And how do I know whether days are 0-based, or any other fragment of the date-time? Or is there simply a better way to initialize the known date_time? – user3236291 Jun 28 '17 at 20:23
  • @user3236291 Subtract 1 from the month's value. Treat `January` as being equivalent to `0`, and `December` as being equivalent to `11`, and adjust when displaying dates. – Xirema Jun 28 '17 at 20:25
  • @user3236291 If you look at the documentation for [date_time](http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/dates_times_timezones.html), you'll see it has examples of being more verbose/explicit with intent in the library itself, like using `boost::locale::period::january()` to get an exact value for individual months. – Xirema Jun 28 '17 at 20:27
  • I see. The documentation said that the days were 1-based (not 0-based), so I assumed the months were as well. That is actually incorrect, and the documentation says the months are 0-based. Thanks for the help! – user3236291 Jun 28 '17 at 20:28
  • @user3236291 "how do I know" ... you read the [docs](http://www.boost.org/doc/libs/1_51_0/libs/locale/doc/html/namespaceboost_1_1locale_1_1period.html) -- e.g. for `period::month`: " The month of year, calendar specific, in Gregorian [0..11] " – Dan Mašek Jun 28 '17 at 20:29
  • @user3236291 It might seem a little inconsistent, but that's how most other Date/Time Libraries work, so it made sense to adopt the same conventions there. – Xirema Jun 28 '17 at 20:29