diff --git a/cpp/src/arrow/util/formatting.h b/cpp/src/arrow/util/formatting.h index 6125f792ff9..dd9af907ecc 100644 --- a/cpp/src/arrow/util/formatting.h +++ b/cpp/src/arrow/util/formatting.h @@ -126,8 +126,10 @@ namespace detail { ARROW_EXPORT extern const char digit_pairs[]; // Based on fmtlib's format_int class: -// Write digits from right to left into a stack allocated buffer -inline void FormatOneChar(char c, char** cursor) { *--*cursor = c; } +// Write digits from right to left into a stack allocated buffer. +// \pre *cursor points to the byte after the one that will be written. +// \post *cursor points to the byte that was written. +inline void FormatOneChar(char c, char** cursor) { *(--(*cursor)) = c; } template void FormatOneDigit(Int value, char** cursor) { @@ -326,6 +328,7 @@ class StringFormatter : public FloatToStringFormatterMixin constexpr size_t BufferSizeHH_MM_SS() { + // "23:59:59" ("." "9"+)? return detail::Digits10(23) + 1 + detail::Digits10(59) + 1 + detail::Digits10(59) + 1 + detail::Digits10(Duration::period::den) - 1; } @@ -505,8 +509,9 @@ class StringFormatter { timepoint_days -= days(1); } + // YYYY_MM_DD " " HH_MM_SS "Z"? constexpr size_t buffer_size = - detail::BufferSizeYYYY_MM_DD() + 1 + detail::BufferSizeHH_MM_SS(); + detail::BufferSizeYYYY_MM_DD() + 1 + detail::BufferSizeHH_MM_SS() + 1; std::array buffer; char* cursor = buffer.data() + buffer_size; diff --git a/cpp/src/arrow/util/formatting_util_test.cc b/cpp/src/arrow/util/formatting_util_test.cc index 13f57a495d6..fcbeec347d3 100644 --- a/cpp/src/arrow/util/formatting_util_test.cc +++ b/cpp/src/arrow/util/formatting_util_test.cc @@ -533,6 +533,14 @@ TEST(Formatting, Timestamp) { } } + { + constexpr int64_t kMillisInDay = 24 * 60 * 60 * 1000; + auto ty = timestamp(TimeUnit::MILLI, "+01:00"); + StringFormatter formatter(ty.get()); + AssertFormatting(formatter, -15000 * 365 * kMillisInDay + 1, + "-13021-12-17 00:00:00.001Z"); + } + { auto ty = timestamp(TimeUnit::MILLI, "Pacific/Maruesas"); StringFormatter formatter(ty.get());