tomaszkam / date

A date and time library based on the C++11/14/17 <chrono> header
Other
0 stars 0 forks source link

[LWG3232] Inconsistency in zoned_time deduction guides #22

Closed tomaszkam closed 5 years ago

tomaszkam commented 5 years ago

Original comment:

Change:

template<class Duration, class TimeZonePtr, class TimeZonePtr2> zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest) -> zoned_time<Duration, TimeZonePtr>;

to:

template<class Duration, class TimeZonePtr, class TimeZonePtr2> zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest) -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;

E-mail conversation: [isocpp-lib] zoned_time issues

tomaszkam commented 5 years ago

Tim's comment:

  1. Alone among the deduction guides, this one doesn't change Duration to common_type_t<Duration, seconds>:

    template<class Duration, class TimeZonePtr, class TimeZonePtr2> zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest) -> zoned_time<Duration, TimeZonePtr>;

tomaszkam commented 5 years ago

Discussion: Currently, the time_zone is always storing the time with the precision not coarser that second, as consequence any instance with the duration with coarser precision with seconds, is de-facto equivalent to one instantiated to the duration of seconds. This is caused by the fact, that time zone offset can be defined up to seconds precision. To illustate both of following specialization has the same behavior (keep seconds):

zoned_time<minutes> zt(current_zone(), floor<minutes>(stystem_clock::now());
zoned_time<hours> zt(current_zone(), floor<hours>(stystem_clock::now());
zoned_time<seconds> zt(current_zone(), floor<seconds>(stystem_clock::now());

To avoid unnecessary code bloat caused by above, most deduction guides are instantiating zoned_time with at least seconds precision (i.e. zoned_time will be deduced for all of above), e.g.:

template<class TimeZonePtr, class Duration>
    zoned_time(TimeZonePtr, zoned_time<Duration>, choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;

However there is single exception:

template<class Duration, class TimeZonePtr, class TimeZonePtr2>
  zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
    -> zoned_time<Duration, TimeZonePtr>;

This deduction guide should be updated to preserve the consistency of design.

Proposed wording: Apply the following changes to [time.zone.zonedtime.overview]:

template<class Duration, class TimeZonePtr, class TimeZonePtr2>
zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
-> zoned_time<common_type_t<Duration ,seconds>, TimeZonePtr>;
tomaszkam commented 5 years ago

Already implemented in in master.