1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 #pragma once
19 
20 // TODO(wesm): IR compilation does not have any include directories set
21 #include "../../arrow/vendored/datetime/date.h"
22 
23 // A point of time measured in millis since epoch.
24 class EpochTimePoint {
25  public:
EpochTimePoint(std::chrono::milliseconds millis_since_epoch)26   explicit EpochTimePoint(std::chrono::milliseconds millis_since_epoch)
27       : tp_(millis_since_epoch) {}
28 
EpochTimePoint(int64_t millis_since_epoch)29   explicit EpochTimePoint(int64_t millis_since_epoch)
30       : EpochTimePoint(std::chrono::milliseconds(millis_since_epoch)) {}
31 
TmYear()32   int TmYear() const { return static_cast<int>(YearMonthDay().year()) - 1900; }
33 
TmMon()34   int TmMon() const { return static_cast<unsigned int>(YearMonthDay().month()) - 1; }
35 
TmYday()36   int TmYday() const {
37     auto to_days = arrow_vendored::date::floor<arrow_vendored::date::days>(tp_);
38     auto first_day_in_year = arrow_vendored::date::sys_days{
39         YearMonthDay().year() / arrow_vendored::date::jan / 1};
40     return (to_days - first_day_in_year).count();
41   }
42 
TmMday()43   int TmMday() const { return static_cast<unsigned int>(YearMonthDay().day()); }
44 
TmWday()45   int TmWday() const {
46     auto to_days = arrow_vendored::date::floor<arrow_vendored::date::days>(tp_);
47     return (arrow_vendored::date::weekday{to_days} -  // NOLINT
48             arrow_vendored::date::Sunday)
49         .count();
50   }
51 
TmHour()52   int TmHour() const { return static_cast<int>(TimeOfDay().hours().count()); }
53 
TmMin()54   int TmMin() const { return static_cast<int>(TimeOfDay().minutes().count()); }
55 
TmSec()56   int TmSec() const {
57     // TODO(wesm): UNIX y2k issue on int=gdv_int32 platforms
58     return static_cast<int>(TimeOfDay().seconds().count());
59   }
60 
AddYears(int num_years)61   EpochTimePoint AddYears(int num_years) const {
62     auto ymd = YearMonthDay() + arrow_vendored::date::years(num_years);
63     return EpochTimePoint((arrow_vendored::date::sys_days{ymd} +  // NOLINT
64                            TimeOfDay().to_duration())
65                               .time_since_epoch());
66   }
67 
AddMonths(int num_months)68   EpochTimePoint AddMonths(int num_months) const {
69     auto ymd = YearMonthDay() + arrow_vendored::date::months(num_months);
70     return EpochTimePoint((arrow_vendored::date::sys_days{ymd} +  // NOLINT
71                            TimeOfDay().to_duration())
72                               .time_since_epoch());
73   }
74 
AddDays(int num_days)75   EpochTimePoint AddDays(int num_days) const {
76     auto days_since_epoch = arrow_vendored::date::sys_days{YearMonthDay()} +  // NOLINT
77                             arrow_vendored::date::days(num_days);
78     return EpochTimePoint(
79         (days_since_epoch + TimeOfDay().to_duration()).time_since_epoch());
80   }
81 
ClearTimeOfDay()82   EpochTimePoint ClearTimeOfDay() const {
83     return EpochTimePoint((tp_ - TimeOfDay().to_duration()).time_since_epoch());
84   }
85 
86   bool operator==(const EpochTimePoint& other) const { return tp_ == other.tp_; }
87 
MillisSinceEpoch()88   int64_t MillisSinceEpoch() const { return tp_.time_since_epoch().count(); }
89 
90  private:
YearMonthDay()91   arrow_vendored::date::year_month_day YearMonthDay() const {
92     return arrow_vendored::date::year_month_day{
93         arrow_vendored::date::floor<arrow_vendored::date::days>(tp_)};  // NOLINT
94   }
95 
TimeOfDay()96   arrow_vendored::date::time_of_day<std::chrono::milliseconds> TimeOfDay() const {
97     auto millis_since_midnight =
98         tp_ - arrow_vendored::date::floor<arrow_vendored::date::days>(tp_);
99     return arrow_vendored::date::time_of_day<std::chrono::milliseconds>(
100         millis_since_midnight);
101   }
102 
103   std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp_;
104 };
105