time.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2017 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  */
21 
22 #include "time.hpp"
23 #include "time-custom-clock.hpp"
24 
25 #include <boost/date_time/posix_time/posix_time.hpp>
26 #include <sstream>
27 
28 namespace ndn {
29 namespace time {
30 
31 static shared_ptr<CustomSystemClock> g_systemClock;
32 static shared_ptr<CustomSteadyClock> g_steadyClock;
33 
34 // this method is defined in time-custom-clock.hpp
35 void
36 setCustomClocks(shared_ptr<CustomSteadyClock> steadyClock,
37  shared_ptr<CustomSystemClock> systemClock)
38 {
39  g_systemClock = systemClock;
40  g_steadyClock = steadyClock;
41 }
42 
44 
47 {
48  if (g_systemClock == nullptr) {
49  // optimized default version
50  return time_point(boost::chrono::system_clock::now().time_since_epoch());
51  }
52  else {
53  return g_systemClock->getNow();
54  }
55 }
56 
57 std::time_t
59 {
60  return duration_cast<seconds>(t.time_since_epoch()).count();
61 }
62 
64 system_clock::from_time_t(std::time_t t) noexcept
65 {
66  return time_point(seconds(t));
67 }
68 
70 
71 #ifdef __APPLE__
72  // Note that on OS X platform boost::steady_clock is not truly monotonic, so we use
73  // system_clock instead. Refer to https://svn.boost.org/trac/boost/ticket/7719)
74  typedef boost::chrono::system_clock base_steady_clock;
75 #else
76  typedef boost::chrono::steady_clock base_steady_clock;
77 #endif
78 
81 {
82  if (g_steadyClock == nullptr) {
83  // optimized default version
84  return time_point(base_steady_clock::now().time_since_epoch());
85  }
86  else {
87  return g_steadyClock->getNow();
88  }
89 }
90 
91 boost::posix_time::time_duration
92 steady_clock::to_posix_duration(const duration& duration)
93 {
94  if (g_steadyClock == nullptr) {
95  // optimized default version
96  return
97 #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
98  boost::posix_time::nanoseconds(duration_cast<nanoseconds>(duration).count())
99 #else
100  boost::posix_time::microseconds(duration_cast<microseconds>(duration).count())
101 #endif
102  ;
103  }
104  else {
105  return g_steadyClock->toPosixDuration(duration);
106  }
107 }
108 
110 
113 {
115  return epoch;
116 }
117 
118 milliseconds
120 {
121  return duration_cast<milliseconds>(point - getUnixEpoch());
122 }
123 
125 fromUnixTimestamp(const milliseconds& duration)
126 {
127  return getUnixEpoch() + duration;
128 }
129 
130 std::string
132 {
133  namespace bpt = boost::posix_time;
134  static bpt::ptime epoch(boost::gregorian::date(1970, 1, 1));
135 
136 #ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
137  using BptResolutionUnit = nanoseconds;
138 #else
139  using BptResolutionUnit = microseconds;
140 #endif
141  constexpr auto unitsPerHour = duration_cast<BptResolutionUnit>(hours(1)).count();
142 
143  auto sinceEpoch = duration_cast<BptResolutionUnit>(timePoint - getUnixEpoch()).count();
144  bpt::ptime ptime = epoch + bpt::time_duration(sinceEpoch / unitsPerHour, 0, 0,
145  sinceEpoch % unitsPerHour);
146 
147  return bpt::to_iso_string(ptime);
148 }
149 
150 
152 fromIsoString(const std::string& isoString)
153 {
154  namespace bpt = boost::posix_time;
155  static bpt::ptime posixTimeEpoch = bpt::from_time_t(0);
156 
157  bpt::ptime ptime = bpt::from_iso_string(isoString);
158 
160  system_clock::from_time_t((ptime - posixTimeEpoch).total_seconds());
161  point += microseconds((ptime - posixTimeEpoch).total_microseconds() % 1000000);
162  return point;
163 }
164 
165 
166 std::string
168  const std::string& format/* = "%Y-%m-%d %H:%M:%S"*/,
169  const std::locale& locale/* = std::locale("C")*/)
170 {
171  namespace bpt = boost::posix_time;
172  bpt::ptime ptime = bpt::from_time_t(system_clock::to_time_t(timePoint));
173 
174  uint64_t micro = duration_cast<microseconds>(timePoint - getUnixEpoch()).count() % 1000000;
175  ptime += bpt::microseconds(micro);
176 
177  bpt::time_facet* facet = new bpt::time_facet(format.c_str());
178  std::ostringstream formattedTimePoint;
179  formattedTimePoint.imbue(std::locale(locale, facet));
180  formattedTimePoint << ptime;
181 
182  return formattedTimePoint.str();
183 }
184 
185 
187 fromString(const std::string& formattedTimePoint,
188  const std::string& format/* = "%Y-%m-%d %H:%M:%S"*/,
189  const std::locale& locale/* = std::locale("C")*/)
190 {
191  namespace bpt = boost::posix_time;
192  static bpt::ptime posixTimeEpoch = bpt::from_time_t(0);
193 
194  bpt::time_input_facet* facet = new bpt::time_input_facet(format);
195  std::istringstream is(formattedTimePoint);
196 
197  is.imbue(std::locale(locale, facet));
198  bpt::ptime ptime;
199  is >> ptime;
200 
202  system_clock::from_time_t((ptime - posixTimeEpoch).total_seconds());
203  point += microseconds((ptime - posixTimeEpoch).total_microseconds() % 1000000);
204  return point;
205 }
206 
207 } // namespace time
208 } // namespace ndn
209 
210 namespace boost {
211 namespace chrono {
212 
214 
215 template<class CharT>
216 std::basic_string<CharT>
217 clock_string<ndn::time::system_clock, CharT>::since()
218 {
219  if (ndn::time::g_systemClock == nullptr) {
220  // optimized default version
221  return clock_string<system_clock, CharT>::since();
222  }
223  else {
224  return ndn::time::g_systemClock->getSince();
225  }
226 }
227 
228 template
229 struct clock_string<ndn::time::system_clock, char>;
230 
232 
233 template<class CharT>
234 std::basic_string<CharT>
235 clock_string<ndn::time::steady_clock, CharT>::since()
236 {
237  if (ndn::time::g_steadyClock == nullptr) {
238  // optimized default version
239  return clock_string<ndn::time::base_steady_clock, CharT>::since();
240  }
241  else {
242  return ndn::time::g_steadyClock->getSince();
243  }
244 }
245 
246 template
247 struct clock_string<ndn::time::steady_clock, char>;
248 
249 } // namespace chrono
250 } // namespace boost
boost::chrono::time_point< system_clock > time_point
Definition: time.hpp:87
boost::chrono::time_point< steady_clock > time_point
Definition: time.hpp:117
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
system_clock::TimePoint fromIsoString(const std::string &isoString)
Convert from the ISO string (YYYYMMDDTHHMMSS,fffffffff) representation to the internal time format...
Definition: time.cpp:152
Copyright (c) 2013-2017 Regents of the University of California.
Definition: block.hpp:31
BOOST_SYSTEM_CLOCK_DURATION duration
Definition: time.hpp:84
static time_point now() noexcept
Definition: time.cpp:80
static std::time_t to_time_t(const time_point &t) noexcept
Definition: time.cpp:58
nanoseconds duration
Definition: time.hpp:114
static time_point now() noexcept
Definition: time.cpp:46
std::string toString(const system_clock::TimePoint &timePoint, const std::string &format, const std::locale &locale)
Convert time point to string with specified format.
Definition: time.cpp:167
boost::chrono::steady_clock base_steady_clock
Definition: time.cpp:76
system_clock::TimePoint fromString(const std::string &formattedTimePoint, const std::string &format, const std::locale &locale)
Convert from string of specified format into time point.
Definition: time.cpp:187
std::string toIsoString(const system_clock::TimePoint &timePoint)
Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
Definition: time.cpp:131
void setCustomClocks(shared_ptr< CustomSteadyClock > steadyClock=nullptr, shared_ptr< CustomSystemClock > systemClock=nullptr)
Set custom system and steady clocks.
Definition: time.cpp:36
time_point TimePoint
Definition: time.hpp:90
static shared_ptr< CustomSteadyClock > g_steadyClock
Definition: time.cpp:32
system_clock::TimePoint fromUnixTimestamp(const milliseconds &duration)
Convert UNIX timestamp to system_clock::TimePoint.
Definition: time.cpp:125
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
Definition: time.cpp:119
static shared_ptr< CustomSystemClock > g_systemClock
Definition: time.cpp:31
static time_point from_time_t(std::time_t t) noexcept
Definition: time.cpp:64
const system_clock::TimePoint & getUnixEpoch()
Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970) ...
Definition: time.cpp:112