blob: 58c852f057b2e886cbaa0ce895e46935fff5c8ed [file] [log] [blame]
/**
* 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(&timestamp, &timeinfo);
return (timeinfo.tm_year + 1900);
}
inline std::int64_t monthField() const {
const std::time_t timestamp = epochTime();
struct tm timeinfo;
quickstep::gmtime_r(&timestamp, &timeinfo);
return (timeinfo.tm_mon + 1);
}
inline std::int64_t dayField() const {
const std::time_t timestamp = epochTime();
struct tm timeinfo;
quickstep::gmtime_r(&timestamp, &timeinfo);
return timeinfo.tm_mday;
}
inline std::int64_t hourField() const {
const std::time_t timestamp = epochTime();
struct tm timeinfo;
quickstep::gmtime_r(&timestamp, &timeinfo);
return timeinfo.tm_hour;
}
inline std::int64_t minuteField() const {
const std::time_t timestamp = epochTime();
struct tm timeinfo;
quickstep::gmtime_r(&timestamp, &timeinfo);
return timeinfo.tm_min;
}
inline std::int64_t secondField() const {
const std::time_t timestamp = epochTime();
struct tm timeinfo;
quickstep::gmtime_r(&timestamp, &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_