blob: afcb97939eb31f8493edf3f6a53f4c60afc7afef [file] [log] [blame]
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -08001/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -07002 * Copyright (C) 2013-2014 Regents of the University of California.
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -08003 * See COPYING for copyright and distribution information.
4 */
5
6#ifndef NDN_TIME_HPP
7#define NDN_TIME_HPP
8
Alexander Afanasyev19508852014-01-29 01:01:51 -08009#include "../common.hpp"
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070010#include <boost/chrono.hpp>
11#include <boost/date_time/posix_time/posix_time.hpp>
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -080012
13namespace ndn {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080014namespace time {
15
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070016using boost::chrono::duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080017
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070018typedef duration<boost::int_least32_t, boost::ratio<86400> > days;
19using boost::chrono::hours;
20using boost::chrono::minutes;
21using boost::chrono::seconds;
22
23using boost::chrono::milliseconds;
24using boost::chrono::microseconds;
25using boost::chrono::nanoseconds;
26
27using boost::chrono::duration_cast;
28
29/**
30 * \brief System clock
31 *
32 * System clock represents the system-wide real time wall clock.
33 *
34 * It may not be monotonic: on most systems, the system time can be
35 * adjusted at any moment. It is the only clock that has the ability
36 * to be displayed and converted to/from UNIX timestamp.
37 *
38 * To get current TimePoint:
39 *
40 * <code>
41 * system_clock::TimePoint now = system_clock::now();
42 * </code>
43 *
44 * To convert TimePoint to/from UNIX timestamp:
45 *
46 * <code>
47 * system_clock::TimePoint time = ...;
48 * uint64_t timestampInMilliseconds = toUnixTimestamp(time).count();
49 * system_clock::TimePoint time2 = fromUnixTimestamp(time::milliseconds(timestampInMilliseconds));
50 * </code>
Alexander Afanasyevf6468892014-01-29 01:04:14 -080051 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070052class system_clock : public boost::chrono::system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080053{
54public:
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070055 typedef time_point TimePoint;
56 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080057
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070058 // /// \brief Get current TimePoint
59 // TimePoint
60 // now();
61}; // class system_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080062
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070063/**
64 * \brief Steady clock
65 *
66 * Steady clock represents a monotonic clock. The time points of this
67 * clock cannot decrease as physical time moves forward. This clock is
68 * not related to wall clock time, and is best suitable for measuring
69 * intervals.
70 *
71 * Note that on OS X platform this defaults to system clock and is not
72 * truly monotonic. Refer to https://svn.boost.org/trac/boost/ticket/7719)
Alexander Afanasyevf6468892014-01-29 01:04:14 -080073 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070074class steady_clock : public
75#ifdef __APPLE__
76// steady_clock may go backwards on OS X platforms, so use system_clock
77// instead
78 boost::chrono::system_clock
79#else
80 boost::chrono::steady_clock
81#endif
Alexander Afanasyevf6468892014-01-29 01:04:14 -080082{
83public:
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070084 typedef time_point TimePoint;
85 typedef duration Duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080086
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087 // /// \brief Get current TimePoint
88 // TimePoint
89 // now();
90}; // class steady_clock
Alexander Afanasyevf6468892014-01-29 01:04:14 -080091
Alexander Afanasyevf6468892014-01-29 01:04:14 -080092
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070093/**
94 * \brief Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970)
95 */
96inline const system_clock::TimePoint&
97getUnixEpoch()
Yingdi Yuf2a82092014-02-03 16:49:15 -080098{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070099 static system_clock::TimePoint epoch = system_clock::from_time_t(0);
100 return epoch;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800101}
102
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800103/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700104 * \brief Convert system_clock::TimePoint to UNIX timestamp
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800105 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700106inline milliseconds
107toUnixTimestamp(const system_clock::TimePoint& point)
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800108{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700109 return duration_cast<milliseconds>(point - getUnixEpoch());
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800110}
111
112/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700113 * \brief Convert UNIX timestamp to system_clock::TimePoint
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800114 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700115inline system_clock::TimePoint
116fromUnixTimestamp(const milliseconds& duration)
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800117{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700118 return getUnixEpoch() + duration;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800119}
120
121/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700122 * \brief Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
123 *
124 * If timePoint contains doesn't contain fractional seconds the
125 * output format is YYYYMMDDTHHMMSS
126 *
127 * Examples:
128 *
129 * - with fractional nanoseconds: 20020131T100001,123456789
130 * - with fractional microseconds: 20020131T100001,123456
131 * - with fractional milliseconds: 20020131T100001,123
132 * - without fractional seconds: 20020131T100001
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800133 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700134inline std::string
135toIsoString(const system_clock::TimePoint& timePoint)
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800136{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700137 boost::posix_time::ptime ptime = boost::posix_time::from_time_t(
138 system_clock::TimePoint::clock::to_time_t(timePoint));
139
140 uint64_t micro = duration_cast<microseconds>(timePoint - getUnixEpoch()).count() % 1000000;
141 if (micro > 0)
142 {
143 ptime += boost::posix_time::microseconds(micro);
144 return boost::posix_time::to_iso_string(ptime);
145 }
146 else
147 return boost::posix_time::to_iso_string(ptime);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800148}
149
150/**
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700151 * \brief Convert from the ISO string (YYYYMMDDTHHMMSS,fffffffff) representation
152 * to the internal time format
153 *
154 * Examples of accepted ISO strings:
155 *
156 * - with fractional nanoseconds: 20020131T100001,123456789
157 * - with fractional microseconds: 20020131T100001,123456
158 * - with fractional milliseconds: 20020131T100001,123
159 * - without fractional seconds: 20020131T100001
160 *
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800161 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700162inline system_clock::TimePoint
163fromIsoString(const std::string& isoString)
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800164{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700165 static boost::posix_time::ptime posixTimeEpoch = boost::posix_time::from_time_t(0);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800166
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700167 boost::posix_time::ptime ptime = boost::posix_time::from_iso_string(isoString);
168
169 system_clock::TimePoint point = system_clock::from_time_t((ptime - posixTimeEpoch).total_seconds());
170 point += microseconds((ptime - posixTimeEpoch).total_microseconds() % 1000000);
171 return point;
172}
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800173
174} // namespace time
Alexander Afanasyeve2e3ca52014-01-03 13:59:07 -0800175} // namespace ndn
176
177#endif // NDN_TIME_HPP