I realised I can use system_clock::time_point in my rows tuple
with the following ctype/conversion traits.

namespace arrow {
template <>
struct CTypeTraits<time_point<system_clock>> {
    using ArrowType = ::arrow::TimestampType;

    static std::shared_ptr<::arrow::DataType> type_singleton() {
        return ::arrow::timestamp(::arrow::TimeUnit::NANO);
    }
};
}

namespace arrow::stl {
template <>
struct ConversionTraits<time_point<system_clock>>
    : public CTypeTraits<time_point<system_clock>> {
    constexpr static bool nullable = false;

    static Status AppendRow(
        typename TypeTraits<TimestampType>::BuilderType& builder,
        time_point<system_clock> cell) {
        return builder.Append(
            duration_cast<nanoseconds>(cell.time_since_epoch()).count());
    }

    static time_point<system_clock> GetEntry(const TimestampArray& array,
                                             size_t j) {
        return time_point<system_clock>(nanoseconds(array.Value(j)));
    }
};
}

On Sun, 7 Apr 2024 at 22:47, Blair Azzopardi <[email protected]> wrote:

> Hi
>
> What timestamp type can I use when converting a table to a tuple (& vice
> versa)? I seem to have ended up with the c_type but this doesn't round
> trip. I'm wondering if I need to implement a ConversionTraits
> specialization. Also are there any existing helper functions for converting
> between arrow timestamp types and chrono time_points?
>
> The following snippet :
>
> inline Status Main() {
>     auto read_options = json::ReadOptions::Defaults();
>     auto parse_options = json::ParseOptions::Defaults();
>     parse_options.unexpected_field_behavior =
>         json::UnexpectedFieldBehavior::InferType;
>
>     std::string json1 =
>         R"({"a": 2.0, "b": "foo", "c": "2020-01-01"}
>     {"a": -5.5, "b": null, "c": "2020-01-02"}
>     )";
>     ARROW_ASSIGN_OR_RAISE(auto tab1,
>                           ReadToTable(json1, read_options, parse_options));
>     cout << tab1->ToString() << endl;
>
>     // what should i use for my timestamp type to ensure round trip?
>     vector<tuple<double, string, TimestampType::c_type>> rows(2);
>
>     compute::ExecContext ctx;
>     compute::CastOptions cast_options;
>     if (!stl::TupleRangeFromTable(*tab1, cast_options, &ctx, &rows).ok()) {
>         throw runtime_error("Failed to convert table to tuple range");
>     }
>
>     shared_ptr<Table> tab2;
>     vector<string> names = {"A", "B", "C"};
>     if (!stl::TableFromTupleRange(default_memory_pool(), rows, names,
> &tab2)
>              .ok()) {
>         throw runtime_error("Failed to convert tuple vector to table");
>     }
>     cout << tab2->ToString() << endl;
>
>     return Status::OK();
> }
>
> outputs:
>
> a: double
> b: string
> c: timestamp[s]
> ----
> a:[[2, -5.5]]
> b:[["foo", null]]
> c:[[2020-01-01 00:00:00, 2020-01-02 00:00:00]]
>
> A: double not null
> B: string not null
> C: int64 not null
> ----
> A:[[2, -5.5]]
> B:[["foo", ""]]
> C:[[1577836800, 1577923200]]
>
> Ignoring null vs not-nulls, you can see the column c are integers.
>
> Thanks in advance!
>

Reply via email to