@@ -991,16 +991,28 @@ inline auto tm_mon_short_name(int mon) -> const char* {
991991}
992992
993993template <typename T, typename = void >
994- struct has_member_data_tm_gmtoff : std::false_type {};
994+ struct has_tm_gmtoff : std::false_type {};
995995template <typename T>
996- struct has_member_data_tm_gmtoff <T, void_t <decltype (T::tm_gmtoff)>>
997- : std::true_type {};
996+ struct has_tm_gmtoff <T, void_t <decltype (T::tm_gmtoff)>> : std::true_type {};
998997
999- template <typename T, typename = void >
1000- struct has_member_data_tm_zone : std::false_type {};
998+ template <typename T, typename = void > struct has_tm_zone : std::false_type {};
1001999template <typename T>
1002- struct has_member_data_tm_zone <T, void_t <decltype (T::tm_zone)>>
1003- : std::true_type {};
1000+ struct has_tm_zone <T, void_t <decltype (T::tm_zone)>> : std::true_type {};
1001+
1002+ template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
1003+ bool set_tm_zone (T& time, char * tz) {
1004+ time.tm_zone = tz;
1005+ return true ;
1006+ }
1007+ template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
1008+ bool set_tm_zone (T&, char *) {
1009+ return false ;
1010+ }
1011+
1012+ inline char * utc () {
1013+ static char tz[] = " UTC" ;
1014+ return tz;
1015+ }
10041016
10051017// Converts value to Int and checks that it's in the range [0, upper).
10061018template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
@@ -1260,24 +1272,24 @@ class tm_writer {
12601272 write2 (static_cast <int >(offset % 60 ));
12611273 }
12621274
1263- template <typename T, FMT_ENABLE_IF(has_member_data_tm_gmtoff <T>::value)>
1264- void format_utc_offset_impl (const T& tm, numeric_system ns) {
1275+ template <typename T, FMT_ENABLE_IF(has_tm_gmtoff <T>::value)>
1276+ void format_utc_offset (const T& tm, numeric_system ns) {
12651277 write_utc_offset (tm.tm_gmtoff , ns);
12661278 }
1267- template <typename T, FMT_ENABLE_IF(!has_member_data_tm_gmtoff <T>::value)>
1268- void format_utc_offset_impl (const T&, numeric_system ns) {
1279+ template <typename T, FMT_ENABLE_IF(!has_tm_gmtoff <T>::value)>
1280+ void format_utc_offset (const T&, numeric_system ns) {
12691281 write_utc_offset (0 , ns);
12701282 }
12711283
1272- template <typename T, FMT_ENABLE_IF(has_member_data_tm_zone <T>::value)>
1273- void format_tz_name_impl (const T& tm) {
1284+ template <typename T, FMT_ENABLE_IF(has_tm_zone <T>::value)>
1285+ void format_tz_name (const T& tm) {
12741286 if (is_classic_)
12751287 out_ = write_tm_str<Char>(out_, tm.tm_zone , loc_);
12761288 else
12771289 format_localized (' Z' );
12781290 }
1279- template <typename T, FMT_ENABLE_IF(!has_member_data_tm_zone <T>::value)>
1280- void format_tz_name_impl (const T&) {
1291+ template <typename T, FMT_ENABLE_IF(!has_tm_zone <T>::value)>
1292+ void format_tz_name (const T&) {
12811293 format_localized (' Z' );
12821294 }
12831295
@@ -1389,8 +1401,8 @@ class tm_writer {
13891401 out_ = copy<Char>(std::begin (buf) + offset, std::end (buf), out_);
13901402 }
13911403
1392- void on_utc_offset (numeric_system ns) { format_utc_offset_impl (tm_, ns); }
1393- void on_tz_name () { format_tz_name_impl (tm_); }
1404+ void on_utc_offset (numeric_system ns) { format_utc_offset (tm_, ns); }
1405+ void on_tz_name () { format_tz_name (tm_); }
13941406
13951407 void on_year (numeric_system ns, pad_type pad) {
13961408 if (is_classic_ || ns == numeric_system::standard)
@@ -2236,7 +2248,7 @@ template <typename Char> struct formatter<std::tm, Char> {
22362248
22372249 public:
22382250 FMT_CONSTEXPR auto parse (parse_context<Char>& ctx) -> const Char* {
2239- return do_parse (ctx, detail::has_member_data_tm_gmtoff <std::tm>::value);
2251+ return do_parse (ctx, detail::has_tm_gmtoff <std::tm>::value);
22402252 }
22412253
22422254 template <typename FormatContext>
@@ -2261,17 +2273,20 @@ struct formatter<sys_time<Duration>, Char> : private formatter<std::tm, Char> {
22612273 if (detail::const_check (
22622274 period::num == 1 && period::den == 1 &&
22632275 !std::is_floating_point<typename Duration::rep>::value)) {
2276+ detail::set_tm_zone (tm, detail::utc ());
22642277 return formatter<std::tm, Char>::format (tm, ctx);
22652278 }
22662279 Duration epoch = val.time_since_epoch ();
22672280 Duration subsecs = detail::duration_cast<Duration>(
22682281 epoch - detail::duration_cast<std::chrono::seconds>(epoch));
22692282 if (subsecs.count () < 0 ) {
22702283 auto second = detail::duration_cast<Duration>(std::chrono::seconds (1 ));
2271- if (tm.tm_sec != 0 )
2284+ if (tm.tm_sec != 0 ) {
22722285 --tm.tm_sec ;
2273- else
2286+ } else {
22742287 tm = gmtime (val - second);
2288+ detail::set_tm_zone (tm, detail::utc ());
2289+ }
22752290 subsecs += second;
22762291 }
22772292 return formatter<std::tm, Char>::do_format (tm, ctx, &subsecs);
0 commit comments