| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| #pragma once | |
| #include <chrono> | |
| #include <cstdint> | |
| #include "iceberg/util/temporal_util.h" | |
| namespace iceberg { | |
| using namespace std::chrono; // NOLINT | |
| struct DateParts { | |
| int32_t year{0}; | |
| uint8_t month{0}; | |
| uint8_t day{0}; | |
| }; | |
| struct TimeParts { | |
| int32_t hour{0}; | |
| int32_t minute{0}; | |
| int32_t second{0}; | |
| int32_t microsecond{0}; | |
| }; | |
| struct TimestampParts { | |
| int32_t year{0}; | |
| uint8_t month{0}; | |
| uint8_t day{0}; | |
| int32_t hour{0}; | |
| int32_t minute{0}; | |
| int32_t second{0}; | |
| int32_t microsecond{0}; | |
| // e.g. -480 for PST (UTC-8:00), +480 for Asia/Shanghai (UTC+8:00) | |
| int32_t tz_offset_minutes{0}; | |
| }; | |
| struct TimestampNanosParts { | |
| int32_t year{0}; | |
| uint8_t month{0}; | |
| uint8_t day{0}; | |
| int32_t hour{0}; | |
| int32_t minute{0}; | |
| int32_t second{0}; | |
| int32_t nanosecond{0}; | |
| // e.g. -480 for PST (UTC-8:00), +480 for Asia/Shanghai (UTC+8:00) | |
| int32_t tz_offset_minutes{0}; | |
| }; | |
| class TemporalTestHelper { | |
| public: | |
| /// \brief Construct a Calendar date without timezone or time | |
| static int32_t CreateDate(const DateParts& parts) { | |
| return static_cast<int32_t>( | |
| (sys_days(year{parts.year} / month{parts.month} / day{parts.day}) - | |
| internal::kEpochDays) | |
| .count()); | |
| } | |
| /// \brief Construct a time-of-day, microsecond precision, without date, timezone | |
| static int64_t CreateTime(const TimeParts& parts) { | |
| return duration_cast<microseconds>(hours(parts.hour) + minutes(parts.minute) + | |
| seconds(parts.second) + | |
| microseconds(parts.microsecond)) | |
| .count(); | |
| } | |
| /// \brief Construct a timestamp, microsecond precision, without timezone | |
| static int64_t CreateTimestamp(const TimestampParts& parts) { | |
| year_month_day ymd{year{parts.year}, month{parts.month}, day{parts.day}}; | |
| auto tp = sys_time<microseconds>{(sys_days(ymd) + hours{parts.hour} + | |
| minutes{parts.minute} + seconds{parts.second} + | |
| microseconds{parts.microsecond}) | |
| .time_since_epoch()}; | |
| return tp.time_since_epoch().count(); | |
| } | |
| /// \brief Construct a timestamp, microsecond precision, with timezone | |
| static int64_t CreateTimestampTz(const TimestampParts& parts) { | |
| year_month_day ymd{year{parts.year}, month{parts.month}, day{parts.day}}; | |
| auto tp = sys_time<microseconds>{(sys_days(ymd) + hours{parts.hour} + | |
| minutes{parts.minute} + seconds{parts.second} + | |
| microseconds{parts.microsecond} - | |
| minutes{parts.tz_offset_minutes}) | |
| .time_since_epoch()}; | |
| return tp.time_since_epoch().count(); | |
| } | |
| /// \brief Construct a timestamp, nanosecond precision, without timezone | |
| static int64_t CreateTimestampNanos(const TimestampNanosParts& parts) { | |
| year_month_day ymd{year{parts.year}, month{parts.month}, day{parts.day}}; | |
| auto tp = | |
| sys_time<nanoseconds>{(sys_days(ymd) + hours{parts.hour} + minutes{parts.minute} + | |
| seconds{parts.second} + nanoseconds{parts.nanosecond}) | |
| .time_since_epoch()}; | |
| return tp.time_since_epoch().count(); | |
| } | |
| /// \brief Construct a timestamp, nanosecond precision, with timezone | |
| static int64_t CreateTimestampTzNanos(const TimestampNanosParts& parts) { | |
| year_month_day ymd{year{parts.year}, month{parts.month}, day{parts.day}}; | |
| auto tp = | |
| sys_time<nanoseconds>{(sys_days(ymd) + hours{parts.hour} + minutes{parts.minute} + | |
| seconds{parts.second} + nanoseconds{parts.nanosecond} - | |
| minutes{parts.tz_offset_minutes}) | |
| .time_since_epoch()}; | |
| return tp.time_since_epoch().count(); | |
| } | |
| }; | |
| } // namespace iceberg |