[DRAFT PROPOSAL]: Adapted from: https://isocpp.org/std/submit-a-proposal [TITLE]: Add a two-digit-truncated-integer-seconds conversion specifier in std::format for std::chrono time types. Document number: i Date: 2023-04-28 Audience: Library Evolution Working Group Reply-to: “Simon Hill " 1. Table of Contents ==================== 1. Table of Contents 2. Introduction. 3. Motivation and Scope 4. Implementation Example 4. Impact On the Standard 5. Design Decisions 6. Technical Specifications 7. Acknowledgements 8. References 2. Introduction =============== This proposal adds the conversion specifier "%s" to std::format for std::chrono time types. "%s" would provide two-digit integer-truncated seconds (compared to the current "%S" which provides fractional seconds). These are defined in the C++ standard at $time.format (29.12:6). 3. Motivation and Scope ======================= 3.a) Prevalence: --------------- Two-digit integer-truncated seconds are widely used everywhere. Most digital clocks that show seconds, from watches to OS time displays, use this format. The %H %M %S codes are used in many places, such as: - (xfce clock): https://docs.xfce.org/xfce/xfce4-panel/clock "%S"="second (00..60)" - (gnome clock format extension): https://github.com/lazka/pgi-docs/blob/master/GLib-2.0/classes/DateTime.html: "%S: the second as a decimal number (range 00 to 60)" - (GNU (ls etc)): https://www.gnu.org/software/coreutils/manual/html_node/Time-conversion-specifiers.html "%S"="second (‘00’…‘60’). This may be ‘60’ if leap seconds are supported. " And other places have the same functionality with different codes: - (.net formatting) https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings "ss"="The second, from 00 through 59." Given the prevalence of %S for integer seconds, I believe the current behavior of C++ would be surprising to many developers. 3.b) Consistency: ---------------- The other sub-day quantities (hours and minutes) are already two-digit integer-truncated. (And there is no fractional minutes or fractional hours specifier (and, IMHO, that's probably good)). 3.c) Reduced verbosity: ---------------------- This reduces verbosity without adding ambiguity, because it is currently necessary to convert any sub-second time quantity to integer seconds prior to formatting to achive two-digit-integer second formatting. 3.d) Efficiency: --------------- The currently required method may have the potential to be less efficient because it *requires* a conversion in user code, (and it's not easy for a user to determine whether this conversion is trivial). This is unlikely to be very important, however, as it's unlikely this function will be called often enough to noticeably affect performance. 4: Implementation Example: ========================= "%s" is easily implemented in GCC by this diff: [GCC PROJECT]/libstdc++-v3/include/bits/chrono_io.h --------------------------------------------------- *** 382,387 **** --- 382,388 ---- __needed = _Duration; break; case 'S': + case 's': __needed = _TimeOfDay; __allowed_mods = _Mod_O; break; *************** *** 615,620 **** --- 616,627 ---- case 'S': __out = _M_S(__t, __print_sign(), __fc, __mod == 'O'); break; + case 's': + // %s The second as a decimal number. + // %Os Locale's alternative representation. + __out = _S_dd_zero_fill(_S_hms(__t).seconds().count(), + __print_sign(), __fc, __mod == 'O'); + break; case 'u': case 'w': __out = _M_u_w(__t, std::move(__out), __fc, __c, __mod == 'O'); --------------------------------------------------- (the functionality is copied and adapted from '%M' (minute specifier)) 4. Impact On the Standard ========================= This proposal requires no changes to the C++ core language. This proposal requires very minor changes to the "time.format" standard-library section of the C++ standard (29.12:6). This proposal requires no changes to other parts of the C++ standard library. This proposal is trivial to implement. 5. Design Decisions =================== The primary proposal, as it exists, should have zero effect on existing valid code. Any software that currently uses "%s" (as a std::format conversion specifier for std::chrono) with a conformant implementation of the C++ standard should, AFAICT, currently be invalid. I can see no downsides to the primary proposal (other than the obvious: adding lines to the standard and requiring time to edit compiler source). Alternate Proposal: ------------------ There is an alternative proposal, which may be worth considering/modifying (in full or by part) Use '%E' (sEconds) instead of '%S' for the current implementation (fractional seconds). "%E" is currently unused. Use '%S' for two-digit-integer seconds (which is more consistent with %H and %M, and is far more common in other software). Use '%s' for seconds since the epoch. (%s is frequently used for this purpose elsewhere, eg. in the examples above). "%s" is currently unused. Use '%f' for subsecond digits only without the radix separator/decimal point. "%f" is currently unused. "%f" is suggested here mostly as a companion to "%s". With other 'combo' conversion specifiers options (such as "%T" and "%F") all their subcomponents are also conversion specifiers. "%E" can now be considered an 'combo' specifier equal to either (the new) "%S" or (the new) "%S.%f". As std::format is quite new, and the desire for fractional seconds is likely low, these changes are unlikely to affect many programs. IMHO this alternative proposal is superior, but its changes have the potential to affect existing programs (although the consequences are unlikely to be very bad). 6. Technical Specifications =========================== In table: - 29.12:6: Table 102: Meaning of conversion specifiers [tab:time.format.spec] Add this row: --- %s | Seconds as a decimal integer. If the number of seconds is less than 10, the result is prefixed with 0. --- 7. Acknowledgements: =================== Me. 8. References: ============= The C++ Standard. GCC. Discussion on stackoverflow: https://stackoverflow.com/questions/76106361/stdformating-stdchrono-seconds-without-fractional-digits