blob: 976a27b9d7bffd790cb65bd462f8be8db4b8260f [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
46/**
47 * \brief System clock
48 *
49 * System clock represents the system-wide real time wall clock.
50 *
51 * It may not be monotonic: on most systems, the system time can be
52 * adjusted at any moment. It is the only clock that has the ability
53 * to be displayed and converted to/from UNIX timestamp.
54 *
55 * To get current TimePoint:
56 *
57 * <code>
58 * system_clock::TimePoint now = system_clock::now();
59 * </code>
60 *
61 * To convert TimePoint to/from UNIX timestamp:
62 *
63 * <code>
64 * system_clock::TimePoint time = ...;
65 * uint64_t timestampInMilliseconds = toUnixTimestamp(time).count();
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080066 * system_clock::TimePoint time2 = fromUnixTimestamp(milliseconds(timestampInMilliseconds));
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070067 * </code>
Alexander Afanasyevf6468892014-01-29 01:04:14 -080068 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080069class system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080070{
71public:
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080072 typedef BOOST_SYSTEM_CLOCK_DURATION duration;
73 typedef duration::rep rep;
74 typedef duration::period period;
75 typedef boost::chrono::time_point<system_clock> time_point;
76 static constexpr bool is_steady = false;
77
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070078 typedef time_point TimePoint;
79 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080080
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080081 static time_point
82 now() noexcept;
83
84 static std::time_t
85 to_time_t(const time_point& t) noexcept;
86
87 static time_point
88 from_time_t(std::time_t t) noexcept;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070089}; // class system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080090
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070091/**
92 * \brief Steady clock
93 *
94 * Steady clock represents a monotonic clock. The time points of this
95 * clock cannot decrease as physical time moves forward. This clock is
96 * not related to wall clock time, and is best suitable for measuring
97 * intervals.
Alexander Afanasyevf6468892014-01-29 01:04:14 -080098 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080099class steady_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800100{
101public:
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800102 typedef nanoseconds duration;
103 typedef duration::rep rep;
104 typedef duration::period period;
105 typedef boost::chrono::time_point<steady_clock> time_point;
106 static constexpr bool is_steady = true;
107
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700108 typedef time_point TimePoint;
109 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800110
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800111 static time_point
112 now() noexcept;
113
114private:
115 /**
116 * \brief Method to be used in deadline timer to select proper waiting
117 *
118 * Mock time implementations should return minimum value to ensure Boost.Asio
119 * is not enabling any waiting on mock timers.
120 *
121 * @sa http://stackoverflow.com/questions/14191855/how-do-you-mock-the-time-for-boost-timers
122 */
123 static boost::posix_time::time_duration
124 to_posix_duration(const duration& duration);
125
126 friend struct boost::asio::time_traits<steady_clock>;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700127}; // class steady_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800128
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800129
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700130/**
131 * \brief Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970)
132 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800133const system_clock::TimePoint&
134getUnixEpoch();
Yingdi Yuf2a82092014-02-03 16:49:15 -0800135
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800136/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700137 * \brief Convert system_clock::TimePoint to UNIX timestamp
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800138 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800139milliseconds
140toUnixTimestamp(const system_clock::TimePoint& point);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800141
142/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700143 * \brief Convert UNIX timestamp to system_clock::TimePoint
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800144 */
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800145system_clock::TimePoint
146fromUnixTimestamp(const milliseconds& duration);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800147
148/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149 * \brief Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
150 *
151 * If timePoint contains doesn't contain fractional seconds the
152 * output format is YYYYMMDDTHHMMSS
153 *
154 * Examples:
155 *
156 * - with fractional nanoseconds: 20020131T100001,123456789
157 * - with fractional microseconds: 20020131T100001,123456
158 * - with fractional milliseconds: 20020131T100001,123
159 * - without fractional seconds: 20020131T100001
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800160 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700161std::string
162toIsoString(const system_clock::TimePoint& timePoint);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800163
164/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700165 * \brief Convert from the ISO string (YYYYMMDDTHHMMSS,fffffffff) representation
166 * to the internal time format
167 *
168 * Examples of accepted ISO strings:
169 *
170 * - with fractional nanoseconds: 20020131T100001,123456789
171 * - with fractional microseconds: 20020131T100001,123456
172 * - with fractional milliseconds: 20020131T100001,123
173 * - without fractional seconds: 20020131T100001
174 *
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800175 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700176system_clock::TimePoint
177fromIsoString(const std::string& isoString);
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700178
179/**
180 * \brief Convert time point to string with specified format
181 *
182 * By default, `%Y-%m-%d %H:%M:%S` is used, producing dates like
183 * `2014-04-10 22:51:00`
184 *
185 * \param timePoint time point of system_clock
186 * \param format desired output format (default: `%Y-%m-%d %H:%M:%S`)
187 * \param locale desired locale (default: "C" locale)
188 *
Davide Pesaventoe6e6fde2016-04-16 14:44:45 +0200189 * \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 -0700190 * described possible formatting flags
191 **/
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700192std::string
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700193toString(const system_clock::TimePoint& timePoint,
194 const std::string& format = "%Y-%m-%d %H:%M:%S",
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700195 const std::locale& locale = std::locale("C"));
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700196
197/**
198 * \brief Convert from string of specified format into time point
199 *
200 * By default, `%Y-%m-%d %H:%M:%S` is used, accepting dates like
201 * `2014-04-10 22:51:00`
202 *
203 * \param formattedTimePoint string representing time point
204 * \param format input output format (default: `%Y-%m-%d %H:%M:%S`)
205 * \param locale input locale (default: "C" locale)
206 *
Davide Pesaventoe6e6fde2016-04-16 14:44:45 +0200207 * \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 -0700208 * described possible formatting flags
209 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700210system_clock::TimePoint
Alexander Afanasyev53af7a12014-04-10 23:35:28 -0700211fromString(const std::string& formattedTimePoint,
212 const std::string& format = "%Y-%m-%d %H:%M:%S",
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700213 const std::locale& locale = std::locale("C"));
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800214
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800215
216////////////////////////////////////////////////////////////////////////////////
217
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800218} // namespace time
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -0800219} // namespace ndn
220
Alexander Afanasyev85b17b82014-11-10 16:22:05 -0800221namespace boost {
222namespace chrono {
223
224template<class CharT>
225struct clock_string<ndn::time::system_clock, CharT>
226{
227 static std::basic_string<CharT>
228 since();
229};
230
231template<class CharT>
232struct clock_string<ndn::time::steady_clock, CharT>
233{
234 static std::basic_string<CharT>
235 since();
236};
237
238} // namespace chrono
239} // namespace boost
240
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -0800241#endif // NDN_TIME_HPP