| /** |
| * 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. |
| **/ |
| |
| #ifndef QUICKSTEP_TYPES_DATETIME_LIT_HPP_ |
| #define QUICKSTEP_TYPES_DATETIME_LIT_HPP_ |
| |
| #include <cstdint> |
| #include <ctime> |
| #include <limits> |
| |
| #include "types/port/gmtime_r.hpp" |
| |
| namespace quickstep { |
| |
| /** \addtogroup Types |
| * @{ |
| */ |
| |
| /** |
| * @brief A literal representing the date. |
| **/ |
| struct DateLit { |
| // Note that although there is no year 0 in the Gregorian calendar, ISO 8601 |
| // has year 0 equivalent to 1 BCE, year -1 equivalent to 2 BCE, and so on. |
| std::int32_t year; |
| std::uint8_t month, day; |
| |
| // The maximum number of characters needed to represent any date in ISO 8601 |
| // notation. |
| static constexpr int kIsoChars |
| = 1 // + or - prefix |
| + 5 // Year digits |
| + 1 // - |
| + 2 // Month |
| + 1 // - |
| + 2; // Day |
| |
| static DateLit Create(const std::int32_t _year, |
| const std::uint8_t _month, |
| const std::uint8_t _day) { |
| DateLit date; |
| date.year = _year; |
| date.month = _month; |
| date.day = _day; |
| |
| return date; |
| } |
| |
| inline bool operator< (const DateLit& rhs) const { |
| return (year != rhs.year) |
| ? (year < rhs.year) |
| : ((month != rhs.month) ? (month < rhs.month) : (day < rhs.day)); |
| } |
| |
| inline bool operator> (const DateLit& rhs) const { |
| return (year != rhs.year) |
| ? (year > rhs.year) |
| : ((month != rhs.month) ? (month > rhs.month) : (day > rhs.day)); |
| } |
| |
| inline bool operator<=(const DateLit& rhs) const { |
| return !(*this > rhs); |
| } |
| |
| inline bool operator>=(const DateLit& rhs) const { |
| return !(*this < rhs); |
| } |
| |
| inline bool operator==(const DateLit& rhs) const { |
| return (year == rhs.year) && |
| (month == rhs.month) && |
| (day == rhs.day); |
| } |
| |
| inline bool operator!=(const DateLit& rhs) const { |
| return !(*this == rhs); |
| } |
| |
| inline std::int32_t yearField() const { |
| return year; |
| } |
| |
| inline std::int32_t monthField() const { |
| return static_cast<std::int32_t>(month); |
| } |
| }; |
| |
| /** |
| * @brief A literal representing the datetime. |
| **/ |
| struct DatetimeLit { |
| std::int64_t ticks; // Ticks in GMT. |
| |
| static constexpr std::int64_t kTicksPerSecond = INT64_C(1000000); |
| |
| // The maximum number of characters needed to represent any date in ISO 8601 |
| // notation. |
| static constexpr int kIsoChars |
| = 1 // + or - prefix |
| + std::numeric_limits<std::int64_t>::digits10 // Year digits |
| + 1 // - |
| + 2 // Month |
| + 1 // - |
| + 2 // Day |
| + 1 // T |
| + 2 // Hour |
| + 1 // : |
| + 2 // Minute |
| + 1 // : |
| + 2 // Second |
| + 1 // . |
| + 6; // Subseconds |
| |
| static DatetimeLit FromEpochTime(const std::time_t t) { |
| DatetimeLit datetime; |
| datetime.ticks = static_cast<std::int64_t>(t) * kTicksPerSecond; |
| return datetime; |
| } |
| |
| static DatetimeLit FromEpochTimePlusSubseconds(const std::time_t t, |
| const std::int64_t subseconds) { |
| return DatetimeLit{static_cast<std::int64_t>(t) * kTicksPerSecond + subseconds}; |
| } |
| |
| inline std::int64_t yearField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return (timeinfo.tm_year + 1900); |
| } |
| |
| inline std::int64_t monthField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return (timeinfo.tm_mon + 1); |
| } |
| |
| inline std::int64_t dayField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return timeinfo.tm_mday; |
| } |
| |
| inline std::int64_t hourField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return timeinfo.tm_hour; |
| } |
| |
| inline std::int64_t minuteField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return timeinfo.tm_min; |
| } |
| |
| inline std::int64_t secondField() const { |
| const std::time_t timestamp = epochTime(); |
| struct tm timeinfo; |
| quickstep::gmtime_r(×tamp, &timeinfo); |
| return timeinfo.tm_sec; |
| } |
| |
| inline std::time_t epochTime() const { |
| return static_cast<std::time_t>(ticks / kTicksPerSecond); |
| } |
| |
| inline std::int64_t subseconds() const { |
| return ticks % kTicksPerSecond; |
| } |
| |
| inline bool operator< (const DatetimeLit& rhs) const { |
| return ticks < rhs.ticks; |
| } |
| |
| inline bool operator> (const DatetimeLit& rhs) const { |
| return ticks > rhs.ticks; |
| } |
| |
| inline bool operator<=(const DatetimeLit& rhs) const { |
| return ticks <= rhs.ticks; |
| } |
| |
| inline bool operator>=(const DatetimeLit& rhs) const { |
| return ticks >= rhs.ticks; |
| } |
| |
| inline bool operator==(const DatetimeLit& rhs) const { |
| return ticks == rhs.ticks; |
| } |
| |
| inline bool operator!=(const DatetimeLit& rhs) const { |
| return ticks != rhs.ticks; |
| } |
| }; |
| |
| /** @} */ |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_TYPES_DATETIME_LIT_HPP_ |