Closed MikeGitb closed 7 years ago
There isn't a direct equivalent to std::tm
because this structure is overkill for some applications and insufficient for others. Instead there are a wide variety of calendrical and temporal building blocks to make it easy for you to build what is just right for you.
year_month_day
is the analog of {tm_year, tm_mon, tm_mday}
but with better syntax. year_month_day
excels at year and month oriented arithmetic.
time_of_day<seconds>
is the analog of {tm_hour, tm_min, tm_sec}
. But that should not be interpreted to mean that time_of_day<seconds>
is the way to carry around the time of day. A count of seconds
since midnight is arguably superior. Indeed you might want to create your own {year_month_day, seconds}
type. Or maybe seconds
isn't precise enough for you, so choose milliseconds
instead. You can also get a time_of_day<milliseconds>
which holds {hours, minutes, seconds, milliseconds}
fields.
There is a weekday
class that is the analog of tm_wday
.
There is no analog of tm_yday
, however this quantity is trivial to compute for any y/m/d
triple: sys_days{y/m/d} - sys_days{y/jan/1}
.
sys_info.save
is the analog of tm_isdst
. sys_info.save == 0min
if Daylight Saving Time is not in effect, otherwise Daylight Saving Time is in effect.
So all the information is there, but presented so that you can mix, match and customize what you need (seconds precision is not presumed to be needed nor sufficient). Additionally there is much more information regarding time zones which is available that std::tm
does not support:
tm
on some platforms).tm
on some platforms).Here (https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#time_point_to_components) is example code for converting to and from a std::tm
.
A recent redesign of the I/O has led to a very tm
-like structure that I have not documented:
template <class Duration>
struct fields
{
year_month_day ymd{0_y/0/0};
weekday wd{7u};
time_of_day<Duration> tod{};
public:
// ... constructors
I have not documented it because I don't want to introduce it to the API if it is not necessary. However if it turns out that people do need it, I can commit to it and document it.
I use this project to simulate localtime()+mktime() for multiple timezones in a single process this way. It assumes:
const date::time_zone *const date_time_zone(date::locate_zone("TIMEZONENAME"));
localtime(): GMT time_t -> local struct tm
const auto zoned(date::make_zoned(date_time_zone,date::sys_time<std::chrono::nanoseconds>(std::chrono::system_clock::from_time_t(ts))));
const time_t tslocal(std::chrono::duration_cast<std::chrono::seconds>(zoned.get_local_time().time_since_epoch()).count());
struct tm tm;
struct tm *const tmerr(gmtime_r(&tslocal,&tm));
assert(tmerr==&tm);
tm.tm_isdst=-1;
mktime(): local struct tm -> GMT time_t
const date::year_month_day ymd(date::year(1900+tm.tm_year),date::month(1+tm.tm_mon),date::day(tm.tm_mday));
const auto zoned(date::make_zoned(date_time_zone,date::local_days(ymd)+std::chrono::seconds((tm.tm_hour*60+tm.tm_min)*60+tm.tm_sec)));
const time_t tsgmt(std::chrono::duration_cast<std::chrono::seconds>(zoned.get_sys_time().time_since_epoch()).count());
assert(tsgmt!=-1);
However if it turns out that people do need it, I can commit to it and document it.
Thank you very much. I'll have to experiment with it a bit, but I believe I would very much like to have it as a part of your library. Most importantly for me would be the ability to easily create this directly from a zoned or sys time.
I hope I haven't just overlooked it, but does your library provide some equivalent to the
std::tm
struct? If not is there a particular reason for it?