blob: 3bc4e4f9287e1cbac7dddc79da5829190dba18f9 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
* Copyright (c) 2013-2014, Regents of the University of California.
* All rights reserved.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* This file licensed under New BSD License. See COPYING for detailed information about
* ndn-cxx library copyright, permissions, and redistribution restrictions.
*/
#ifndef NDN_TIME_HPP
#define NDN_TIME_HPP
#include "../common.hpp"
#include <boost/chrono.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace ndn {
namespace time {
using boost::chrono::duration;
typedef duration<boost::int_least32_t, boost::ratio<86400> > days;
using boost::chrono::hours;
using boost::chrono::minutes;
using boost::chrono::seconds;
using boost::chrono::milliseconds;
using boost::chrono::microseconds;
using boost::chrono::nanoseconds;
using boost::chrono::duration_cast;
/**
* \brief System clock
*
* System clock represents the system-wide real time wall clock.
*
* It may not be monotonic: on most systems, the system time can be
* adjusted at any moment. It is the only clock that has the ability
* to be displayed and converted to/from UNIX timestamp.
*
* To get current TimePoint:
*
* <code>
* system_clock::TimePoint now = system_clock::now();
* </code>
*
* To convert TimePoint to/from UNIX timestamp:
*
* <code>
* system_clock::TimePoint time = ...;
* uint64_t timestampInMilliseconds = toUnixTimestamp(time).count();
* system_clock::TimePoint time2 = fromUnixTimestamp(time::milliseconds(timestampInMilliseconds));
* </code>
*/
class system_clock : public boost::chrono::system_clock
{
public:
typedef time_point TimePoint;
typedef duration Duration;
// /// \brief Get current TimePoint
// TimePoint
// now();
}; // class system_clock
/**
* \brief Steady clock
*
* Steady clock represents a monotonic clock. The time points of this
* clock cannot decrease as physical time moves forward. This clock is
* not related to wall clock time, and is best suitable for measuring
* intervals.
*
* Note that on OS X platform this defaults to system clock and is not
* truly monotonic. Refer to https://svn.boost.org/trac/boost/ticket/7719)
*/
class steady_clock : public
#ifdef __APPLE__
// steady_clock may go backwards on OS X platforms, so use system_clock
// instead
boost::chrono::system_clock
#else
boost::chrono::steady_clock
#endif
{
public:
typedef time_point TimePoint;
typedef duration Duration;
// /// \brief Get current TimePoint
// TimePoint
// now();
}; // class steady_clock
/**
* \brief Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970)
*/
inline const system_clock::TimePoint&
getUnixEpoch()
{
static system_clock::TimePoint epoch = system_clock::from_time_t(0);
return epoch;
}
/**
* \brief Convert system_clock::TimePoint to UNIX timestamp
*/
inline milliseconds
toUnixTimestamp(const system_clock::TimePoint& point)
{
return duration_cast<milliseconds>(point - getUnixEpoch());
}
/**
* \brief Convert UNIX timestamp to system_clock::TimePoint
*/
inline system_clock::TimePoint
fromUnixTimestamp(const milliseconds& duration)
{
return getUnixEpoch() + duration;
}
/**
* \brief Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
*
* If timePoint contains doesn't contain fractional seconds the
* output format is YYYYMMDDTHHMMSS
*
* Examples:
*
* - with fractional nanoseconds: 20020131T100001,123456789
* - with fractional microseconds: 20020131T100001,123456
* - with fractional milliseconds: 20020131T100001,123
* - without fractional seconds: 20020131T100001
*/
inline std::string
toIsoString(const system_clock::TimePoint& timePoint)
{
namespace bpt = boost::posix_time;
bpt::ptime ptime = bpt::from_time_t(system_clock::to_time_t(timePoint));
uint64_t micro = duration_cast<microseconds>(timePoint - getUnixEpoch()).count() % 1000000;
if (micro > 0)
{
ptime += bpt::microseconds(micro);
return bpt::to_iso_string(ptime);
}
else
return bpt::to_iso_string(ptime);
}
/**
* \brief Convert from the ISO string (YYYYMMDDTHHMMSS,fffffffff) representation
* to the internal time format
*
* Examples of accepted ISO strings:
*
* - with fractional nanoseconds: 20020131T100001,123456789
* - with fractional microseconds: 20020131T100001,123456
* - with fractional milliseconds: 20020131T100001,123
* - without fractional seconds: 20020131T100001
*
*/
inline system_clock::TimePoint
fromIsoString(const std::string& isoString)
{
namespace bpt = boost::posix_time;
static bpt::ptime posixTimeEpoch = bpt::from_time_t(0);
bpt::ptime ptime = bpt::from_iso_string(isoString);
system_clock::TimePoint point =
system_clock::from_time_t((ptime - posixTimeEpoch).total_seconds());
point += microseconds((ptime - posixTimeEpoch).total_microseconds() % 1000000);
return point;
}
/**
* \brief Convert time point to string with specified format
*
* By default, `%Y-%m-%d %H:%M:%S` is used, producing dates like
* `2014-04-10 22:51:00`
*
* \param timePoint time point of system_clock
* \param format desired output format (default: `%Y-%m-%d %H:%M:%S`)
* \param locale desired locale (default: "C" locale)
*
* \sa http://www.boost.org/doc/libs/1_48_0/doc/html/date_time/date_time_io.html#date_time.format_flags
* described possible formatting flags
**/
inline std::string
toString(const system_clock::TimePoint& timePoint,
const std::string& format = "%Y-%m-%d %H:%M:%S",
const std::locale& locale = std::locale("C"))
{
namespace bpt = boost::posix_time;
bpt::ptime ptime = bpt::from_time_t(system_clock::to_time_t(timePoint));
uint64_t micro = duration_cast<microseconds>(timePoint - getUnixEpoch()).count() % 1000000;
ptime += bpt::microseconds(micro);
bpt::time_facet* facet = new bpt::time_facet(format.c_str());
std::ostringstream formattedTimePoint;
formattedTimePoint.imbue(std::locale(locale, facet));
formattedTimePoint << ptime;
return formattedTimePoint.str();
}
/**
* \brief Convert from string of specified format into time point
*
* By default, `%Y-%m-%d %H:%M:%S` is used, accepting dates like
* `2014-04-10 22:51:00`
*
* \param formattedTimePoint string representing time point
* \param format input output format (default: `%Y-%m-%d %H:%M:%S`)
* \param locale input locale (default: "C" locale)
*
* \sa http://www.boost.org/doc/libs/1_48_0/doc/html/date_time/date_time_io.html#date_time.format_flags
* described possible formatting flags
*/
inline system_clock::TimePoint
fromString(const std::string& formattedTimePoint,
const std::string& format = "%Y-%m-%d %H:%M:%S",
const std::locale& locale = std::locale("C"))
{
namespace bpt = boost::posix_time;
static bpt::ptime posixTimeEpoch = bpt::from_time_t(0);
bpt::time_input_facet* facet = new bpt::time_input_facet(format);
std::istringstream is(formattedTimePoint);
is.imbue(std::locale(locale, facet));
bpt::ptime ptime;
is >> ptime;
system_clock::TimePoint point =
system_clock::from_time_t((ptime - posixTimeEpoch).total_seconds());
point += microseconds((ptime - posixTimeEpoch).total_microseconds() % 1000000);
return point;
}
} // namespace time
} // namespace ndn
#endif // NDN_TIME_HPP