netxsimdg
Loading...
Searching...
No Matches
Time.hpp
Go to the documentation of this file.
1
8#ifndef TIME_HPP
9#define TIME_HPP
10
11#include <array>
12#include <chrono>
13#include <ctime>
14#include <iomanip>
15#include <iostream>
16#include <sstream>
17
18namespace Nextsim {
19
21 enum TimeOption { USE_DOY, DAYS_360, COUNT };
22
23public:
24 static bool& useDOY() { return m_opt[USE_DOY]; }
25
26private:
27 static std::array<bool, COUNT> m_opt;
28};
29
30typedef std::chrono::system_clock SystemClock;
31typedef SystemClock::duration SystemDuration;
32
33class TimePoint;
34
35class Duration {
36public:
37 typedef SystemDuration Basis;
38 Duration()
39 : m_d()
40 {
41 }
42 Duration(const std::string& str);
43 Duration(double seconds);
44
45 TimePoint operator+(const TimePoint& t) const;
46
47 Duration& operator+=(const Duration& a)
48 {
49 m_d += a.m_d;
50 return *this;
51 }
52 Duration& operator-=(const Duration& a)
53 {
54 m_d -= a.m_d;
55 return *this;
56 }
57
58 Duration& operator*=(double a)
59 {
60 m_d *= a;
61 return *this;
62 }
63 Duration& operator/=(double a)
64 {
65 m_d /= a;
66 return *this;
67 }
68
69 Duration operator+(const Duration& a) const { return Duration(m_d + a.m_d); }
70 Duration operator-(const Duration& a) const { return Duration(m_d - a.m_d); }
71
72 double seconds() const { return std::chrono::duration_cast<std::chrono::seconds>(m_d).count(); }
73
74 std::istream& parse(std::istream& is);
75
76 Duration& parse(const std::string& str)
77 {
78 std::stringstream is(str);
79 parse(is);
80 return *this;
81 }
82
83 std::ostream& format(std::ostream& os) const { return os << seconds(); }
84
85 std::string format() const
86 {
87 std::stringstream ss;
88 format(ss);
89 return ss.str();
90 }
91
92 friend TimePoint;
93 friend Duration durationFromISO(const std::string&, int);
94
95private:
96 Duration(const Basis& d)
97 : m_d(d)
98 {
99 }
100 Basis m_d;
101 void setDurationSeconds(double);
102};
103
115std::time_t mkgmtime(std::tm* time, bool recalculateDoy = true);
116
123int julianGregorianShiftDays(int year);
124
130std::time_t timeFromISO(const std::string& iso);
136std::time_t timeFromISO(std::istream& is);
137
139public:
140 typedef SystemClock Clock;
141 typedef std::chrono::time_point<Clock, Duration::Basis> Basis;
142
143 TimePoint()
144 : m_t() {};
145 TimePoint(const std::string& str) { this->parse(str); }
146 TimePoint(const TimePoint&, const Duration&);
147
148 Duration operator-(const TimePoint& a) const { return Duration(m_t - a.m_t); }
149 TimePoint& operator+=(const Duration& d)
150 {
151 m_t += d.m_d;
152 return *this;
153 }
154 TimePoint& operator-=(const Duration& d)
155 {
156 m_t -= d.m_d;
157 return *this;
158 }
159 TimePoint operator+(const Duration& d) const
160 {
161 TimePoint t2(*this);
162 return t2 += d;
163 }
164
165 bool operator<=(const TimePoint& a) const { return m_t <= a.m_t; }
166 bool operator<(const TimePoint& a) const { return m_t < a.m_t; }
167 bool operator>=(const TimePoint& a) const { return m_t >= a.m_t; }
168 bool operator>(const TimePoint& a) const { return m_t > a.m_t; }
169 bool operator==(const TimePoint& a) const { return m_t == a.m_t; }
170 bool operator!=(const TimePoint& a) const { return m_t != a.m_t; }
171
172 std::istream& parse(std::istream& is)
173 {
174 auto fromTime = Clock::from_time_t(timeFromISO(is));
175 m_t = fromTime;
176 return is;
177 }
178
179 TimePoint& parse(const std::string& str)
180 {
181 std::stringstream is(str);
182 parse(is);
183 return *this;
184 }
185
186 std::ostream& format(std::ostream& os) const
187 {
188 // Temporary conversion from int to system_clock
189 auto tt = Clock::to_time_t(m_t);
190 os << std::put_time(std::gmtime(&tt), ymdhmsFormat.c_str());
191 return os;
192 }
193
194 std::string format() const
195 {
196 std::stringstream ss;
197 format(ss);
198 return ss.str();
199 }
200
201 std::tm* gmtime() const;
202
203 static const std::string ymdFormat;
204 static const std::string doyFormat;
205 static const std::string ymdhmsFormat;
206 static const std::string doyhmsFormat;
207 static const std::string hmsFormat;
208
209 friend Duration;
210
211private:
212 TimePoint(const Basis& t)
213 : m_t(t)
214 {
215 }
216 Basis m_t;
217};
218
220 TimePoint start;
221 Duration step;
222};
223
225public:
226 StartStepStop(TimePoint start, Duration step, TimePoint stop)
227 : m_start(start)
228 , m_step(step)
229 , m_stop(stop)
230 , m_last(start)
231 {
232 }
233
234 inline bool isIn(const TimePoint& query) { return query >= m_start && query < m_stop; }
235
236 inline bool doStep(const TimePoint& query)
237 {
238 if (m_last + m_step <= query) {
239 m_last += m_step;
240 return true;
241 }
242 return false;
243 }
244
245private:
246 TimePoint m_start;
247 Duration m_step;
248 TimePoint m_stop;
249 TimePoint m_last;
250};
251
252inline double operator*(double a, const Duration& b) { return a * b.seconds(); }
253inline double operator/(double a, const Duration& b) { return a / b.seconds(); }
254inline double operator*(const Duration& a, double b) { return b * a; }
255inline double operator/(const Duration& a, double b) { return a.seconds() / b; }
256
257inline std::istream& operator>>(std::istream& is, TimePoint& tp) { return tp.parse(is); }
258inline std::istream& operator>>(std::istream& is, Duration& dur) { return dur.parse(is); }
259inline std::ostream& operator<<(std::ostream& os, const TimePoint& tp) { return tp.format(os); }
260inline std::ostream& operator<<(std::ostream& os, const Duration& dur) { return dur.format(os); }
261
262}; // namespace Nextsim
263
264#endif /* TIME_HPP */
std::istream & operator>>(std::istream &, EnumWrapper< E > &)
A templated input operator that uses the defined map to set the value of the wrapped enum.
std::time_t timeFromISO(const std::string &iso)
Returns a std::time_t from a given ISO date string of a specific format.
Definition Time.cpp:144
int julianGregorianShiftDays(int year)
Returns the number of days between the Julian and Gregorian years.
Definition Time.cpp:60
std::time_t mkgmtime(std::tm *time, bool recalculateDoy=true)
converts the std::tm struct to a std::time_t value assuming UTC.
Definition Time.cpp:39