If you are willing to use a free, open-source library that is not boost and are using C++11 or later, check out:
https://github.com/HowardHinnant/date
Example code:
#include "date.h"
#include "iso_week.h"
#include <iostream>
int
main()
{
using namespace iso_week::literals;
auto ymd = date::year_month_day{2016_y/13_w/mon};
std::cout << ymd << '\n';
}
This outputs:
2016-03-28
There are year()
, month()
and day()
getters on the ymd
object.
There is full documentation at the above link. "date.h" and "iso_week.h" are header only, so there is no need to link to any other source.
These computations strictly follow the rules for the ISO week-based year outlined here. The first week of the year begins on the Monday following the last Thursday of December of the preceding year. This means that sometimes an ISO-year for a date is different than the Gregorian year. For example 2016_y/jan/1 == 2015_y/53_w/fri
, and in this pseudo-code 2016_y
and 2015_y
have different types (date::year
and iso_week::year
) so they can not be accidentally confused. The C++ type system will find accidental ambiguities at compile-time.
It is just as easy to go the other direction:
#include "date.h"
#include "iso_week.h"
#include <iostream>
int
main()
{
using namespace date::literals;
auto iso = iso_week::year_weeknum_weekday{2016_y/mar/28};
std::cout << iso << '\n';
}
which outputs:
2016-W13-Mon
In C++14, if your inputs are compile-time constants, then the result can be constexpr
(a compile-time computation). (requires more constexpr
muscle than VS-2015 currently supports)