blob: e239ccdfbcbca561d4d10d17e92d5957c4eda8d2 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -08002/**
Davide Pesaventoe6e6fde2016-04-16 14:44:45 +02003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -080020 */
21
22#ifndef NDN_TIME_HPP
23#define NDN_TIME_HPP
24
Alexander Afanasyev19508852014-01-29 01:01:51 -080025#include "../common.hpp"
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070026#include <boost/chrono.hpp>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080027#include <boost/asio/time_traits.hpp>
28#include <boost/date_time/posix_time/posix_time_types.hpp>
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -080029
30namespace ndn {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080031namespace time {
32
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070033using boost::chrono::duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080034
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070035typedef duration<boost::int_least32_t, boost::ratio<86400> > days;
36using boost::chrono::hours;
37using boost::chrono::minutes;
38using boost::chrono::seconds;
39
40using boost::chrono::milliseconds;
41using boost::chrono::microseconds;
42using boost::chrono::nanoseconds;
43
44using boost::chrono::duration_cast;
45
Junxiao Shidc2d6d22016-08-04 14:30:23 +000046/** \return the absolute value of the duration d
47 * \note The function does not participate in the overload resolution
48 * unless std::numeric_limits<Rep>::is_signed is true.
49 */
50template<typename Rep, typename Period,
Junxiao Shi5537d132016-08-05 03:48:01 +000051 typename = typename std::enable_if<std::numeric_limits<Rep>::is_signed>::type>
Junxiao Shidc2d6d22016-08-04 14:30:23 +000052constexpr duration<Rep, Period>
53abs(duration<Rep, Period> d)
54{
55 return d >= d.zero() ? d : -d;
56}
57
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070058/**
59 * \brief System clock
60 *
61 * System clock represents the system-wide real time wall clock.
62 *
63 * It may not be monotonic: on most systems, the system time can be
64 * adjusted at any moment. It is the only clock that has the ability
65 * to be displayed and converted to/from UNIX timestamp.
66 *
67 * To get current TimePoint:
68 *
69 * <code>
70 * system_clock::TimePoint now = system_clock::now();
71 * </code>
72 *
73 * To convert TimePoint to/from UNIX timestamp:
74 *
75 * <code>
76 * system_clock::TimePoint time = ...;
77 * uint64_t timestampInMilliseconds = toUnixTimestamp(time).count();
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080078 * system_clock::TimePoint time2 = fromUnixTimestamp(milliseconds(timestampInMilliseconds));
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070079 * </code>
Alexander Afanasyevf6468892014-01-29 01:04:14 -080080 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080081class system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080082{
83public:
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080084 typedef BOOST_SYSTEM_CLOCK_DURATION duration;
85 typedef duration::rep rep;
86 typedef duration::period period;
87 typedef boost::chrono::time_point<system_clock> time_point;
88 static constexpr bool is_steady = false;
89
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090 typedef time_point TimePoint;
91 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080092
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080093 static time_point
94 now() noexcept;
95
96 static std::time_t
97 to_time_t(const time_point& t) noexcept;
98
99 static time_point
100 from_time_t(std::time_t t) noexcept;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700101}; // class system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800102
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700103/**
104 * \brief Steady clock
105 *
106 * Steady clock represents a monotonic clock. The time points of this
107 * clock cannot decrease as physical time moves forward. This clock is
108 * not related to wall clock time, and is best suitable for measuring
109 * intervals.
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800110 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800111class steady_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800112{
113public:
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800114 typedef nanoseconds duration;
115 typedef duration::rep rep;
116 typedef duration::period period;
117 typedef boost::chrono::time_point<steady_clock> time_point;
118 static constexpr bool is_steady = true;
119
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700120 typedef time_point TimePoint;
121 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800122
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800123 static time_point
124 now() noexcept;
125
126private:
127 /**
128 * \brief Method to be used in deadline timer to select proper waiting
129 *
130 * Mock time implementations should return minimum value to ensure Boost.Asio
131 * is not enabling any waiting on mock timers.
132 *
133 * @sa http://stackoverflow.com/questions/14191855/how-do-you-mock-the-time-for-boost-timers
134 */
135 static boost::posix_time::time_duration
136 to_posix_duration(const duration& duration);
137
138 friend struct boost::asio::time_traits<steady_clock>;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700139}; // class steady_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800140
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800141
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700142/**
143 * \brief Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970)
144 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800145const system_clock::TimePoint&
146getUnixEpoch();
Yingdi Yuf2a82092014-02-03 16:49:15 -0800147
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800148/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149 * \brief Convert system_clock::TimePoint to UNIX timestamp
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800150 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800151milliseconds
152toUnixTimestamp(const system_clock::TimePoint& point);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800153
154/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700155 * \brief Convert UNIX timestamp to system_clock::TimePoint
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800156 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800157system_clock::TimePoint
158fromUnixTimestamp(const milliseconds& duration);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800159
160/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700161 * \brief Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
162 *
163 * If timePoint contains doesn't contain fractional seconds the
164 * output format is YYYYMMDDTHHMMSS
165 *
166 * Examples:
167 *
168 * - with fractional nanoseconds: 20020131T100001,123456789
169 * - with fractional microseconds: 20020131T100001,123456
170 * - with fractional milliseconds: 20020131T100001,123
171 * - without fractional seconds: 20020131T100001
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800172 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700173std::string
174toIsoString(const system_clock::TimePoint& timePoint);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800175
176/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700177 * \brief Convert from the ISO string (YYYYMMDDTHHMMSS,fffffffff) representation
178 * to the internal time format
179 *
180 * Examples of accepted ISO strings:
181 *
182 * - with fractional nanoseconds: 20020131T100001,123456789
183 * - with fractional microseconds: 20020131T100001,123456
184 * - with fractional milliseconds: 20020131T100001,123
185 * - without fractional seconds: 20020131T100001
186 *
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800187 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700188system_clock::TimePoint
189fromIsoString(const std::string& isoString);
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700190
191/**
192 * \brief Convert time point to string with specified format
193 *
194 * By default, `%Y-%m-%d %H:%M:%S` is used, producing dates like
195 * `2014-04-10 22:51:00`
196 *
197 * \param timePoint time point of system_clock
198 * \param format desired output format (default: `%Y-%m-%d %H:%M:%S`)
199 * \param locale desired locale (default: "C" locale)
200 *
Davide Pesaventoe6e6fde2016-04-16 14:44:45 +0200201 * \sa http://www.boost.org/doc/libs/1_54_0/doc/html/date_time/date_time_io.html#date_time.format_flags
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700202 * described possible formatting flags
203 **/
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700204std::string
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700205toString(const system_clock::TimePoint& timePoint,
206 const std::string& format = "%Y-%m-%d %H:%M:%S",
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700207 const std::locale& locale = std::locale("C"));
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700208
209/**
210 * \brief Convert from string of specified format into time point
211 *
212 * By default, `%Y-%m-%d %H:%M:%S` is used, accepting dates like
213 * `2014-04-10 22:51:00`
214 *
215 * \param formattedTimePoint string representing time point
216 * \param format input output format (default: `%Y-%m-%d %H:%M:%S`)
217 * \param locale input locale (default: "C" locale)
218 *
Davide Pesaventoe6e6fde2016-04-16 14:44:45 +0200219 * \sa http://www.boost.org/doc/libs/1_54_0/doc/html/date_time/date_time_io.html#date_time.format_flags
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700220 * described possible formatting flags
221 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700222system_clock::TimePoint
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700223fromString(const std::string& formattedTimePoint,
224 const std::string& format = "%Y-%m-%d %H:%M:%S",
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700225 const std::locale& locale = std::locale("C"));
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800226
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800227
228////////////////////////////////////////////////////////////////////////////////
229
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800230} // namespace time
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -0800231} // namespace ndn
232
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800233namespace boost {
234namespace chrono {
235
236template<class CharT>
237struct clock_string<ndn::time::system_clock, CharT>
238{
239 static std::basic_string<CharT>
240 since();
241};
242
243template<class CharT>
244struct clock_string<ndn::time::steady_clock, CharT>
245{
246 static std::basic_string<CharT>
247 since();
248};
249
250} // namespace chrono
251} // namespace boost
252
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -0800253#endif // NDN_TIME_HPP