Skip to content

Commit a288364

Browse files
AlenkaFrok
andauthored
GH-30117: [C++][Python] Add "Z" to the end of timestamp print string when tz defined (#39272)
### What changes are included in this PR? This PR updates the PrettyPrint for Timestamp type so that "Z" is printed at the end of the output string if the timezone has been defined. This way we add minimum information about the values being stored in UTC. ### Are these changes tested? Yes. ### Are there any user-facing changes? There is a change in how `TimestampArray` prints out the data. With this change "Z" would be added to the end of the string if the timezone is defined. * Closes: #30117 Lead-authored-by: AlenkaF <frim.alenka@gmail.com> Co-authored-by: Alenka Frim <AlenkaF@users.noreply.github.com> Co-authored-by: Rok Mihevc <rok@mihevc.org> Signed-off-by: Joris Van den Bossche <jorisvandenbossche@gmail.com>
1 parent 6b93c4a commit a288364

4 files changed

Lines changed: 48 additions & 4 deletions

File tree

cpp/src/arrow/pretty_print_test.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,10 @@ TEST_F(TestPrettyPrint, DateTimeTypes) {
350350
std::vector<int64_t> values = {
351351
0, 1, 2, 678 + 1000000 * (5 + 60 * (4 + 60 * (3 + 24 * int64_t(1)))), 4};
352352
static const char* expected = R"expected([
353-
1970-01-01 00:00:00.000000,
354-
1970-01-01 00:00:00.000001,
353+
1970-01-01 00:00:00.000000Z,
354+
1970-01-01 00:00:00.000001Z,
355355
null,
356-
1970-01-02 03:04:05.000678,
356+
1970-01-02 03:04:05.000678Z,
357357
null
358358
])expected";
359359
CheckPrimitive<TimestampType, int64_t>(timestamp(TimeUnit::MICRO, "Transylvania"),

cpp/src/arrow/util/formatting.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ class StringFormatter<TimestampType> {
470470
using value_type = int64_t;
471471

472472
explicit StringFormatter(const DataType* type)
473-
: unit_(checked_cast<const TimestampType&>(*type).unit()) {}
473+
: unit_(checked_cast<const TimestampType&>(*type).unit()),
474+
timezone_(checked_cast<const TimestampType&>(*type).timezone()) {}
474475

475476
template <typename Duration, typename Appender>
476477
Return<Appender> operator()(Duration, value_type value, Appender&& append) {
@@ -503,6 +504,9 @@ class StringFormatter<TimestampType> {
503504
std::array<char, buffer_size> buffer;
504505
char* cursor = buffer.data() + buffer_size;
505506

507+
if (timezone_.size() > 0) {
508+
detail::FormatOneChar('Z', &cursor);
509+
}
506510
detail::FormatHH_MM_SS(arrow_vendored::date::make_time(since_midnight), &cursor);
507511
detail::FormatOneChar(' ', &cursor);
508512
detail::FormatYYYY_MM_DD(timepoint_days, &cursor);
@@ -516,6 +520,7 @@ class StringFormatter<TimestampType> {
516520

517521
private:
518522
TimeUnit::type unit_;
523+
std::string timezone_;
519524
};
520525

521526
template <typename T>

cpp/src/arrow/util/formatting_util_test.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,34 @@ TEST(Formatting, Timestamp) {
522522
AssertFormatting(formatter, -2203932304LL * 1000000000LL + 8,
523523
"1900-02-28 12:34:56.000000008");
524524
}
525+
526+
{
527+
auto timestamp_types = {timestamp(TimeUnit::SECOND, "US/Eastern"),
528+
timestamp(TimeUnit::SECOND, "+01:00")};
529+
for (auto ty : timestamp_types) {
530+
StringFormatter<TimestampType> formatter(ty.get());
531+
532+
AssertFormatting(formatter, 0, "1970-01-01 00:00:00Z");
533+
}
534+
}
535+
536+
{
537+
auto ty = timestamp(TimeUnit::MILLI, "Pacific/Maruesas");
538+
StringFormatter<TimestampType> formatter(ty.get());
539+
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000Z");
540+
}
541+
542+
{
543+
auto ty = timestamp(TimeUnit::MICRO, "-42:00");
544+
StringFormatter<TimestampType> formatter(ty.get());
545+
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000000Z");
546+
}
547+
548+
{
549+
auto ty = timestamp(TimeUnit::NANO, "Mars/Mariner_Valley");
550+
StringFormatter<TimestampType> formatter(ty.get());
551+
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000000000Z");
552+
}
525553
}
526554

527555
TEST(Formatting, Interval) {

python/pyarrow/tests/test_types.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,17 @@ def test_timestamp():
487487
pa.timestamp(invalid_unit)
488488

489489

490+
def test_timestamp_print():
491+
for unit in ('s', 'ms', 'us', 'ns'):
492+
for tz in ('UTC', 'Europe/Paris', 'Pacific/Marquesas',
493+
'Mars/Mariner_Valley', '-00:42', '+42:00'):
494+
ty = pa.timestamp(unit, tz=tz)
495+
arr = pa.array([0], ty)
496+
assert "Z" in str(arr)
497+
arr = pa.array([0], pa.timestamp(unit))
498+
assert "Z" not in str(arr)
499+
500+
490501
def test_time32_units():
491502
for valid_unit in ('s', 'ms'):
492503
ty = pa.time32(valid_unit)

0 commit comments

Comments
 (0)