Skip to content

Formatting a std::chrono::system_clock renders in local time, not in UTC #3199

Description

@ned14

For some time now we've had this in our cmake, so I figured time to upstream this:

  message(STATUS "NOTE: Patching '${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/fmt/chrono.h' to fix a formatting bug ...")
  file(READ "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/fmt/chrono.h" fmt_chrono_contents)
  string(REPLACE "  auto format(std::chrono::time_point<std::chrono::system_clock> val," "  auto format(std::chrono::time_point<std::chrono::system_clock, Duration> val," fmt_chrono_contents "${fmt_chrono_contents}")
  string(REPLACE "    return formatter<std::tm, Char>::format(localtime(val), ctx);" "    return formatter<std::tm, Char>::format(gmtime(std::chrono::time_point_cast<std::chrono::system_clock::time_point::duration>(val)), ctx);" fmt_chrono_contents "${fmt_chrono_contents}")
  file(WRITE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/fmt/chrono.h" "${fmt_chrono_contents}")

Two things are changed here:

  1. The Duration template parameter isn't passed through, breaking formatting time points with non-default duration types.

  2. Formatting system clock time points is to UTC, not to localtime, as system clock specifically represents UTC not local time (if you want a local time point, use chrono::local_t). Microsoft's implementation of std::format agrees with this formatting interpretation i.e. system clocks format to UTC strings, local clocks format to local strings.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions