all: Refactoring work with time using boost::chrono

Now the library has two clocks: time::steady_clock and
time::system_clock, following (boost|std)::chrono.  In addition to
standard now() method, the library contains several helpers to convert
to/from UnixTimestamp (microsecond resolution) and IsoString (optional
microsecond resolution).  The IsoString conversions use
boost::posix_time routines, since boost::chrono supports extended IO
support only starting boost version 1.52 (Boost Chrono V2).

This commit breaks compatibility with previous API.  All time-related
Data/Interest calls must explicitly use time units to specify
FreshnessPeriod/InterestLifetime.

Brief usage/conversion guide:

- creation of time units does not support double/float types.  If
  necessary to create time unit from double, ``ndn::duration<double>`` (for
  seconds) needs to be used instead.  In some cases, this would also
  require ``ndn::duration_cast``, if the target is not ``ndn::nanoseconds``.
- ndn::getNow, ndn::ndn_getNowMilliseconds, ndn::time::now are all
  removed in favor of the now() method in a specific clock:

    * time::system_clock::now();
    * time::steady_clock::now();

- When necessary to convert system_clock::TimePoint to unix timestamp,
  ``time::toUnixTimestamp`` can be used.  This method return number of
  milliseconds since UNIX epoch as ``ndn::time::milliseconds`` type.
  Use count() method to obtain number as an integral value.

Change-Id: Icd688bc6766e008d60c3d2888173627874526e47
Refs: #1152
diff --git a/examples/consumer-with-timer.cpp b/examples/consumer-with-timer.cpp
index 6c7ef8c..83bb858 100644
--- a/examples/consumer-with-timer.cpp
+++ b/examples/consumer-with-timer.cpp
@@ -32,7 +32,7 @@
   
   ndn::Interest i(ndn::Name("/localhost/testApp/randomData"));
   i.setScope(1);
-  i.setInterestLifetime(1000);
+  i.setInterestLifetime(ndn::time::milliseconds(1000));
   i.setMustBeFresh(true);
 
   face.expressInterest(i,
@@ -50,7 +50,7 @@
     
     ndn::Interest i(ndn::Name("/localhost/testApp/randomData"));
     i.setScope(1);
-    i.setInterestLifetime(1000);
+    i.setInterestLifetime(ndn::time::seconds(1));
     i.setMustBeFresh(true);
 
     ndn::Face face(io);
diff --git a/examples/consumer.cpp b/examples/consumer.cpp
index 69a51e4..9ef366a 100644
--- a/examples/consumer.cpp
+++ b/examples/consumer.cpp
@@ -29,7 +29,7 @@
   try {
     ndn::Interest i(ndn::Name("/localhost/testApp/randomData"));
     i.setScope(1);
-    i.setInterestLifetime(1000);
+    i.setInterestLifetime(ndn::time::milliseconds(1000));
     i.setMustBeFresh(true);
 
     ndn::Face face;
diff --git a/examples/producer.cpp b/examples/producer.cpp
index c098739..b34bae1 100644
--- a/examples/producer.cpp
+++ b/examples/producer.cpp
@@ -26,7 +26,7 @@
     std::cout << "<< I: " << interest << std::endl;
     
     ndn::Data data(ndn::Name(interest.getName()).append("testApp").appendVersion());
-    data.setFreshnessPeriod(1000); // 10 sec
+    data.setFreshnessPeriod(time::seconds(10));
 
     data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
 
diff --git a/src/data.hpp b/src/data.hpp
index 5130b03..9fd00ab 100644
--- a/src/data.hpp
+++ b/src/data.hpp
@@ -18,18 +18,18 @@
 #include "management/nfd-local-control-header.hpp"
 
 namespace ndn {
-  
+
 class Data : public enable_shared_from_this<Data>
 {
 public:
   struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
-  
+
   /**
    * @brief Create an empty Data object
    */
   inline
   Data();
-  
+
   /**
    * @brief Create a new Data object with the given name
    * @param name A reference to the name which is copied.
@@ -45,20 +45,20 @@
   {
     wireDecode(wire);
   }
-  
+
   /**
    * @brief The destructor
    */
   inline
   ~Data();
-  
+
   /**
    * @brief Fast encoding or block size estimation
    */
   template<bool T>
   inline size_t
   wireEncode(EncodingImpl<T> &block, bool unsignedPortion = false) const;
-  
+
   /**
    * @brief Encode to a wire format
    */
@@ -68,7 +68,7 @@
   /**
    * @brief Decode from the wire format
    */
-  inline void 
+  inline void
   wireDecode(const Block &wire);
 
   /**
@@ -76,12 +76,12 @@
    */
   inline bool
   hasWire() const;
-  
-  ////////////////////////////////////////////////////////////////////  
-  
-  inline const Name& 
+
+  ////////////////////////////////////////////////////////////////////
+
+  inline const Name&
   getName() const;
-  
+
   /**
    * @brief Set name to a copy of the given Name.
    *
@@ -92,10 +92,10 @@
   setName(const Name& name);
 
   //
-  
-  inline const MetaInfo& 
+
+  inline const MetaInfo&
   getMetaInfo() const;
-  
+
   /**
    * @brief Set metaInfo to a copy of the given MetaInfo.
    * @param metaInfo The MetaInfo which is copied.
@@ -105,25 +105,25 @@
   setMetaInfo(const MetaInfo& metaInfo);
 
   //
-  
+
   ///////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////
   // MetaInfo proxy methods
 
-  inline uint32_t 
+  inline uint32_t
   getContentType() const;
-  
-  inline void 
+
+  inline void
   setContentType(uint32_t type);
 
   //
-  
-  inline Milliseconds 
+
+  inline const time::milliseconds&
   getFreshnessPeriod() const;
-  
-  inline void 
-  setFreshnessPeriod(Milliseconds freshnessPeriod);
+
+  inline void
+  setFreshnessPeriod(const time::milliseconds& freshnessPeriod);
 
   //
 
@@ -137,14 +137,14 @@
   ///////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////
-  
+
   /**
    * @brief Get content Block
    *
    * To access content value, one can use value()/value_size() or
    * value_begin()/value_end() methods of the Block class
    */
-  inline const Block& 
+  inline const Block&
   getContent() const;
 
   /**
@@ -162,17 +162,17 @@
   setContent(const ConstBufferPtr &contentValue);
 
   //
-  
+
   inline const Signature&
   getSignature() const;
-  
+
   /**
    * @brief Set the signature to a copy of the given signature.
    * @param signature The signature object which is cloned.
    */
   inline void
   setSignature(const Signature& signature);
-  
+
   inline void
   setSignatureValue(const Block &value);
 
@@ -183,18 +183,18 @@
 
   const nfd::LocalControlHeader&
   getLocalControlHeader() const;
-  
+
   inline uint64_t
   getIncomingFaceId() const;
 
   inline void
   setIncomingFaceId(uint64_t incomingFaceId);
-  
+
 private:
   /**
    * @brief Clear the wire encoding.
    */
-  inline void 
+  inline void
   onChanged();
 
 private:
@@ -253,10 +253,10 @@
 
   // SignatureInfo
   total_len += prependBlock(block, m_signature.getInfo());
-  
+
   // Content
   total_len += prependBlock(block, getContent());
-  
+
   // MetaInfo
   total_len += getMetaInfo().wireEncode(block);
 
@@ -279,16 +279,16 @@
 
   EncodingEstimator estimator;
   size_t estimatedSize = wireEncode(estimator);
-  
+
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
   const_cast<Data*>(this)->wireDecode(buffer.block());
   return m_wire;
 }
-  
+
 /**
- * Decode the input using a particular wire format and update this Data. 
+ * Decode the input using a particular wire format and update this Data.
  * @param input The input byte array to be decoded.
  */
 void
@@ -302,7 +302,7 @@
   //            MetaInfo
   //            Content
   //            Signature
-    
+
   // Name
   m_name.wireDecode(m_wire.get(Tlv::Name));
 
@@ -315,10 +315,10 @@
   ///////////////
   // Signature //
   ///////////////
-  
+
   // SignatureInfo
   m_signature.setInfo(m_wire.get(Tlv::SignatureInfo));
-  
+
   // SignatureValue
   Block::element_const_iterator val = m_wire.find(Tlv::SignatureValue);
   if (val != m_wire.elements_end())
@@ -331,53 +331,53 @@
   return m_wire.hasWire();
 }
 
-inline const Name& 
+inline const Name&
 Data::getName() const
 {
   return m_name;
 }
-  
+
 inline void
 Data::setName(const Name& name)
-{ 
+{
   onChanged();
-  m_name = name; 
+  m_name = name;
 }
-  
-inline const MetaInfo& 
+
+inline const MetaInfo&
 Data::getMetaInfo() const
 {
   return m_metaInfo;
 }
-  
+
 inline void
-Data::setMetaInfo(const MetaInfo& metaInfo) 
-{ 
+Data::setMetaInfo(const MetaInfo& metaInfo)
+{
   onChanged();
-  m_metaInfo = metaInfo; 
+  m_metaInfo = metaInfo;
 }
 
-inline uint32_t 
+inline uint32_t
 Data::getContentType() const
 {
   return m_metaInfo.getType();
 }
-  
-inline void 
+
+inline void
 Data::setContentType(uint32_t type)
 {
   onChanged();
   m_metaInfo.setType(type);
 }
-  
-inline Milliseconds 
+
+inline const time::milliseconds&
 Data::getFreshnessPeriod() const
 {
   return m_metaInfo.getFreshnessPeriod();
 }
-  
-inline void 
-Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
+
+inline void
+Data::setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
 {
   onChanged();
   m_metaInfo.setFreshnessPeriod(freshnessPeriod);
@@ -396,7 +396,7 @@
   m_metaInfo.setFinalBlockId(finalBlockId);
 }
 
-inline const Block& 
+inline const Block&
 Data::getContent() const
 {
   if (m_content.empty())
@@ -408,7 +408,7 @@
 }
 
 inline void
-Data::setContent(const uint8_t* content, size_t contentLength) 
+Data::setContent(const uint8_t* content, size_t contentLength)
 {
   onChanged();
 
@@ -422,9 +422,9 @@
 
   m_content = Block(Tlv::Content, contentValue); // not real a wire encoding yet
 }
-  
+
 inline void
-Data::setContent(const Block& content) 
+Data::setContent(const Block& content)
 {
   onChanged();
 
@@ -440,9 +440,9 @@
 {
   return m_signature;
 }
-  
+
 inline void
-Data::setSignature(const Signature& signature) 
+Data::setSignature(const Signature& signature)
 {
   onChanged();
   m_signature = signature;
@@ -482,14 +482,14 @@
   // ! do not reset Data's wire !
 }
 
-inline void 
+inline void
 Data::onChanged()
 {
   // The values have changed, so the wire format is invalidated
 
   // !!!Note!!! Signature is not invalidated and it is responsibility of
   // the application to do proper re-signing if necessary
-  
+
   m_wire.reset();
 }
 
diff --git a/src/detail/pending-interest.hpp b/src/detail/pending-interest.hpp
index b53dc1f..4cfc48a 100644
--- a/src/detail/pending-interest.hpp
+++ b/src/detail/pending-interest.hpp
@@ -30,15 +30,10 @@
     : interest_(interest),
       onData_(onData), onTimeout_(onTimeout)
   {
-    // Set up timeoutTime_.
-    if (interest_->getInterestLifetime() >= 0)
-      timeoutTimeMilliseconds_ = getNowMilliseconds() + interest_->getInterestLifetime();
+    if (interest_->getInterestLifetime() >= time::milliseconds::zero())
+      timeout_ = time::steady_clock::now() + interest_->getInterestLifetime();
     else
-      // No timeout.
-      /**
-       * @todo Set more meaningful default timeout.  This timeout MUST exist.
-       */
-      timeoutTimeMilliseconds_ = getNowMilliseconds() + 4000;
+      timeout_ = time::steady_clock::now() + DEFAULT_INTEREST_LIFETIME;
   }
     
   const shared_ptr<const Interest>& 
@@ -55,13 +50,12 @@
     
   /**
    * Check if this interest is timed out.
-   * @param nowMilliseconds The current time in milliseconds from getNowMilliseconds.
    * @return true if this interest timed out, otherwise false.
    */
   bool 
-  isTimedOut(MillisecondsSince1970 nowMilliseconds)
+  isTimedOut(const time::steady_clock::TimePoint& now)
   {
-    return timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_;
+    return now >= timeout_;
   }
 
   /**
@@ -80,8 +74,8 @@
   const OnData onData_;
   const OnTimeout onTimeout_;
 
-  /** The time when the interest times out in milliseconds according to getNowMilliseconds, or -1 for no timeout. */
-  MillisecondsSince1970 timeoutTimeMilliseconds_;
+  /** The time when the interest times out in time::milliseconds according to getNowMilliseconds, or -1 for no timeout. */
+  time::steady_clock::TimePoint timeout_;
 };
 
 
diff --git a/src/encoding/cryptopp/asn_ext.cpp b/src/encoding/cryptopp/asn_ext.cpp
index beea45d..7741314 100644
--- a/src/encoding/cryptopp/asn_ext.cpp
+++ b/src/encoding/cryptopp/asn_ext.cpp
@@ -17,29 +17,14 @@
 namespace ndn {
 
 size_t
-DEREncodeGeneralTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 time)
+DEREncodeGeneralTime(CryptoPP::BufferedTransformation &bt, const time::system_clock::TimePoint& time)
 {
-  if (time < 0)
-    throw Asn::Error("Calendar time value out of range");
-  else if (time > 2e14)
-    // 2e14 is about the year 8300.  We don't want to go over a 4-digit year.
-    throw Asn::Error("Calendar time value out of range");
+  std::string str = time::toIsoString(time);
+  // For example, 20131226T232254
+  // 20131226T232254.100000
+  BOOST_ASSERT(str.size() >= 15);
+  std::string asn1time = str.substr(0, 8) + str.substr(9,6) + "Z";
 
-
-  boost::posix_time::ptime boostTime =
-    UNIX_EPOCH_TIME + boost::posix_time::milliseconds(time);
-  
-  const boost::format f = boost::format("%04d%02d%02d%02d%02d%02dZ")
-                % boostTime.date().year_month_day().year
-                % boostTime.date().year_month_day().month.as_number()
-                % boostTime.date().year_month_day().day.as_number()
-                % boostTime.time_of_day().hours()
-                % boostTime.time_of_day().minutes()
-                % boostTime.time_of_day().seconds()
-    ;
-
-  std::string asn1time = f.str();
-  
   bt.Put(GENERALIZED_TIME);
   size_t lengthBytes = DERLengthEncode(bt, asn1time.size());
   bt.Put(reinterpret_cast<const uint8_t*>(asn1time.c_str()), asn1time.size());
@@ -47,7 +32,7 @@
 }
 
 void
-BERDecodeTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 &time)
+BERDecodeTime(CryptoPP::BufferedTransformation &bt, time::system_clock::TimePoint& time)
 {
   byte b;
   if (!bt.Get(b) || (b != GENERALIZED_TIME && b != UTC_TIME))
@@ -71,7 +56,7 @@
       str = "19" + str;
   }
  
-  time = fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6));
+  time = time::fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6));
 }
 
 } // namespace ndn
diff --git a/src/encoding/cryptopp/asn_ext.hpp b/src/encoding/cryptopp/asn_ext.hpp
index e0a9a6b..b02b3e9 100644
--- a/src/encoding/cryptopp/asn_ext.hpp
+++ b/src/encoding/cryptopp/asn_ext.hpp
@@ -16,14 +16,14 @@
 namespace ndn {
 
 namespace Asn {
-struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+struct Error : public std::runtime_error { Error(const std::string& what) : std::runtime_error(what) {} };
 }
 
 size_t
-DEREncodeGeneralTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 time);
+DEREncodeGeneralTime(CryptoPP::BufferedTransformation& bt, const time::system_clock::TimePoint& time);
 
 void
-BERDecodeTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 &time);
+BERDecodeTime(CryptoPP::BufferedTransformation& bt, time::system_clock::TimePoint& time);
 
 } // namespace ndn
 
diff --git a/src/face.cpp b/src/face.cpp
index fe509c4..aec1cdf 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -65,8 +65,8 @@
   m_transport = transport;
   m_ioService = ioService;
 
-  m_pitTimeoutCheckTimer      = make_shared<boost::asio::deadline_timer>(boost::ref(*m_ioService));
-  m_processEventsTimeoutTimer = make_shared<boost::asio::deadline_timer>(boost::ref(*m_ioService));
+  m_pitTimeoutCheckTimer      = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
+  m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
 
   if (std::getenv("NFD") != 0)
     {
@@ -132,7 +132,7 @@
 
   if (!m_pitTimeoutCheckTimerActive) {
     m_pitTimeoutCheckTimerActive = true;
-    m_pitTimeoutCheckTimer->expires_from_now(boost::posix_time::milliseconds(100));
+    m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
     m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
   }
 }
@@ -218,20 +218,21 @@
 }
 
 void
-Face::processEvents(Milliseconds timeout/* = 0 */, bool keepThread/* = false*/)
+Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
+                    bool keepThread/* = false*/)
 {
   try
     {
-      if (timeout < 0)
+      if (timeout < time::milliseconds::zero())
         {
           // do not block if timeout is negative, but process pending events
           m_ioService->poll();
           return;
         }
 
-      if (timeout > 0)
+      if (timeout > time::milliseconds::zero())
         {
-          m_processEventsTimeoutTimer->expires_from_now(boost::posix_time::milliseconds(timeout));
+          m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
           m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
         }
 
@@ -279,13 +280,13 @@
 void
 Face::checkPitExpire()
 {
-  // Check for PIT entry timeouts.  Go backwards through the list so we can erase entries.
-  MillisecondsSince1970 nowMilliseconds = getNowMilliseconds();
+  // Check for PIT entry timeouts.
+  time::steady_clock::TimePoint now = time::steady_clock::now();
 
   PendingInterestTable::iterator i = m_pendingInterestTable.begin();
   while (i != m_pendingInterestTable.end())
     {
-      if ((*i)->isTimedOut(nowMilliseconds))
+      if ((*i)->isTimedOut(now))
         {
           // Save the PendingInterest and remove it from the PIT.  Then call the callback.
           shared_ptr<PendingInterest> pendingInterest = *i;
@@ -301,7 +302,7 @@
   if (!m_pendingInterestTable.empty()) {
     m_pitTimeoutCheckTimerActive = true;
 
-    m_pitTimeoutCheckTimer->expires_from_now(boost::posix_time::milliseconds(100));
+    m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
     m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
   }
   else {
diff --git a/src/face.hpp b/src/face.hpp
index fcd9bd0..4cb4c67 100644
--- a/src/face.hpp
+++ b/src/face.hpp
@@ -17,6 +17,7 @@
 
 #include "management/controller.hpp"
 
+#include "util/scheduler.hpp"
 #include "detail/registered-prefix.hpp"
 #include "detail/pending-interest.hpp"
 
@@ -192,7 +193,8 @@
    * call this from an main event loop, you may want to catch and log/disregard all exceptions.
    */
   void 
-  processEvents(Milliseconds timeout = 0, bool keepThread = false);
+  processEvents(const time::milliseconds& timeout = time::milliseconds::zero(),
+                bool keepThread = false);
 
   void 
   shutdown();
@@ -241,9 +243,9 @@
 private:
   shared_ptr<boost::asio::io_service> m_ioService;
   shared_ptr<boost::asio::io_service::work> m_ioServiceWork; // needed if thread needs to be preserved
-  shared_ptr<boost::asio::deadline_timer> m_pitTimeoutCheckTimer;
+  shared_ptr<monotonic_deadline_timer> m_pitTimeoutCheckTimer;
   bool m_pitTimeoutCheckTimerActive;
-  shared_ptr<boost::asio::deadline_timer> m_processEventsTimeoutTimer;
+  shared_ptr<monotonic_deadline_timer> m_processEventsTimeoutTimer;
   
   shared_ptr<Transport> m_transport;
 
diff --git a/src/interest.cpp b/src/interest.cpp
index 942a5f7..229e0fb 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -29,7 +29,7 @@
 {
   if (!m_name.isPrefixOf(name))
     return false;
-  
+
   if (getMinSuffixComponents() >= 0 &&
     // Add 1 for the implicit digest.
       !(name.size() + 1 - m_name.size() >= getMinSuffixComponents()))
@@ -74,7 +74,8 @@
     os << delim << "ndn.Scope=" << interest.getScope();
     delim = '&';
   }
-  if (interest.getInterestLifetime() >= 0 && interest.getInterestLifetime() != DEFAULT_INTEREST_LIFETIME) {
+  if (interest.getInterestLifetime() >= time::milliseconds::zero()
+      && interest.getInterestLifetime() != DEFAULT_INTEREST_LIFETIME) {
     os << delim << "ndn.InterestLifetime=" << interest.getInterestLifetime();
     delim = '&';
   }
diff --git a/src/interest.hpp b/src/interest.hpp
index a22578f..2783aa9 100644
--- a/src/interest.hpp
+++ b/src/interest.hpp
@@ -14,55 +14,55 @@
 
 namespace ndn {
 
-const Milliseconds DEFAULT_INTEREST_LIFETIME = 4000;
+const time::seconds DEFAULT_INTEREST_LIFETIME = time::seconds(4);
 
 /**
  * An Interest holds a Name and other fields for an interest.
  */
 class Interest : public enable_shared_from_this<Interest>
 {
-public:    
+public:
   /**
    * @brief Create a new Interest with an empty name and "none" for all values.
    */
   Interest()
     : m_nonce(0)
     , m_scope(-1)
-    , m_interestLifetime(-1.0)
+    , m_interestLifetime(time::milliseconds::min())
   {
   }
 
   /**
    * @brief Create a new Interest with the given name and "none" for other values.
-   * 
+   *
    * @param name The name for the interest.
    */
-  Interest(const Name& name) 
+  Interest(const Name& name)
     : m_name(name)
     , m_nonce(0)
     , m_scope(-1)
-    , m_interestLifetime(-1.0)
+    , m_interestLifetime(time::milliseconds::min())
   {
   }
 
   /**
    * Create a new Interest with the given name and interest lifetime and "none" for other values.
    * @param name The name for the interest.
-   * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
+   * @param interestLifetimeMilliseconds The interest lifetime in time::milliseconds, or -1 for none.
    */
-  Interest(const Name& name, Milliseconds interestLifetime) 
+  Interest(const Name& name, const time::milliseconds& interestLifetime)
     : m_name(name)
     , m_nonce(0)
     , m_scope(-1)
     , m_interestLifetime(interestLifetime)
   {
   }
-  
+
   Interest(const Name& name,
-           const Selectors& selectors, 
+           const Selectors& selectors,
            int scope,
-           Milliseconds interestLifetime,
-           uint32_t nonce = 0) 
+           const time::milliseconds& interestLifetime,
+           uint32_t nonce = 0)
     : m_name(name)
     , m_selectors(selectors)
     , m_nonce(nonce)
@@ -70,7 +70,7 @@
     , m_interestLifetime(interestLifetime)
   {
   }
-  
+
   /**
    * Create a new Interest for the given name and values.
    * @param name
@@ -84,13 +84,13 @@
    * @param nonce
    */
   Interest(const Name& name,
-           int minSuffixComponents, int maxSuffixComponents, 
+           int minSuffixComponents, int maxSuffixComponents,
            const Exclude& exclude,
            int childSelector,
-           bool mustBeFresh, 
+           bool mustBeFresh,
            int scope,
-           Milliseconds interestLifetime,
-           uint32_t nonce = 0) 
+           const time::milliseconds& interestLifetime,
+           uint32_t nonce = 0)
     : m_name(name)
     , m_selectors(minSuffixComponents, maxSuffixComponents, exclude, childSelector, mustBeFresh)
     , m_nonce(nonce)
@@ -121,7 +121,7 @@
   /**
    * @brief Decode from the wire format
    */
-  inline void 
+  inline void
   wireDecode(const Block &wire);
 
   /**
@@ -129,7 +129,7 @@
    */
   inline bool
   hasWire() const;
-  
+
   /**
    * Encode the name according to the "NDN URI Scheme".  If there are interest selectors, append "?" and
    * added the selectors as a query string.  For example "/test/name?ndn.ChildSelector=1".
@@ -145,7 +145,7 @@
   hasGuiders() const;
 
   /**
-   * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the 
+   * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the
    * interest selectors.
    * @param self A pointer to the ndn_Interest struct.
    * @param name A pointer to the name to check.
@@ -158,8 +158,8 @@
   ///////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////
   // Getters/setters
-  
-  const Name& 
+
+  const Name&
   getName() const
   {
     return m_name;
@@ -172,7 +172,7 @@
     m_wire.reset();
     return *this;
   }
-  
+
   //
 
   const Selectors&
@@ -191,7 +191,7 @@
 
   //
 
-  int 
+  int
   getScope() const
   {
     return m_scope;
@@ -206,15 +206,15 @@
   }
 
   //
-  
-  Milliseconds 
+
+  const time::milliseconds&
   getInterestLifetime() const
   {
     return m_interestLifetime;
   }
 
   Interest&
-  setInterestLifetime(Milliseconds interestLifetime)
+  setInterestLifetime(const time::milliseconds& interestLifetime)
   {
     m_interestLifetime = interestLifetime;
     m_wire.reset();
@@ -222,7 +222,7 @@
   }
 
   //
-  
+
   /**
    * @brief Get Interest's nonce
    *
@@ -256,7 +256,7 @@
   }
 
   // helper methods for LocalControlHeader
-  
+
   uint64_t
   getIncomingFaceId() const
   {
@@ -274,7 +274,7 @@
   //
 
   // NextHopFaceId helpers make sense only for Interests
-  
+
   uint64_t
   getNextHopFaceId() const
   {
@@ -290,19 +290,19 @@
   }
 
   //
-  
+
   ///////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////
   // Wrappers for Selectors
   //
-  
+
   int
   getMinSuffixComponents() const
   {
     return m_selectors.getMinSuffixComponents();
   }
-  
+
   Interest&
   setMinSuffixComponents(int minSuffixComponents)
   {
@@ -312,7 +312,7 @@
   }
 
   //
-  
+
   int
   getMaxSuffixComponents() const
   {
@@ -326,7 +326,7 @@
     m_wire.reset();
     return *this;
   }
-  
+
   //
 
   const Exclude&
@@ -344,8 +344,8 @@
   }
 
   //
-  
-  int 
+
+  int
   getChildSelector() const
   {
     return m_selectors.getChildSelector();
@@ -361,7 +361,7 @@
 
   //
 
-  int 
+  int
   getMustBeFresh() const
   {
     return m_selectors.getMustBeFresh();
@@ -380,7 +380,7 @@
   Selectors m_selectors;
   mutable uint32_t m_nonce;
   int m_scope;
-  Milliseconds m_interestLifetime;
+  time::milliseconds m_interestLifetime;
 
   mutable Block m_wire;
 
@@ -409,7 +409,7 @@
 Interest::hasGuiders() const
 {
   return m_scope >= 0 ||
-    m_interestLifetime >= 0 ||
+    m_interestLifetime >= time::milliseconds::zero() ||
     m_nonce > 0;
 }
 
@@ -424,14 +424,15 @@
   //                Selectors?
   //                Nonce
   //                Scope?
-  //                InterestLifetime?  
+  //                InterestLifetime?
 
   // (reverse encoding)
 
   // InterestLifetime
-  if (getInterestLifetime() >= 0 && getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
+  if (getInterestLifetime() >= time::milliseconds::zero()
+      && getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
     {
-      total_len += prependNonNegativeIntegerBlock(block, Tlv::InterestLifetime, getInterestLifetime());
+      total_len += prependNonNegativeIntegerBlock(block, Tlv::InterestLifetime, getInterestLifetime().count());
     }
 
   // Scope
@@ -451,7 +452,7 @@
 
   // Name
   total_len += getName().wireEncode(block);
-  
+
   total_len += block.prependVarNumber (total_len);
   total_len += block.prependVarNumber (Tlv::Interest);
   return total_len;
@@ -465,7 +466,7 @@
 
   EncodingEstimator estimator;
   size_t estimatedSize = wireEncode(estimator);
-  
+
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
@@ -474,7 +475,7 @@
 }
 
 inline void
-Interest::wireDecode(const Block &wire) 
+Interest::wireDecode(const Block &wire)
 {
   m_wire = wire;
   m_wire.parse();
@@ -484,11 +485,11 @@
   //                Selectors?
   //                Nonce
   //                Scope?
-  //                InterestLifetime?  
+  //                InterestLifetime?
 
   if (m_wire.type() != Tlv::Interest)
     throw Tlv::Error("Unexpected TLV number when decoding Interest");
-  
+
   // Name
   m_name.wireDecode(m_wire.get(Tlv::Name));
 
@@ -518,12 +519,12 @@
     }
   else
     m_scope = -1;
-  
+
   // InterestLifetime
   val = m_wire.find(Tlv::InterestLifetime);
   if (val != m_wire.elements_end())
     {
-      m_interestLifetime = readNonNegativeInteger(*val);
+      m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
     }
   else
     {
diff --git a/src/management/ndnd-controller.cpp b/src/management/ndnd-controller.cpp
index b3b7821..1d3fb60 100644
--- a/src/management/ndnd-controller.cpp
+++ b/src/management/ndnd-controller.cpp
@@ -139,7 +139,7 @@
 
   Interest interest(interestName);
   interest.setScope(1);
-  interest.setInterestLifetime(1000);
+  interest.setInterestLifetime(time::seconds(1));
   interest.setMustBeFresh(true);
 
   m_face.expressInterest(interest,
@@ -172,7 +172,7 @@
 
   Interest interest(interestName);
   interest.setScope(1);
-  interest.setInterestLifetime(1000);
+  interest.setInterestLifetime(time::seconds(1));
   interest.setMustBeFresh(true);
 
   m_face.expressInterest(interest,
diff --git a/src/management/ndnd-face-instance.hpp b/src/management/ndnd-face-instance.hpp
index 1da6b94..60c07dc 100644
--- a/src/management/ndnd-face-instance.hpp
+++ b/src/management/ndnd-face-instance.hpp
@@ -18,7 +18,7 @@
  * An FaceInstance holds an action and  Name prefix and other fields for an forwarding entry.
  */
 class FaceInstance {
-public:    
+public:
   FaceInstance(const std::string &action,
                int64_t     faceId,
                uint32_t    ipProto,
@@ -26,7 +26,7 @@
                const std::string &port,
                const std::string &multicastInterface,
                uint32_t    multicastTtl,
-               Milliseconds freshnessPeriod) 
+               const time::milliseconds& freshnessPeriod)
     : action_(action)
     , faceId_(faceId)
     , ipProto_(ipProto)
@@ -42,73 +42,79 @@
     : faceId_(-1)
     , ipProto_(-1)
     , multicastTtl_(-1)
-    , freshnessPeriod_(-1)
+    , freshnessPeriod_(time::milliseconds::min())
   {
   }
 
   // Action
-  const std::string& 
+  const std::string&
   getAction() const { return action_; }
 
-  void 
+  void
   setAction(const std::string& action) { action_ = action; wire_.reset(); }
 
   // FaceID
   int64_t
   getFaceId() const { return faceId_; }
 
-  void 
+  void
   setFaceId(int64_t faceId) { faceId_ = faceId; wire_.reset(); }
 
   // IPProto
-  int32_t 
+  int32_t
   getIpProto() const { return ipProto_; }
 
-  void 
+  void
   setIpProto(int32_t ipProto) { ipProto_ = ipProto; wire_.reset(); }
 
   // Host
-  const std::string& 
+  const std::string&
   getHost() const { return host_; }
 
-  void 
+  void
   setHost(const std::string& host) { host_ = host; wire_.reset(); }
 
   // Port
   const std::string&
   getPort() const { return port_; }
 
-  void 
+  void
   setPort(const std::string &port) { port_ = port; wire_.reset(); }
 
   // MulticastInterface
-  const std::string& 
+  const std::string&
   getMulticastInterface() const { return multicastInterface_; }
 
-  void 
-  setMulticastInterface(const std::string& multicastInterface) { multicastInterface_ = multicastInterface; wire_.reset(); }
+  void
+  setMulticastInterface(const std::string& multicastInterface)
+  {
+    multicastInterface_ = multicastInterface; wire_.reset();
+  }
 
   // MulticastTTL
   int32_t
   getMulticastTtl() const { return multicastTtl_; }
 
-  void 
+  void
   setMulticastTtl(int32_t multicastTtl) { multicastTtl_ = multicastTtl; wire_.reset(); }
 
   // Freshness
-  int 
+  const time::milliseconds&
   getFreshnessPeriod() const { return freshnessPeriod_; }
 
-  void 
-  setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+  void
+  setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
+  {
+    freshnessPeriod_ = freshnessPeriod; wire_.reset();
+  }
 
   // Wire
   inline const Block&
   wireEncode() const;
-  
-  inline void 
+
+  inline void
   wireDecode(const Block &wire);
-  
+
 private:
   std::string action_;
   int64_t     faceId_;
@@ -117,8 +123,8 @@
   std::string port_;
   std::string multicastInterface_;
   int32_t     multicastTtl_;
-  Milliseconds freshnessPeriod_;
-  
+  time::milliseconds freshnessPeriod_;
+
   mutable Block wire_;
 };
 
@@ -137,7 +143,7 @@
   //                  MulticastInterface?
   //                  MulticastTTL?
   //                  FreshnessPeriod?
-  
+
   wire_ = Block(tlv::ndnd::FaceInstance);
 
   // Action
@@ -160,7 +166,7 @@
       wire_.push_back
         (nonNegativeIntegerBlock(tlv::ndnd::IPProto, ipProto_));
     }
-  
+
   // Host
   if (!host_.empty())
     {
@@ -190,17 +196,17 @@
     }
 
   // FreshnessPeriod
-  if (freshnessPeriod_ >= 0)
+  if (freshnessPeriod_ >= time::milliseconds::zero())
     {
       wire_.push_back
-        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_.count()));
     }
-  
+
   wire_.encode();
-  return wire_;    
+  return wire_;
 }
-  
-inline void 
+
+inline void
 FaceInstance::wireDecode(const Block &wire)
 {
   action_.clear();
@@ -210,7 +216,7 @@
   port_.clear();
   multicastInterface_.clear();
   multicastTtl_ = -1;
-  freshnessPeriod_ = -1;
+  freshnessPeriod_ = time::milliseconds::min();
 
   wire_ = wire;
   wire_.parse();
@@ -278,7 +284,7 @@
   val = wire_.find(Tlv::FreshnessPeriod);
   if (val != wire_.elements_end())
     {
-      freshnessPeriod_ = readNonNegativeInteger(*val);
+      freshnessPeriod_ = time::milliseconds(readNonNegativeInteger(*val));
     }
 }
 
@@ -286,7 +292,7 @@
 operator << (std::ostream &os, const FaceInstance &entry)
 {
   os << "FaceInstance(";
-  
+
   // Action
   if (!entry.getAction().empty())
     {
@@ -330,7 +336,7 @@
     }
 
   // FreshnessPeriod
-  if (entry.getFreshnessPeriod() >= 0)
+  if (entry.getFreshnessPeriod() >= time::milliseconds::zero())
     {
       os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
     }
@@ -343,4 +349,3 @@
 } // namespace ndn
 
 #endif // NDN_MANAGEMENT_NDND_FACE_INSTANCE_HPP
-
diff --git a/src/management/ndnd-forwarding-entry.hpp b/src/management/ndnd-forwarding-entry.hpp
index 3d262f1..03272b1 100644
--- a/src/management/ndnd-forwarding-entry.hpp
+++ b/src/management/ndnd-forwarding-entry.hpp
@@ -20,12 +20,12 @@
  * An ForwardingEntry holds an action and  Name prefix and other fields for an forwarding entry.
  */
 class ForwardingEntry {
-public:    
+public:
   ForwardingEntry(const std::string& action,
                   const Name& prefix,
                   int faceId = -1,
                   const ForwardingFlags& forwardingFlags = ForwardingFlags(),
-                  int freshnessPeriod = -1) 
+                  time::milliseconds freshnessPeriod = time::milliseconds::min())
     : action_(action)
     , prefix_(prefix)
     , faceId_(faceId)
@@ -36,52 +36,52 @@
 
   ForwardingEntry()
   : faceId_(-1)
-  , freshnessPeriod_(-1)
+  , freshnessPeriod_(time::milliseconds::min())
   {
   }
-  
-  const std::string& 
+
+  const std::string&
   getAction() const { return action_; }
 
-  void 
+  void
   setAction(const std::string& action) { action_ = action; wire_.reset(); }
-    
-  const Name& 
+
+  const Name&
   getPrefix() const { return prefix_; }
-  
+
   void
   setPrefix(const Name &prefix) { prefix_ = prefix; wire_.reset(); }
-  
-  int 
+
+  int
   getFaceId() const { return faceId_; }
 
-  void 
+  void
   setFaceId(int faceId) { faceId_ = faceId; wire_.reset(); }
-      
-  const ForwardingFlags& 
+
+  const ForwardingFlags&
   getForwardingFlags() const { return forwardingFlags_; }
 
-  void 
+  void
   setForwardingFlags(const ForwardingFlags& forwardingFlags) { forwardingFlags_ = forwardingFlags; wire_.reset(); }
-      
-  int 
+
+  const time::milliseconds&
   getFreshnessPeriod() const { return freshnessPeriod_; }
 
-  void 
-  setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+  void
+  setFreshnessPeriod(const time::milliseconds& freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
 
   inline const Block&
   wireEncode() const;
-  
-  inline void 
+
+  inline void
   wireDecode(const Block &wire);
-  
+
 private:
   std::string action_;   /**< empty for none. */
   Name prefix_;
   int faceId_;           /**< -1 for none. */
   ForwardingFlags forwardingFlags_;
-  int freshnessPeriod_; /**< -1 for none. */
+  time::milliseconds freshnessPeriod_; /**< time::milliseconds::min() for none. */
 
   mutable Block wire_;
 };
@@ -98,7 +98,7 @@
   //                       FaceID?
   //                       ForwardingFlags?
   //                       FreshnessPeriod?
-  
+
   wire_ = Block(tlv::ndnd::ForwardingEntry);
 
   // Action
@@ -124,24 +124,24 @@
     (forwardingFlags_.wireEncode());
 
   // FreshnessPeriod
-  if (freshnessPeriod_ >= 0)
+  if (freshnessPeriod_ >= time::milliseconds::zero())
     {
       wire_.push_back
-        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_.count()));
     }
-  
+
   wire_.encode();
-  return wire_;    
+  return wire_;
 }
-  
-inline void 
+
+inline void
 ForwardingEntry::wireDecode(const Block &wire)
 {
   action_.clear();
   prefix_.clear();
   faceId_ = -1;
   forwardingFlags_ = ForwardingFlags();
-  freshnessPeriod_ = -1;
+  freshnessPeriod_ = time::milliseconds::min();
 
   wire_ = wire;
   wire_.parse();
@@ -185,7 +185,7 @@
   val = wire_.find(Tlv::FreshnessPeriod);
   if (val != wire_.elements_end())
     {
-      freshnessPeriod_ = readNonNegativeInteger(*val);
+      freshnessPeriod_ = time::milliseconds(readNonNegativeInteger(*val));
     }
 }
 
@@ -193,7 +193,7 @@
 operator << (std::ostream &os, const ForwardingEntry &entry)
 {
   os << "ForwardingEntry(";
-  
+
   // Action
   if (!entry.getAction().empty())
     {
@@ -213,7 +213,7 @@
   os << "ForwardingFlags:" << entry.getForwardingFlags() << ", ";
 
   // FreshnessPeriod
-  if (entry.getFreshnessPeriod() >= 0)
+  if (entry.getFreshnessPeriod() >= time::milliseconds::zero())
     {
       os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
     }
diff --git a/src/management/nfd-status.hpp b/src/management/nfd-status.hpp
index fa7f884..e00c705 100644
--- a/src/management/nfd-status.hpp
+++ b/src/management/nfd-status.hpp
@@ -44,8 +44,6 @@
   wireDecode(const Block& payload);
 
 public:
-  typedef boost::chrono::time_point<boost::chrono::system_clock, boost::chrono::seconds> Timestamp;
-
   int
   getNfdVersion() const
   {
@@ -58,26 +56,26 @@
     m_nfdVersion = nfdVersion;
   }
 
-  Timestamp
+  const time::system_clock::TimePoint&
   getStartTimestamp() const
   {
     return m_startTimestamp;
   }
 
   void
-  setStartTimestamp(Timestamp startTimestamp)
+  setStartTimestamp(const time::system_clock::TimePoint& startTimestamp)
   {
     m_startTimestamp = startTimestamp;
   }
 
-  Timestamp
+  const time::system_clock::TimePoint&
   getCurrentTimestamp() const
   {
     return m_currentTimestamp;
   }
 
   void
-  setCurrentTimestamp(Timestamp currentTimestamp)
+  setCurrentTimestamp(const time::system_clock::TimePoint& currentTimestamp)
   {
     m_currentTimestamp = currentTimestamp;
   }
@@ -192,8 +190,8 @@
 
 private:
   int       m_nfdVersion;
-  Timestamp m_startTimestamp;
-  Timestamp m_currentTimestamp;
+  time::system_clock::TimePoint m_startTimestamp;
+  time::system_clock::TimePoint m_currentTimestamp;
   size_t    m_nNameTreeEntries;
   size_t    m_nFibEntries;
   size_t    m_nPitEntries;
@@ -205,24 +203,22 @@
   int       m_nOutDatas;
 };
 
-BOOST_STATIC_ASSERT((boost::is_same<Status::Timestamp::period, boost::ratio<1> >::value));
-
 inline
 Status::Status()
-{
-  m_nfdVersion = 0;
-  m_startTimestamp = Timestamp::min();
-  m_currentTimestamp = Timestamp::min();
-  m_nNameTreeEntries = 0;
-  m_nFibEntries = 0;
-  m_nPitEntries = 0;
-  m_nMeasurementsEntries = 0;
-  m_nCsEntries = 0;
-  m_nInInterests = 0;
-  m_nOutInterests = 0;
-  m_nInDatas = 0;
-  m_nOutDatas = 0;
-}
+  : m_nfdVersion(0)
+  , m_startTimestamp(time::system_clock::TimePoint::min())
+  , m_currentTimestamp(time::system_clock::TimePoint::min())
+  , m_nNameTreeEntries(0)
+  , m_nFibEntries(0)
+  , m_nPitEntries(0)
+  , m_nMeasurementsEntries(0)
+  , m_nCsEntries(0)
+  , m_nInInterests(0)
+  , m_nOutInterests(0)
+  , m_nInDatas(0)
+  , m_nOutDatas(0)
+  {
+  }
 
 template<bool T>
 inline size_t
@@ -249,9 +245,9 @@
   total_len += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NNameTreeEntries,
                                               m_nNameTreeEntries);
   total_len += prependNonNegativeIntegerBlock(encoder, tlv::nfd::CurrentTimestamp,
-               m_currentTimestamp.time_since_epoch().count());
+                                              time::toUnixTimestamp(m_currentTimestamp).count());
   total_len += prependNonNegativeIntegerBlock(encoder, tlv::nfd::StartTimestamp,
-               m_startTimestamp.time_since_epoch().count());
+                                              time::toUnixTimestamp(m_startTimestamp).count());
   total_len += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NfdVersion,
                                               m_nfdVersion);
 
@@ -262,8 +258,8 @@
 Status::wireDecode(const Block& payload)
 {
   m_nfdVersion = 0;
-  m_startTimestamp = Timestamp::min();
-  m_currentTimestamp = Timestamp::min();
+  m_startTimestamp = time::system_clock::TimePoint::min();
+  m_currentTimestamp = time::system_clock::TimePoint::min();
   m_nNameTreeEntries = 0;
   m_nFibEntries = 0;
   m_nPitEntries = 0;
@@ -288,12 +284,12 @@
 
   val = payload.find(tlv::nfd::StartTimestamp);
   if (val != payload.elements_end()) {
-    m_startTimestamp = Timestamp(boost::chrono::seconds(readNonNegativeInteger(*val)));
+    m_startTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
   }
 
   val = payload.find(tlv::nfd::CurrentTimestamp);
   if (val != payload.elements_end()) {
-    m_currentTimestamp = Timestamp(boost::chrono::seconds(readNonNegativeInteger(*val)));
+    m_currentTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
   }
 
   val = payload.find(tlv::nfd::NNameTreeEntries);
diff --git a/src/management/nrd-prefix-reg-options.hpp b/src/management/nrd-prefix-reg-options.hpp
index 412194b..c80d04b 100644
--- a/src/management/nrd-prefix-reg-options.hpp
+++ b/src/management/nrd-prefix-reg-options.hpp
@@ -26,13 +26,13 @@
  */
 class PrefixRegOptions {
 public:
-  struct Error : public Tlv::Error { Error(const std::string &what) : Tlv::Error(what) {} };
+  struct Error : public Tlv::Error { Error(const std::string& what) : Tlv::Error(what) {} };
 
   PrefixRegOptions()
-    : m_faceId (INVALID_FACE_ID)
-    , m_flags (DEFAULT_FLAGS)
-    , m_cost (DEFAULT_COST)
-    , m_expirationPeriod (-1)
+    : m_faceId(INVALID_FACE_ID)
+    , m_flags(DEFAULT_FLAGS)
+    , m_cost(DEFAULT_COST)
+    , m_expirationPeriod(time::milliseconds::min())
   {
   }
 
@@ -117,14 +117,14 @@
 
   //
 
-  Milliseconds
+  const time::milliseconds&
   getExpirationPeriod() const
   {
     return m_expirationPeriod;
   }
 
   PrefixRegOptions&
-  setExpirationPeriod(Milliseconds expirationPeriod)
+  setExpirationPeriod(const time::milliseconds& expirationPeriod)
   {
     m_expirationPeriod = expirationPeriod;
     m_wire.reset();
@@ -152,7 +152,7 @@
   uint64_t m_faceId;
   uint64_t m_flags;
   uint64_t m_cost;
-  Milliseconds m_expirationPeriod;
+  time::milliseconds m_expirationPeriod;
   std::string m_protocol;
 
   mutable Block m_wire;
@@ -184,10 +184,11 @@
     }
 
   // ExpirationPeriod
-  if (m_expirationPeriod > 0)
+  if (m_expirationPeriod > time::milliseconds::zero())
     {
       total_len += prependNonNegativeIntegerBlock(block,
-                                                  tlv::nrd::ExpirationPeriod, m_expirationPeriod);
+                                                  tlv::nrd::ExpirationPeriod,
+                                                  m_expirationPeriod.count());
     }
 
   // Cost
@@ -247,7 +248,7 @@
   m_faceId = INVALID_FACE_ID;
   m_flags = DEFAULT_FLAGS;
   m_cost = DEFAULT_COST;
-  m_expirationPeriod = -1;
+  m_expirationPeriod = time::milliseconds::min();
   m_protocol.clear();
 
   m_wire = wire;
@@ -289,7 +290,7 @@
   val = m_wire.find(tlv::nrd::ExpirationPeriod);
   if (val != m_wire.elements_end())
     {
-      m_expirationPeriod = readNonNegativeInteger(*val);
+      m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
     }
 
   // Protocol
diff --git a/src/meta-info.hpp b/src/meta-info.hpp
index 2bccd37..42875d8 100644
--- a/src/meta-info.hpp
+++ b/src/meta-info.hpp
@@ -22,11 +22,11 @@
     TYPE_LINK = 1,
     TYPE_KEY = 2
   };
-  
+
   MetaInfo()
     : m_type(TYPE_DEFAULT)
     , m_freshnessPeriod(-1)
-  {   
+  {
   }
 
   MetaInfo(const Block& block)
@@ -38,21 +38,21 @@
   size_t
   wireEncode(EncodingImpl<T> &block) const;
 
-  const Block& 
+  const Block&
   wireEncode() const;
-  
+
   void
-  wireDecode(const Block &wire);  
-  
+  wireDecode(const Block &wire);
+
   ///////////////////////////////////////////////////////////////////////////////
   // Getters/setters
-  
-  uint32_t 
+
+  uint32_t
   getType() const
   {
     return m_type;
   }
-  
+
   MetaInfo&
   setType(uint32_t type)
   {
@@ -60,15 +60,15 @@
     m_type = type;
     return *this;
   }
-  
-  Milliseconds 
+
+  const time::milliseconds&
   getFreshnessPeriod() const
   {
     return m_freshnessPeriod;
   }
-  
+
   MetaInfo&
-  setFreshnessPeriod(Milliseconds freshnessPeriod)
+  setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
   {
     m_wire.reset();
     m_freshnessPeriod = freshnessPeriod;
@@ -88,10 +88,10 @@
     m_finalBlockId = finalBlockId;
     return *this;
   }
-  
+
 private:
   uint32_t m_type;
-  Milliseconds m_freshnessPeriod;
+  time::milliseconds m_freshnessPeriod;
   name::Component m_finalBlockId;
 
   mutable Block m_wire;
@@ -105,7 +105,7 @@
   //                ContentType?
   //                FreshnessPeriod?
   //                FinalBlockId?
-  
+
   size_t total_len = 0;
 
   // FinalBlockId
@@ -113,11 +113,12 @@
     {
       total_len += prependNestedBlock(blk, Tlv::FinalBlockId, m_finalBlockId);
     }
-  
+
   // FreshnessPeriod
-  if (m_freshnessPeriod >= 0)
+  if (m_freshnessPeriod >= time::milliseconds::zero())
     {
-      total_len += prependNonNegativeIntegerBlock(blk, Tlv::FreshnessPeriod, m_freshnessPeriod);
+      total_len += prependNonNegativeIntegerBlock(blk, Tlv::FreshnessPeriod,
+                                                  m_freshnessPeriod.count());
     }
 
   // ContentType
@@ -131,7 +132,7 @@
   return total_len;
 }
 
-inline const Block& 
+inline const Block&
 MetaInfo::wireEncode() const
 {
   if (m_wire.hasWire ())
@@ -139,14 +140,14 @@
 
   EncodingEstimator estimator;
   size_t estimatedSize = wireEncode(estimator);
-  
+
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
   m_wire = buffer.block();
   return m_wire;
 }
-  
+
 inline void
 MetaInfo::wireDecode(const Block &wire)
 {
@@ -156,7 +157,7 @@
   // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
   //                ContentType?
   //                FreshnessPeriod?
-  
+
   // ContentType
   Block::element_const_iterator val = m_wire.find(Tlv::ContentType);
   if (val != m_wire.elements().end())
@@ -170,10 +171,10 @@
   val = m_wire.find(Tlv::FreshnessPeriod);
   if (val != m_wire.elements().end())
     {
-      m_freshnessPeriod = readNonNegativeInteger(*val);
+      m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
     }
   else
-    m_freshnessPeriod = -1;
+    m_freshnessPeriod = time::milliseconds::min();
 
   // FinalBlockId
   val = m_wire.find(Tlv::FinalBlockId);
@@ -197,7 +198,7 @@
   os << "ContentType: " << info.getType();
 
   // FreshnessPeriod
-  if (info.getFreshnessPeriod() >= 0) {
+  if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
     os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
   }
 
diff --git a/src/name.cpp b/src/name.cpp
index a355e4a..846cabb 100644
--- a/src/name.cpp
+++ b/src/name.cpp
@@ -91,7 +91,7 @@
 Name& 
 Name::appendVersion()
 {
-  appendVersion(ndn_getNowMilliseconds());
+  appendVersion(time::toUnixTimestamp(time::system_clock::now()).count());
   return *this;
 }
 
diff --git a/src/security/certificate-cache-ttl.cpp b/src/security/certificate-cache-ttl.cpp
index 6f831d0..0997182 100644
--- a/src/security/certificate-cache-ttl.cpp
+++ b/src/security/certificate-cache-ttl.cpp
@@ -17,32 +17,34 @@
 
 namespace ndn {
 
-CertificateCacheTtl::CertificateCacheTtl(shared_ptr<boost::asio::io_service> io, int defaultTtl)
+CertificateCacheTtl::CertificateCacheTtl(shared_ptr<boost::asio::io_service> io, const time::seconds& defaultTtl)
   : m_defaultTtl(defaultTtl)
   , m_scheduler(*io)
 {}
 
 CertificateCacheTtl::~CertificateCacheTtl()
 {}
-  
+
 void
 CertificateCacheTtl::insertCertificate(ptr_lib::shared_ptr<const IdentityCertificate> certificate)
 {
-  time::Duration expire = (certificate->getFreshnessPeriod() >= 0 ? time::milliseconds(certificate->getFreshnessPeriod()) : time::seconds(m_defaultTtl));
+  time::milliseconds expire = (certificate->getFreshnessPeriod() >= time::seconds::zero() ?
+                         certificate->getFreshnessPeriod() : m_defaultTtl);
 
   Name trackerIndex = certificate->getName().getPrefix(-1);
   EventTracker::iterator it = m_tracker.find(trackerIndex);
   if(it != m_tracker.end())
       m_scheduler.cancelEvent(m_tracker[trackerIndex]);
 
-  m_scheduler.scheduleEvent(time::seconds(0), bind(&CertificateCacheTtl::insert, this, certificate));  
-  m_tracker[trackerIndex] = m_scheduler.scheduleEvent(expire, bind(&CertificateCacheTtl::remove, this, certificate->getName()));
+  m_scheduler.scheduleEvent(time::seconds(0), bind(&CertificateCacheTtl::insert, this, certificate));
+  m_tracker[trackerIndex] = m_scheduler.scheduleEvent(expire, bind(&CertificateCacheTtl::remove,
+                                                                   this, certificate->getName()));
 
 }
 
 void
 CertificateCacheTtl::insert(ptr_lib::shared_ptr<const IdentityCertificate> certificate)
-{ 
+{
   Name name = certificate->getName().getPrefix(-1);
   m_cache[name] = certificate;
 }
@@ -56,7 +58,7 @@
     m_cache.erase(it);
 }
 
-ptr_lib::shared_ptr<const IdentityCertificate> 
+ptr_lib::shared_ptr<const IdentityCertificate>
 CertificateCacheTtl::getCertificate(const Name & certificateName)
 {
   Cache::iterator it = m_cache.find(certificateName);
@@ -67,5 +69,3 @@
 }
 
 } // namespace ndn
-
-
diff --git a/src/security/certificate-cache-ttl.hpp b/src/security/certificate-cache-ttl.hpp
index 9ac91d5..1e31e9c 100644
--- a/src/security/certificate-cache-ttl.hpp
+++ b/src/security/certificate-cache-ttl.hpp
@@ -14,25 +14,25 @@
 #include "../util/time.hpp"
 
 namespace ndn {
- 
+
 class CertificateCacheTtl : public CertificateCache
 {
 public:
-  CertificateCacheTtl(shared_ptr<boost::asio::io_service> io, int defaultTtl = 3600);
-  
+  CertificateCacheTtl(shared_ptr<boost::asio::io_service> io, const time::seconds& defaultTtl = time::seconds(3600));
+
   virtual
   ~CertificateCacheTtl();
-    
+
   virtual void
   insertCertificate(ptr_lib::shared_ptr<const IdentityCertificate> certificate);
-  
-  virtual ptr_lib::shared_ptr<const IdentityCertificate> 
+
+  virtual ptr_lib::shared_ptr<const IdentityCertificate>
   getCertificate(const Name & certificateNameWithoutVersion);
 
-private:  
+private:
   void
   insert(ptr_lib::shared_ptr<const IdentityCertificate> certificate);
-  
+
   void
   remove(const Name &certificateName);
 
@@ -40,7 +40,7 @@
   typedef std::map<Name, ptr_lib::shared_ptr<const IdentityCertificate> > Cache;
   typedef std::map<Name, EventId> EventTracker;
 
-  int m_defaultTtl;
+  time::seconds m_defaultTtl;
   Cache m_cache;
   EventTracker m_tracker;
   Scheduler m_scheduler;
diff --git a/src/security/certificate.cpp b/src/security/certificate.cpp
index 0312fd5..931a40e 100644
--- a/src/security/certificate.cpp
+++ b/src/security/certificate.cpp
@@ -26,8 +26,8 @@
 namespace ndn {
 
 Certificate::Certificate()
-  : notBefore_(std::numeric_limits<MillisecondsSince1970>::max())
-  , notAfter_(std::numeric_limits<MillisecondsSince1970>::min())
+  : notBefore_(time::system_clock::TimePoint::max())
+  , notAfter_(time::system_clock::TimePoint::min())
 {}
 
 Certificate::Certificate(const Data& data)
@@ -47,18 +47,16 @@
 bool
 Certificate::isTooEarly()
 {
-  MillisecondsSince1970 now = ndn_getNowMilliseconds();
-  if(now < notBefore_)
+  if(time::system_clock::now() < notBefore_)
     return true;
   else
     return false;
 }
 
-bool 
+bool
 Certificate::isTooLate()
 {
-  MillisecondsSince1970 now = ndn_getNowMilliseconds();
-  if(now > notAfter_)
+  if(time::system_clock::now() > notAfter_)
     return true;
   else
     return false;
@@ -106,7 +104,7 @@
 
   OBufferStream os;
   CryptoPP::FileSink sink(os);
-  
+
   // idCert ::= SEQUENCE {
   //     validity            Validity,
   //     subject             Name,
@@ -126,7 +124,7 @@
 
     // Name ::= CHOICE {
     //     RDNSequence   }
-    // 
+    //
     // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     DERSequenceEncoder name(idCert);
     {
@@ -137,7 +135,7 @@
         }
     }
     name.MessageEnd();
-  
+
     // SubjectPublicKeyInfo
     key_.encode(idCert);
 
@@ -151,7 +149,7 @@
       {
         DERSequenceEncoder extensions(idCert);
         {
-          
+
           for(ExtensionList::iterator it = extensionList_.begin();
               it != extensionList_.end(); ++it)
             {
@@ -168,14 +166,14 @@
   setContentType(MetaInfo::TYPE_KEY);
 }
 
-void 
+void
 Certificate::decode()
 {
   using namespace CryptoPP;
 
   OBufferStream os;
   CryptoPP::StringSource source(getContent().value(), getContent().value_size(), true);
-  
+
   // idCert ::= SEQUENCE {
   //     validity            Validity,
   //     subject             Name,
@@ -195,7 +193,7 @@
 
     // Name ::= CHOICE {
     //     RDNSequence   }
-    // 
+    //
     // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     subjectDescriptionList_.clear();
     BERSequenceDecoder name(idCert);
@@ -206,7 +204,7 @@
         }
     }
     name.MessageEnd();
-  
+
     // SubjectPublicKeyInfo ::= SEQUENCE {
     //     algorithm           AlgorithmIdentifier
     //     keybits             BIT STRING   }
@@ -235,18 +233,18 @@
   idCert.MessageEnd();
 }
 
-void 
+void
 Certificate::printCertificate(std::ostream &os) const
 {
   os << "Certificate name:" << endl;
   os << "  " << getName() << endl;
   os << "Validity:" << endl;
   {
-    os << "  NotBefore: " << toIsoString(notBefore_) << endl;
-    os << "  NotAfter: "  << toIsoString(notAfter_)  << endl;
+    os << "  NotBefore: " << time::toIsoString(notBefore_) << endl;
+    os << "  NotAfter: "  << time::toIsoString(notAfter_)  << endl;
   }
 
-  os << "Subject Description:" << endl;  
+  os << "Subject Description:" << endl;
   for(SubjectDescriptionList::const_iterator it = subjectDescriptionList_.begin();
       it != subjectDescriptionList_.end(); ++it)
     {
@@ -256,7 +254,7 @@
   os << "Public key bits:" << endl;
   CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os), true, 64);
   key_.encode(encoder);
-  
+
   // ndnboost::iostreams::stream<ndnboost::iostreams::array_source> is((const char*)key_.getKeyDer().buf(), key_.getKeyDer().size());
 
   // ptr_lib::shared_ptr<der::DerNode> keyRoot = der::DerNode::parse(reinterpret_cast<der::InputIterator&> (is));
diff --git a/src/security/certificate.hpp b/src/security/certificate.hpp
index 35934d0..d27f7a4 100644
--- a/src/security/certificate.hpp
+++ b/src/security/certificate.hpp
@@ -35,16 +35,16 @@
    * @param data The data packet with the content to decode.
    */
   Certificate(const Data& data);
- 
+
   /**
    * The virtual destructor.
    */
-  virtual 
+  virtual
   ~Certificate();
 
   inline void
   wireDecode(const Block &wire);
-  
+
   /**
    * encode certificate info into content
    */
@@ -55,63 +55,63 @@
    * Add a subject description.
    * @param description The description to be added.
    */
-  void 
+  void
   addSubjectDescription(const CertificateSubjectDescription& description) { subjectDescriptionList_.push_back(description); }
 
-  const SubjectDescriptionList& 
+  const SubjectDescriptionList&
   getSubjectDescriptionList() const { return subjectDescriptionList_; }
-  
-  SubjectDescriptionList& 
+
+  SubjectDescriptionList&
   getSubjectDescriptionList() { return subjectDescriptionList_; }
- 
+
   /**
    * Add a certificate extension.
    * @param extension the extension to be added
    */
-  void 
+  void
   addExtension(const CertificateExtension& extension) { extensionList_.push_back(extension); }
 
   const ExtensionList&
   getExtensionList() const { return extensionList_; }
-  
+
   ExtensionList&
   getExtensionList() { return extensionList_; }
 
-  void 
-  setNotBefore(const MillisecondsSince1970& notBefore) { notBefore_ = notBefore; }
+  void
+  setNotBefore(const time::system_clock::TimePoint& notBefore) { notBefore_ = notBefore; }
 
-  MillisecondsSince1970& 
+  time::system_clock::TimePoint&
   getNotBefore() { return notBefore_; }
-  
-  const MillisecondsSince1970& 
+
+  const time::system_clock::TimePoint&
   getNotBefore() const { return notBefore_; }
 
   void
-  setNotAfter(const MillisecondsSince1970& notAfter) { notAfter_ = notAfter; }
+  setNotAfter(const time::system_clock::TimePoint& notAfter) { notAfter_ = notAfter; }
 
-  MillisecondsSince1970& 
+  time::system_clock::TimePoint&
   getNotAfter() { return notAfter_; }
 
-  const MillisecondsSince1970& 
+  const time::system_clock::TimePoint&
   getNotAfter() const { return notAfter_; }
 
   void
   setPublicKeyInfo(const PublicKey& key) { key_ = key; }
-  
-  PublicKey& 
+
+  PublicKey&
   getPublicKeyInfo() { return key_; }
 
-  const PublicKey& 
+  const PublicKey&
   getPublicKeyInfo() const { return key_; }
 
-  // virtual Name 
+  // virtual Name
   // getPublicKeyName() const = 0;
-  
+
   /**
    * Check if the certificate is valid.
    * @return True if the current time is earlier than notBefore.
    */
-  bool 
+  bool
   isTooEarly();
 
   /**
@@ -121,7 +121,7 @@
   bool
   isTooLate();
 
-  void 
+  void
   printCertificate(std::ostream &os) const;
 
 protected:
@@ -130,8 +130,8 @@
 
 protected:
   SubjectDescriptionList subjectDescriptionList_;
-  MillisecondsSince1970 notBefore_;
-  MillisecondsSince1970 notAfter_;
+  time::system_clock::TimePoint notBefore_;
+  time::system_clock::TimePoint notAfter_;
   PublicKey key_;
   ExtensionList extensionList_;
 };
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 28642ae..e58cbf9 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -124,8 +124,8 @@
   shared_ptr<IdentityCertificate>
   prepareUnsignedIdentityCertificate(const Name& keyName,
                                      const Name& signingIdentity,
-                                     const MillisecondsSince1970& notBefore,
-                                     const MillisecondsSince1970& notAfter,
+                                     const time::system_clock::TimePoint& notBefore,
+                                     const time::system_clock::TimePoint& notAfter,
                                      const std::vector<CertificateSubjectDescription>& subjectDescription)
 
   {
@@ -360,8 +360,8 @@
     certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
 
     certificate->setName(certificateName);
-    certificate->setNotBefore(getNow());
-    certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
+    certificate->setNotBefore(time::system_clock::now());
+    certificate->setNotAfter(time::system_clock::now() + time::days(7300)/* ~20 years*/);
     certificate->setPublicKeyInfo(*pubKey);
     certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
     certificate->encode();
diff --git a/src/security/sec-public-info-sqlite3.cpp b/src/security/sec-public-info-sqlite3.cpp
index 16041d3..aeb34dd 100644
--- a/src/security/sec-public-info-sqlite3.cpp
+++ b/src/security/sec-public-info-sqlite3.cpp
@@ -365,9 +365,11 @@
 //   sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
 //   sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
 
-//   // Convert from milliseconds to seconds since 1/1/1970.
-//   sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
-//   sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
+//   // Convert from time::milliseconds to time::seconds since 1/1/1970.
+// sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(
+//                                    time::toUnixTimestamp(certificate.getNotBefore()).count()));
+// sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(
+//                                    time::toUnixTimestamp(certificate.getNotAfter()).count()));
 
 //   sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
 
@@ -420,9 +422,10 @@
   sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
 
-  // Convert from milliseconds to seconds since 1/1/1970.
-  sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
-  sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
+  sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(
+                                     time::toUnixTimestamp(certificate.getNotBefore()).count()));
+  sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(
+                                     time::toUnixTimestamp(certificate.getNotAfter()).count()));
 
   sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_TRANSIENT);
 
@@ -447,7 +450,8 @@
   if (res == SQLITE_ROW)
     {
       shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
-      certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0)));
+      certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0),
+                                    sqlite3_column_bytes(statement, 0)));
       sqlite3_finalize(statement);
       return certificate;
     }
diff --git a/src/security/sec-public-info.hpp b/src/security/sec-public-info.hpp
index e1e0fbe..0861b67 100644
--- a/src/security/sec-public-info.hpp
+++ b/src/security/sec-public-info.hpp
@@ -402,7 +402,7 @@
   else
     oss << "dsk-";
 
-  oss << getNow();
+  oss << time::toUnixTimestamp(time::system_clock::now()).count();
   
   Name keyName = Name(identityName).append(oss.str());
 
diff --git a/src/transport/stream-transport.hpp b/src/transport/stream-transport.hpp
index 1bde91b..8562d88 100644
--- a/src/transport/stream-transport.hpp
+++ b/src/transport/stream-transport.hpp
@@ -86,7 +86,7 @@
     if (!m_connectionInProgress) {
       m_connectionInProgress = true;
 
-      // Wait at most 4 seconds to connect
+      // Wait at most 4 time::seconds to connect
       /// @todo Decide whether this number should be configurable
       m_connectTimer.expires_from_now(boost::posix_time::seconds(4));
       m_connectTimer.async_wait(bind(&impl::connectTimeoutHandler, this, _1));
@@ -337,7 +337,7 @@
     if (!this->m_connectionInProgress) {
       this->m_connectionInProgress = true;
 
-      // Wait at most 4 seconds to connect
+      // Wait at most 4 time::seconds to connect
       /// @todo Decide whether this number should be configurable
       this->m_connectTimer.expires_from_now(boost::posix_time::seconds(4));
       this->m_connectTimer.async_wait(bind(&impl::connectTimeoutHandler, this, _1));
diff --git a/src/util/command-interest-generator.hpp b/src/util/command-interest-generator.hpp
index 8b4d796..18bc960 100644
--- a/src/util/command-interest-generator.hpp
+++ b/src/util/command-interest-generator.hpp
@@ -25,7 +25,7 @@
   static const Name DEFAULT_CERTIFICATE_NAME;
 
   CommandInterestGenerator()
-    : m_lastTimestamp(time::now() / 1000000)
+    : m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
   {
   }
 
@@ -36,30 +36,29 @@
 
   void
   generate(Interest& interest, const Name& certificateName = Name());
-  
+
   void
   generateWithIdentity(Interest& interest, const Name& identity);
-  
+
 private:
-  int64_t m_lastTimestamp;
+  time::milliseconds m_lastTimestamp;
   KeyChain m_keyChain;
 };
 
 
 inline void
-CommandInterestGenerator::generate(Interest& interest, 
+CommandInterestGenerator::generate(Interest& interest,
 				   const Name& certificateName /*= Name()*/)
 {
-  int64_t timestamp = time::now() / 1000000;
-  while(timestamp == m_lastTimestamp)
+  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
+  while(timestamp <= m_lastTimestamp)
     {
-      usleep(1000); //Guarantee unqiueness of timestamp
-      timestamp = time::now();
+      timestamp += time::milliseconds(1);
     }
 
   Name commandInterestName = interest.getName();
   commandInterestName
-    .append(name::Component::fromNumber(timestamp))
+    .append(name::Component::fromNumber(timestamp.count()))
     .append(name::Component::fromNumber(random::generateWord64()));
   interest.setName(commandInterestName);
 
@@ -70,17 +69,19 @@
 
   m_lastTimestamp = timestamp;
 }
-  
+
 inline void
 CommandInterestGenerator::generateWithIdentity(Interest& interest, const Name& identity)
 {
-  int64_t timestamp = time::now() / 1000000;
-  if(timestamp <= m_lastTimestamp)
-    timestamp = m_lastTimestamp + 1;
+  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
+  while(timestamp <= m_lastTimestamp)
+    {
+      timestamp += time::milliseconds(1);
+    }
 
   Name commandInterestName = interest.getName();
   commandInterestName
-    .append(name::Component::fromNumber(timestamp))
+    .append(name::Component::fromNumber(timestamp.count()))
     .append(name::Component::fromNumber(random::generateWord64()));
   interest.setName(commandInterestName);
 
diff --git a/src/util/command-interest-validator.hpp b/src/util/command-interest-validator.hpp
index af8c796..257f476 100644
--- a/src/util/command-interest-validator.hpp
+++ b/src/util/command-interest-validator.hpp
@@ -24,10 +24,11 @@
 
     GRACE_INTERVAL = 3000 // ms
   };
-  
-  CommandInterestValidator(int64_t graceInterval = GRACE_INTERVAL/*ms*/) 
+
+  CommandInterestValidator(const time::milliseconds& graceInterval = time::milliseconds(static_cast<int>(GRACE_INTERVAL)))
+    : m_graceInterval(graceInterval < time::milliseconds::zero() ?
+                      time::milliseconds(static_cast<int>(GRACE_INTERVAL)) : graceInterval)
   {
-    m_graceInterval = (graceInterval < 0 ? GRACE_INTERVAL : graceInterval);
   }
 
   virtual
@@ -43,26 +44,28 @@
 
 protected:
   virtual void
-  checkPolicy (const Data& data, 
-               int stepCount, 
-               const OnDataValidated &onValidated, 
+  checkPolicy (const Data& data,
+               int stepCount,
+               const OnDataValidated &onValidated,
                const OnDataValidationFailed &onValidationFailed,
                std::vector<shared_ptr<ValidationRequest> > &nextSteps)
   {
     onValidationFailed(data.shared_from_this(), "No policy for data checking");
   }
-  
+
   virtual void
-  checkPolicy (const Interest& interest, 
-               int stepCount, 
-               const OnInterestValidated &onValidated, 
+  checkPolicy (const Interest& interest,
+               int stepCount,
+               const OnInterestValidated &onValidated,
                const OnInterestValidationFailed &onValidationFailed,
                std::vector<shared_ptr<ValidationRequest> > &nextSteps);
 private:
-  int64_t m_graceInterval; //ms
+  time::milliseconds m_graceInterval; //ms
   std::map<Name, PublicKey> m_trustAnchorsForInterest;
   std::list<SecRuleSpecific> m_trustScopeForInterest;
-  std::map<Name, uint64_t> m_lastTimestamp;
+
+  typedef std::map<Name, time::system_clock::TimePoint> LastTimestampMap;
+  LastTimestampMap m_lastTimestamp;
 };
 
 inline void
@@ -82,28 +85,28 @@
 }
 
 inline void
-CommandInterestValidator::checkPolicy (const Interest& interest, 
-                                       int stepCount, 
-                                       const OnInterestValidated &onValidated, 
+CommandInterestValidator::checkPolicy (const Interest& interest,
+                                       int stepCount,
+                                       const OnInterestValidated &onValidated,
                                        const OnInterestValidationFailed &onValidationFailed,
                                        std::vector<shared_ptr<ValidationRequest> > &nextSteps)
 {
   const Name& interestName = interest.getName();
-  
-  //Prepare 
+
+  //Prepare
   if (interestName.size() < 4)
-    return onValidationFailed(interest.shared_from_this(), 
+    return onValidationFailed(interest.shared_from_this(),
                               "Interest is not signed: " + interest.getName().toUri());
-  
-  Signature signature(interestName[POS_SIG_INFO].blockFromValue(), 
+
+  Signature signature(interestName[POS_SIG_INFO].blockFromValue(),
                       interestName[POS_SIG_VALUE].blockFromValue());
-  
+
   SignatureSha256WithRsa sig(signature);
   const Name& keyLocatorName = sig.getKeyLocator().getName();
   Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-  
+
   //Check if command is in the trusted scope
-  bool inScope = false;  
+  bool inScope = false;
   for(std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
       scopeIt != m_trustScopeForInterest.end();
       ++scopeIt)
@@ -115,23 +118,28 @@
         }
     }
   if(inScope == false)
-    return onValidationFailed(interest.shared_from_this(), 
+    return onValidationFailed(interest.shared_from_this(),
                               "Signer cannot be authorized for the command: " + keyName.toUri());
 
   //Check if timestamp is valid
-  uint64_t timestamp = interestName.get(POS_TIMESTAMP).toNumber();
-  uint64_t current = static_cast<uint64_t>(time::now()/1000000);
-  std::map<Name, uint64_t>::const_iterator timestampIt = m_lastTimestamp.find(keyName);
-  if(timestampIt == m_lastTimestamp.end())
+  time::system_clock::TimePoint interestTime = time::fromUnixTimestamp(
+                                           time::milliseconds(interestName.get(POS_TIMESTAMP).toNumber()));
+  time::system_clock::TimePoint currentTime = time::system_clock::now();
+
+  LastTimestampMap::iterator timestampIt = m_lastTimestamp.find(keyName);
+  if (timestampIt == m_lastTimestamp.end())
     {
-      if(timestamp > (current + m_graceInterval) || (timestamp + m_graceInterval) < current)
-        return onValidationFailed(interest.shared_from_this(), 
-                                  "The command is not in grace interval: " + interest.getName().toUri());
+      if (!(currentTime - m_graceInterval <= interestTime &&
+            interestTime <= currentTime + m_graceInterval))
+        {
+          return onValidationFailed(interest.shared_from_this(),
+                                    "The command is not in grace interval: " + interest.getName().toUri());
+        }
     }
-  else 
+  else
     {
-      if(m_lastTimestamp[keyName] >= timestamp)
-        return onValidationFailed(interest.shared_from_this(), 
+      if(interestTime <= timestampIt->second)
+        return onValidationFailed(interest.shared_from_this(),
                                   "The command is outdated: " + interest.getName().toUri());
     }
 
@@ -139,16 +147,22 @@
   if(!Validator::verifySignature(interestName.wireEncode().value(),
                                  interestName.wireEncode().value_size() - interestName[-1].size(),
                                  sig, m_trustAnchorsForInterest[keyName]))
-    return onValidationFailed(interest.shared_from_this(), 
+    return onValidationFailed(interest.shared_from_this(),
                               "Signature cannot be validated: " + interest.getName().toUri());
 
   //Update timestamp
-  m_lastTimestamp[keyName] = timestamp;
+  if (timestampIt == m_lastTimestamp.end())
+    {
+      m_lastTimestamp[keyName] = interestTime;
+    }
+  else
+    {
+      timestampIt->second = interestTime;
+    }
 
   return onValidated(interest.shared_from_this());
 }
 
-
 } // namespace ndn
 
 #endif // NDN_HELPERS_COMMAND_INTEREST_VALIDATOR_HPP
diff --git a/src/util/monotonic_deadline_timer.hpp b/src/util/monotonic_deadline_timer.hpp
index 3cfb05f..2b1558d 100644
--- a/src/util/monotonic_deadline_timer.hpp
+++ b/src/util/monotonic_deadline_timer.hpp
@@ -17,20 +17,20 @@
 namespace boost {
 namespace asio {
 
-template <> 
-struct time_traits<ndn::time::monotonic_clock>
+template <>
+struct time_traits<ndn::time::steady_clock::TimePoint::clock>
 {
-  typedef ndn::time::Point time_type;
-  typedef ndn::time::Duration duration_type;
+  typedef ndn::time::steady_clock::TimePoint time_type;
+  typedef ndn::time::steady_clock::TimePoint::clock::duration duration_type;
 
   static time_type
   now()
   {
-    return ndn::time::now();
+    return ndn::time::steady_clock::now();
   }
 
   static time_type
-  add(const time_type& time, const duration_type& duration) 
+  add(const time_type& time, const duration_type& duration)
   {
     return time + duration;
   }
@@ -50,13 +50,25 @@
   static boost::posix_time::time_duration
   to_posix_duration(const duration_type& duration)
   {
-    return boost::posix_time::microseconds(duration/1000);
+    return
+#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
+      boost::posix_time::nanoseconds(
+        ndn::time::duration_cast<ndn::time::nanoseconds>(duration).count())
+#else
+      boost::posix_time::microseconds(
+        ndn::time::duration_cast<ndn::time::microseconds>(duration).count())
+#endif
+      ;
   }
 };
 
-typedef basic_deadline_timer<ndn::time::monotonic_clock> monotonic_deadline_timer; 
-
 } // namespace asio
 } // namespace boost
 
+namespace ndn {
+
+typedef boost::asio::basic_deadline_timer<time::steady_clock::TimePoint::clock> monotonic_deadline_timer;
+
+} // namespace ndn
+
 #endif // NDN_UTIL_MONOTONIC_DEADLINE_TIMER_HPP
diff --git a/src/util/scheduler.cpp b/src/util/scheduler.cpp
index 388d5e7..377800f 100644
--- a/src/util/scheduler.cpp
+++ b/src/util/scheduler.cpp
@@ -47,16 +47,16 @@
   bool m_isValid;
 };
 
-Scheduler::EventInfo::EventInfo(const time::Duration& after,
-                        const time::Duration& period,
-                        const Event& event)
-  : m_scheduledTime(time::now() + after)
+Scheduler::EventInfo::EventInfo(const time::nanoseconds& after,
+                                const time::nanoseconds& period,
+                                const Event& event)
+  : m_scheduledTime(time::steady_clock::now() + after)
   , m_period(period)
   , m_event(event)
 {
 }
 
-Scheduler::EventInfo::EventInfo(const time::Point& when, const EventInfo& previousEvent)
+Scheduler::EventInfo::EventInfo(const time::steady_clock::TimePoint& when, const EventInfo& previousEvent)
   : m_scheduledTime(when)
   , m_period(previousEvent.m_period)
   , m_event(previousEvent.m_event)
@@ -64,10 +64,10 @@
 {
 }
 
-time::Duration
+time::nanoseconds
 Scheduler::EventInfo::expiresFromNow() const
 {
-  time::Point now = time::now();
+  time::steady_clock::TimePoint now = time::steady_clock::now();
   if (now > m_scheduledTime)
     return time::seconds(0); // event should be scheduled ASAP
   else
@@ -84,15 +84,15 @@
 }
 
 EventId
-Scheduler::scheduleEvent(const time::Duration& after,
+Scheduler::scheduleEvent(const time::nanoseconds& after,
                          const Event& event)
 {
   return schedulePeriodicEvent(after, time::nanoseconds(-1), event);
 }
 
 EventId
-Scheduler::schedulePeriodicEvent(const time::Duration& after,
-                                 const time::Duration& period,
+Scheduler::schedulePeriodicEvent(const time::nanoseconds& after,
+                                 const time::nanoseconds& period,
                                  const Event& event)
 {
   EventQueue::iterator i = m_events.insert(EventInfo(after, period, event));
@@ -154,13 +154,13 @@
   m_isEventExecuting = true;
 
   // process all expired events
-  time::Point now = time::now();
+  time::steady_clock::TimePoint now = time::steady_clock::now();
   while(!m_events.empty() && m_events.begin()->m_scheduledTime <= now)
     {
       EventQueue::iterator head = m_events.begin();
       
       Event event = head->m_event;
-      if (head->m_period < 0)
+      if (head->m_period < time::nanoseconds::zero())
         {
           head->m_eventId->invalidate();
           m_events.erase(head);
diff --git a/src/util/scheduler.hpp b/src/util/scheduler.hpp
index 18c3004..b7364ce 100644
--- a/src/util/scheduler.hpp
+++ b/src/util/scheduler.hpp
@@ -33,7 +33,7 @@
    * \returns EventId that can be used to cancel the scheduled event
    */
   EventId
-  scheduleEvent(const time::Duration& after, const Event& event);
+  scheduleEvent(const time::nanoseconds& after, const Event& event);
 
   /**
    * \brief Schedule periodic event that should be fired every specified period.
@@ -41,8 +41,8 @@
    * \returns EventId that can be used to cancel the scheduled event
    */
   EventId
-  schedulePeriodicEvent(const time::Duration& after,
-                        const time::Duration& period,
+  schedulePeriodicEvent(const time::nanoseconds& after,
+                        const time::nanoseconds& period,
                         const Event& event);
   
   /**
@@ -60,10 +60,11 @@
 
   struct EventInfo
   {
-    EventInfo(const time::Duration& after,
-              const time::Duration& period,
+    EventInfo(const time::nanoseconds& after,
+              const time::nanoseconds& period,
               const Event& event);
-    EventInfo(const time::Point& when, const EventInfo& previousEvent);
+
+    EventInfo(const time::steady_clock::TimePoint& when, const EventInfo& previousEvent);
 
     bool
     operator <=(const EventInfo& other) const
@@ -77,11 +78,11 @@
       return this->m_scheduledTime < other.m_scheduledTime;
     }
 
-    time::Duration
+    time::nanoseconds
     expiresFromNow() const;
     
-    time::Point m_scheduledTime;
-    time::Duration m_period;
+    time::steady_clock::TimePoint m_scheduledTime;
+    time::nanoseconds m_period;
     Event m_event;
     mutable EventId m_eventId;
   };
@@ -91,7 +92,7 @@
 
   EventQueue m_events;
   EventQueue::iterator m_scheduledEvent;
-  boost::asio::monotonic_deadline_timer m_deadlineTimer;
+  monotonic_deadline_timer m_deadlineTimer;
 
   bool m_isEventExecuting;
 };
diff --git a/src/util/time.cpp b/src/util/time.cpp
deleted file mode 100644
index 07e7f34..0000000
--- a/src/util/time.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#include "common.hpp"
-
-#include "time.hpp"
-#include <time.h>
-#include <stdexcept>
-#include <sys/time.h>
-
-namespace ndn {
-namespace time {
-
-Point
-now()
-{
-// based on suggestion from https://svn.boost.org/trac/boost/ticket/3504
-#if defined(_POSIX_TIMERS) && ( _POSIX_TIMERS > 0 ) && defined(_POSIX_MONOTONIC_CLOCK)
-
-  struct timespec t;
-  int res = clock_gettime(CLOCK_MONOTONIC, &t);
-
-  if (res == -1) {
-    throw std::runtime_error("clock_gettime");
-  }
-
-  return Point(time::seconds(t.tv_sec) + time::nanoseconds(t.tv_nsec));
-
-#else
-
-  // fallback to wall clock time
-
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-
-  if (res == -1) {
-    throw std::runtime_error("gettimeofday");
-  }
-
-  return Point(time::seconds(tv.tv_sec) + time::microseconds(tv.tv_usec));
-
-#endif
-}
-
-} // namespace time
-} // namespace ndn
diff --git a/src/util/time.hpp b/src/util/time.hpp
index e0b3727..afcb979 100644
--- a/src/util/time.hpp
+++ b/src/util/time.hpp
@@ -1,7 +1,5 @@
 /**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Copyright (C) 2013-2014 Regents of the University of California.
  * See COPYING for copyright and distribution information.
  */
 
@@ -9,228 +7,171 @@
 #define NDN_TIME_HPP
 
 #include "../common.hpp"
+#include <boost/chrono.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 namespace ndn {
-
-/**
- * A time interval represented as the number of milliseconds.
- */
-typedef int64_t Milliseconds;
-   
-/**
- * The calendar time represented as the number of milliseconds since 1/1/1970.
- */
-typedef int64_t MillisecondsSince1970;
-
-
-const boost::posix_time::ptime UNIX_EPOCH_TIME =
-  boost::posix_time::ptime (boost::gregorian::date (1970, boost::gregorian::Jan, 1));
-
-/**
- * @brief Get the current time in milliseconds since 1/1/1970, including fractions of a millisecond
- */
-inline MillisecondsSince1970 
-getNowMilliseconds()
-{
-  return (boost::posix_time::microsec_clock::universal_time() - UNIX_EPOCH_TIME).total_milliseconds();
-}
-
-inline MillisecondsSince1970 
-ndn_getNowMilliseconds()
-{
-  return getNowMilliseconds();
-}
-
-inline MillisecondsSince1970
-getNow()
-{
-  return getNowMilliseconds();
-}
-
-/**
- * Convert to the ISO string representation of the time.
- * @param time Milliseconds since 1/1/1970.
- * @return The ISO string.
- */
-inline std::string
-toIsoString(const MillisecondsSince1970& time)
-{
-  boost::posix_time::ptime boostTime = UNIX_EPOCH_TIME + boost::posix_time::milliseconds(time);
-
-  /// @todo Determine whether this is necessary at all
-  if ((time % 1000) == 0)
-    return boost::posix_time::to_iso_string(boostTime) + ".000000"; 
-  else
-    return boost::posix_time::to_iso_string(boostTime);
-}
-  
-/**
- * Convert from the ISO string representation to the internal time format.
- * @param isoString The ISO time formatted string. 
- * @return The time in milliseconds since 1/1/1970.
- */
-inline MillisecondsSince1970
-fromIsoString(const std::string& isoString)
-{
-  boost::posix_time::ptime boostTime = boost::posix_time::from_iso_string(isoString);
-  
-  return (boostTime-UNIX_EPOCH_TIME).total_milliseconds();
-}
-
 namespace time {
 
-class monotonic_clock;
+using boost::chrono::duration;
 
-/** \class Duration
- *  \brief represents a time interval
- *  Time unit is nanosecond.
+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 Duration
+class system_clock : public boost::chrono::system_clock
 {
 public:
-  Duration()
-    : m_value(0)
-  {
-  }
+  typedef time_point TimePoint;
+  typedef duration Duration;
 
-  explicit
-  Duration(int64_t value)
-    : m_value(value)
-  {
-  }
-  
-  operator int64_t&()
-  {
-    return m_value;
-  }
+  // /// \brief Get current TimePoint
+  // TimePoint
+  // now();
+}; // class system_clock
 
-  operator const int64_t&() const
-  {
-    return m_value;
-  }
-
-  Duration
-  operator+(const Duration& other) const
-  {
-    return Duration(this->m_value + other.m_value);
-  }
-  
-  Duration
-  operator-(const Duration& other) const
-  {
-    return Duration(this->m_value - other.m_value);
-  }
-
-private:
-  int64_t m_value;
-};
-
-/** \class Point
- *  \brief represents a point in time
- *  This uses monotonic 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 Point
+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:
-  Point()
-    : m_value(0)
-  {
-  }
+  typedef time_point TimePoint;
+  typedef duration Duration;
 
-  explicit
-  Point(int64_t value)
-    : m_value(value)
-  {
-  }
-  
-  operator int64_t&()
-  {
-    return m_value;
-  }
+  // /// \brief Get current TimePoint
+  // TimePoint
+  // now();
+}; // class steady_clock
 
-  operator const int64_t&() const
-  {
-    return m_value;
-  }
 
-  Point
-  operator+(const Duration& other) const
-  {
-    return Point(this->m_value + static_cast<int64_t>(other));
-  }
-  
-  Duration
-  operator-(const Point& other) const
-  {
-    return Duration(this->m_value - other.m_value);
-  }
-
-  Point
-  operator-(const Duration& other) const
-  {
-    return Point(this->m_value  - static_cast<int64_t>(other));
-  }
-  
-private:
-  int64_t m_value;
-};
-
-inline std::ostream&
-operator<<(std::ostream &os, const Duration& duration)
+/**
+ * \brief Get system_clock::TimePoint representing UNIX time epoch (00:00:00 on Jan 1, 1970)
+ */
+inline const system_clock::TimePoint&
+getUnixEpoch()
 {
-  os << static_cast<int64_t>(duration) / 1000000000.0 << " s";
-  return os;
+  static system_clock::TimePoint epoch = system_clock::from_time_t(0);
+  return epoch;
 }
 
 /**
- * \brief Get current time
- * \return{ the current time in monotonic clock }
+ * \brief Convert system_clock::TimePoint to UNIX timestamp
  */
-Point
-now();
-
-/**
- * \brief Get time::Duration for the specified number of seconds
- */
-template<class T>
-inline Duration
-seconds(T value)
+inline milliseconds
+toUnixTimestamp(const system_clock::TimePoint& point)
 {
-  return Duration(value * static_cast<int64_t>(1000000000));
+  return duration_cast<milliseconds>(point - getUnixEpoch());
 }
 
 /**
- * \brief Get time::Duration for the specified number of milliseconds
+ * \brief Convert UNIX timestamp to system_clock::TimePoint
  */
-template<class T>
-inline Duration
-milliseconds(T value)
+inline system_clock::TimePoint
+fromUnixTimestamp(const milliseconds& duration)
 {
-  return Duration(value * static_cast<int64_t>(1000000));
+  return getUnixEpoch() + duration;
 }
 
 /**
- * \brief Get time::Duration for the specified number of microseconds
+ * \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
  */
-template<class T>
-inline Duration
-microseconds(T value)
+inline std::string
+toIsoString(const system_clock::TimePoint& timePoint)
 {
-  return Duration(value * static_cast<int64_t>(1000));
+  boost::posix_time::ptime ptime = boost::posix_time::from_time_t(
+                                     system_clock::TimePoint::clock::to_time_t(timePoint));
+
+  uint64_t micro = duration_cast<microseconds>(timePoint - getUnixEpoch()).count() % 1000000;
+  if (micro > 0)
+    {
+      ptime += boost::posix_time::microseconds(micro);
+      return boost::posix_time::to_iso_string(ptime);
+    }
+  else
+    return boost::posix_time::to_iso_string(ptime);
 }
 
 /**
- * \brief Get time::Duration for the specified number of nanoseconds
+ * \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 Duration
-nanoseconds(int64_t value)
+inline system_clock::TimePoint
+fromIsoString(const std::string& isoString)
 {
-  return Duration(value);
-}
+  static boost::posix_time::ptime posixTimeEpoch = boost::posix_time::from_time_t(0);
 
+  boost::posix_time::ptime ptime = boost::posix_time::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;
+}
 
 } // namespace time
-
 } // namespace ndn
 
 #endif // NDN_TIME_HPP
diff --git a/tests-integrated/main.cpp b/tests-integrated/main.cpp
new file mode 100644
index 0000000..d43aa5a
--- /dev/null
+++ b/tests-integrated/main.cpp
@@ -0,0 +1,9 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#define BOOST_TEST_MAIN 1
+#define BOOST_TEST_DYN_LINK 1
+
+#include <boost/test/unit_test.hpp>
diff --git a/tests/test-faces.cpp b/tests-integrated/test-faces.cpp
similarity index 92%
rename from tests/test-faces.cpp
rename to tests-integrated/test-faces.cpp
index 0205cb1..03bfa9b 100644
--- a/tests/test-faces.cpp
+++ b/tests-integrated/test-faces.cpp
@@ -62,7 +62,7 @@
   expressInterest(Face& face, const Name& name)
   {
     Interest i(name);
-    i.setInterestLifetime(50);
+    i.setInterestLifetime(time::milliseconds(50));
     face.expressInterest(i,
                          bind(&FacesFixture::onData, this),
                          bind(&FacesFixture::onTimeout, this));
@@ -88,7 +88,7 @@
 {
   Face face;
 
-  face.expressInterest(Interest("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY", 1000),
+  face.expressInterest(Interest("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY", time::milliseconds(1000)),
                        ptr_lib::bind(&FacesFixture::onData, this),
                        ptr_lib::bind(&FacesFixture::onTimeout, this));
 
@@ -97,7 +97,7 @@
   BOOST_CHECK_EQUAL(dataCount, 1);
   BOOST_CHECK_EQUAL(timeoutCount, 0);
 
-  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere", 50),
+  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere", time::milliseconds(50)),
                        ptr_lib::bind(&FacesFixture::onData, this),
                        ptr_lib::bind(&FacesFixture::onTimeout, this));
   
@@ -111,7 +111,7 @@
 {
   Face face("localhost");
 
-  face.expressInterest(Interest("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY", 1000),
+  face.expressInterest(Interest("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY", time::milliseconds(1000)),
                        bind(&FacesFixture::onData, this),
                        bind(&FacesFixture::onTimeout, this));
 
@@ -120,7 +120,7 @@
   BOOST_CHECK_EQUAL(dataCount, 1);
   BOOST_CHECK_EQUAL(timeoutCount, 0);
 
-  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere", 50),
+  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere", time::milliseconds(50)),
                        bind(&FacesFixture::onData, this),
                        bind(&FacesFixture::onTimeout, this));
 
@@ -136,14 +136,14 @@
   Face face;
   Face face2(face.ioService());
   Scheduler scheduler(*face.ioService());
-  scheduler.scheduleEvent(time::seconds(0.3),
+  scheduler.scheduleEvent(time::milliseconds(300),
                           bind(&FacesFixture::terminate, this, func_lib::ref(face)));
   
   regPrefixId = face.setInterestFilter("/Hello/World",
                                        bind(&FacesFixture::onInterest, this, func_lib::ref(face)),
                                        bind(&FacesFixture::onRegFailed, this));
 
-  scheduler.scheduleEvent(time::seconds(0.2),
+  scheduler.scheduleEvent(time::milliseconds(200),
                           bind(&FacesFixture::expressInterest, this,
                                func_lib::ref(face2), Name("/Hello/World/!")));
   
@@ -172,7 +172,7 @@
                                        bind(&FacesFixture::onRegFailed, this));
 
 
-  scheduler.scheduleEvent(time::seconds(0.2),
+  scheduler.scheduleEvent(time::milliseconds(200),
                           bind(&FacesFixture::expressInterest, this,
                                func_lib::ref(face2), Name("/Hello/World/!")));
   
diff --git a/tests-integrated/wscript b/tests-integrated/wscript
new file mode 100644
index 0000000..c0466cd
--- /dev/null
+++ b/tests-integrated/wscript
@@ -0,0 +1,25 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+from waflib import Utils
+
+top = '..'
+
+def build(bld):
+    unittests = bld.program (
+        target="../integrated-tests",
+        features = "cxx cxxprogram",
+        source = bld.path.ant_glob(['**/*.cpp'],
+                                   excl = ['**/*-osx.cpp', '**/*-sqlite3.cpp']),
+        use = 'ndn-cpp-dev',
+        install_path = None,
+        )
+
+    if Utils.unversioned_sys_platform () == "darwin":
+        unittests.source += bld.path.ant_glob('**/*-osx.cpp')
+
+    # In case we want to make it optional later
+    unittests.source += bld.path.ant_glob('**/*-sqlite3.cpp')
+
+    if bld.env['WITH_PCH']:
+        unittests.pch = "test-all.hpp"
+    
diff --git a/tests/management/nfd-status.cpp b/tests/management/nfd-status.cpp
index b5d408c..ef411a4 100644
--- a/tests/management/nfd-status.cpp
+++ b/tests/management/nfd-status.cpp
@@ -18,8 +18,8 @@
 {
   Status status1;
   status1.setNfdVersion(1014210635);
-  status1.setStartTimestamp(Status::Timestamp(boost::chrono::seconds(375193249)));
-  status1.setCurrentTimestamp(Status::Timestamp(boost::chrono::seconds(1886109034)));
+  status1.setStartTimestamp(time::fromUnixTimestamp(time::seconds(375193249)));
+  status1.setCurrentTimestamp(time::fromUnixTimestamp(time::seconds(1886109034)));
   status1.setNNameTreeEntries(1849943160);
   status1.setNFibEntries(621739748);
   status1.setNPitEntries(482129741);
diff --git a/tests/management/test-ndnd-forwarding-entry.cpp b/tests/management/test-ndnd-forwarding-entry.cpp
index 1c1afb8..7ad5c94 100644
--- a/tests/management/test-ndnd-forwarding-entry.cpp
+++ b/tests/management/test-ndnd-forwarding-entry.cpp
@@ -30,7 +30,7 @@
 
 BOOST_AUTO_TEST_CASE (Encode)
 {
-  ForwardingEntry forwardingEntry("selfreg", "/a/prefix", -1, ForwardingFlags(), -1);
+  ForwardingEntry forwardingEntry("selfreg", "/a/prefix", -1, ForwardingFlags(), time::milliseconds::min());
   const Block &wire = forwardingEntry.wireEncode();
 
   BOOST_REQUIRE_EQUAL_COLLECTIONS(FORWARDING_ENTRY, FORWARDING_ENTRY+sizeof(FORWARDING_ENTRY),
@@ -54,7 +54,7 @@
   BOOST_REQUIRE_EQUAL(forwardingEntry.getForwardingFlags().getLocal(), false);
   BOOST_REQUIRE_EQUAL(forwardingEntry.getForwardingFlags().getTap(), false);
   BOOST_REQUIRE_EQUAL(forwardingEntry.getForwardingFlags().getCaptureOk(), false);
-  BOOST_REQUIRE_EQUAL(forwardingEntry.getFreshnessPeriod(), -1);
+  BOOST_REQUIRE_EQUAL(forwardingEntry.getFreshnessPeriod(), time::milliseconds::min());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/management/test-nrd.cpp b/tests/management/test-nrd.cpp
index de95ee2..92622f0 100644
--- a/tests/management/test-nrd.cpp
+++ b/tests/management/test-nrd.cpp
@@ -39,7 +39,7 @@
   std::ostringstream os;
   os << opt;
   BOOST_CHECK_EQUAL(os.str(), "PrefixRegOptions(Prefix: /localhost/reg/test, "
-                    "FaceID: 0, Flags: 1, Cost: 0, ExpirationPeriod: -1, Protocol: )");
+                    "FaceID: 0, Flags: 1, Cost: 0, ExpirationPeriod: -9223372036854775808 milliseconds, Protocol: )");
 }
 
 BOOST_AUTO_TEST_CASE (PrefixRegOptionsDecoding)
diff --git a/tests/security/test-certificate-cache.cpp b/tests/security/test-certificate-cache.cpp
index 3718170..ee7fd6f 100644
--- a/tests/security/test-certificate-cache.cpp
+++ b/tests/security/test-certificate-cache.cpp
@@ -25,17 +25,17 @@
 BOOST_AUTO_TEST_CASE (Ttl)
 {
   shared_ptr<boost::asio::io_service> io = make_shared<boost::asio::io_service>();
-  shared_ptr<CertificateCacheTtl> cache = make_shared<CertificateCacheTtl>(io, 1);
+  shared_ptr<CertificateCacheTtl> cache = make_shared<CertificateCacheTtl>(io, time::seconds(1));
   Scheduler scheduler(*io);
 
   shared_ptr<IdentityCertificate> cert1 = make_shared<IdentityCertificate>();
   Name certName1("/tmp/KEY/ksk-1/ID-CERT/1");
   cert1->setName(certName1);
-  cert1->setFreshnessPeriod(500);
+  cert1->setFreshnessPeriod(time::milliseconds(500));
   shared_ptr<IdentityCertificate> cert2 = make_shared<IdentityCertificate>();
   Name certName2("/tmp/KEY/ksk-2/ID-CERT/2");
   cert2->setName(certName2);
-  cert2->setFreshnessPeriod(1000);
+  cert2->setFreshnessPeriod(time::milliseconds(1000));
 
   Name name1 = certName1.getPrefix(-1);
   Name name2 = certName2.getPrefix(-1);
@@ -43,13 +43,13 @@
   cache->insertCertificate(cert1);
   cache->insertCertificate(cert2);
 
-  scheduler.scheduleEvent(time::seconds(0.3), bind(&getCertificateTtl, cache, name1, true));
-  scheduler.scheduleEvent(time::seconds(0.3), bind(&getCertificateTtl, cache, name2, true));
-  scheduler.scheduleEvent(time::seconds(0.6), bind(&getCertificateTtl, cache, name1, false));
-  scheduler.scheduleEvent(time::seconds(0.6), bind(&getCertificateTtl, cache, name2, true));
-  scheduler.scheduleEvent(time::seconds(0.6), bind(&CertificateCache::insertCertificate, &*cache, cert2));
-  scheduler.scheduleEvent(time::seconds(1.3), bind(&getCertificateTtl, cache, name2, true));
-  scheduler.scheduleEvent(time::seconds(1.7), bind(&getCertificateTtl, cache, name2, false));
+  scheduler.scheduleEvent(time::milliseconds(300),  bind(&getCertificateTtl, cache, name1, true));
+  scheduler.scheduleEvent(time::milliseconds(300),  bind(&getCertificateTtl, cache, name2, true));
+  scheduler.scheduleEvent(time::milliseconds(600),  bind(&getCertificateTtl, cache, name1, false));
+  scheduler.scheduleEvent(time::milliseconds(600),  bind(&getCertificateTtl, cache, name2, true));
+  scheduler.scheduleEvent(time::milliseconds(600),  bind(&CertificateCache::insertCertificate, &*cache, cert2));
+  scheduler.scheduleEvent(time::milliseconds(1300), bind(&getCertificateTtl, cache, name2, true));
+  scheduler.scheduleEvent(time::milliseconds(1700), bind(&getCertificateTtl, cache, name2, false));
 
   io->run();
 }
diff --git a/tests/security/test-encode-decode-certificate.cpp b/tests/security/test-encode-decode-certificate.cpp
index 409e757..3b8cc83 100644
--- a/tests/security/test-encode-decode-certificate.cpp
+++ b/tests/security/test-encode-decode-certificate.cpp
@@ -83,8 +83,8 @@
 const std::string CERT_INFO = "Certificate name:\n"
   "  /\n"
   "Validity:\n"
-  "  NotBefore: 20131226T232254.000000\n"
-  "  NotAfter: 20131226T232254.000000\n"
+  "  NotBefore: 20131226T232254\n"
+  "  NotAfter: 20131226T232254\n"
   "Subject Description:\n"
   "  2.5.4.41: TEST NAME\n"
   "Public key bits:\n"
@@ -98,8 +98,8 @@
   ndn::Certificate c;
 
   // validity
-  c.setNotBefore(1388100174000); // 12/26/2013 @ 11:22pm
-  c.setNotAfter(1388100174000); // 12/26/2013 @ 11:22pm
+  c.setNotBefore(time::fromUnixTimestamp(time::milliseconds(1388100174000))); // 12/26/2013 @ 11:22pm
+  c.setNotAfter(time::fromUnixTimestamp(time::milliseconds(1388100174000))); // 12/26/2013 @ 11:22pm
 
   // subject
   c.addSubjectDescription(CertificateSubjectDescription("2.5.4.41", "TEST NAME"));
@@ -131,19 +131,19 @@
   // p.Load(source);
 
   BOOST_REQUIRE_NO_THROW(c.encode());
-  
+
   // ofstream of("cert.out");
   // of.write((const char*)c.getContent().value(), c.getContent().value_size());
   
   // const Block &wire = i.wireEncode();
   BOOST_REQUIRE_EQUAL_COLLECTIONS(CERT, CERT+sizeof(CERT),
-                                c.getContent().value_begin(), c.getContent().value_end());
+                                  c.getContent().value_begin(), c.getContent().value_end());
 
   std::ostringstream os;
   os << c << std::endl;
   std::string info(os.str());
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(CERT_INFO.begin(), CERT_INFO.end(),
-                                  info.begin(), info.end());
+
+  BOOST_CHECK_EQUAL(CERT_INFO, info);
 }
 
 const unsigned char REAL_CERT[] = {
@@ -153,8 +153,8 @@
 const std::string REAL_CERT_INFO = "Certificate name:\n"
 "  /tmp\n"
 "Validity:\n"
-"  NotBefore: 20131101T171122.000000\n"
-"  NotAfter: 20141101T171122.000000\n"
+"  NotBefore: 20131101T171122\n"
+"  NotAfter: 20141101T171122\n"
 "Subject Description:\n"
 "  2.5.4.41: NDN Testbed Root\n"
 "Public key bits:\n"
@@ -176,8 +176,7 @@
   std::ostringstream os;
   os << c << std::endl;
   std::string info(os.str());
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(REAL_CERT_INFO.begin(), REAL_CERT_INFO.end(),
-                                  info.begin(), info.end());
+  BOOST_CHECK_EQUAL(REAL_CERT_INFO, info);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/security/test-keychain.cpp b/tests/security/test-keychain.cpp
index 3e9b4fc..8a76b79 100644
--- a/tests/security/test-keychain.cpp
+++ b/tests/security/test-keychain.cpp
@@ -7,7 +7,6 @@
 #include <boost/test/unit_test.hpp>
 
 #include "security/key-chain.hpp"
-#include "util/time.hpp"
 
 using namespace std;
 
@@ -19,7 +18,8 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identity(string("/TestKeyChain/ExportIdentity/") + boost::lexical_cast<std::string>(time::now()));
+  Name identity("/TestKeyChain/ExportIdentity/");
+  identity.appendVersion();
   keyChain.createIdentity(identity);
   
   shared_ptr<SecuredBag> exported = keyChain.exportIdentity(identity, "1234");
@@ -60,28 +60,30 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
   
-  Name identity(string("/TestKeyChain/PrepareIdentityCertificate/") + boost::lexical_cast<std::string>(time::now()));
+  Name identity("/TestKeyChain/PrepareIdentityCertificate/");
+  identity.appendVersion();
   keyChain.createIdentity(identity);
 
   vector<CertificateSubjectDescription> subjectDescription;
   Name lowerIdentity = identity;
-  lowerIdentity.append("Lower").append(boost::lexical_cast<std::string>(time::now()));
+  lowerIdentity.append("Lower").appendVersion();
   Name lowerKeyName = keyChain.generateRSAKeyPair(lowerIdentity, true);
   shared_ptr<IdentityCertificate> idCert
     = keyChain.prepareUnsignedIdentityCertificate(lowerKeyName, identity,
-						  time::now() / 1000000,
-						  time::now() / 1000000 + 630720000,
+						  time::system_clock::now(),
+						  time::system_clock::now() + time::days(365),
 						  subjectDescription);
   BOOST_CHECK(static_cast<bool>(idCert));
   BOOST_CHECK(idCert->getName().getPrefix(5) == Name().append(identity).append("KEY").append("Lower"));
 
 
-  Name anotherIdentity(string("/TestKeyChain/PrepareIdentityCertificate/Another/") + boost::lexical_cast<std::string>(time::now()));
+  Name anotherIdentity("/TestKeyChain/PrepareIdentityCertificate/Another/");
+  anotherIdentity.appendVersion();
   Name anotherKeyName = keyChain.generateRSAKeyPair(anotherIdentity, true);
   shared_ptr<IdentityCertificate> idCert2
     = keyChain.prepareUnsignedIdentityCertificate(anotherKeyName, identity,
-						  time::now() / 1000000,
-						  time::now() / 1000000 + 630720000,
+						  time::system_clock::now(),
+						  time::system_clock::now() + time::days(365),
 						  subjectDescription);
   BOOST_CHECK(static_cast<bool>(idCert2));
   BOOST_CHECK(idCert2->getName().getPrefix(5) == Name().append(anotherIdentity).append("KEY"));
@@ -90,8 +92,8 @@
   Name wrongKeyName1;
   shared_ptr<IdentityCertificate> idCert3
     = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName1, identity,
-						  time::now() / 1000000,
-						  time::now() / 1000000 + 630720000,
+						  time::system_clock::now(),
+						  time::system_clock::now() + time::days(365),
 						  subjectDescription);
   BOOST_CHECK(!static_cast<bool>(idCert3));
 
@@ -99,8 +101,8 @@
   Name wrongKeyName2("/TestKeyChain/PrepareIdentityCertificate");
   shared_ptr<IdentityCertificate> idCert4
     = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName2, identity,
-						  time::now() / 1000000,
-						  time::now() / 1000000 + 630720000,
+						  time::system_clock::now(),
+						  time::system_clock::now() + time::days(365),
 						  subjectDescription);
   BOOST_CHECK(!static_cast<bool>(idCert4));
   
@@ -108,8 +110,8 @@
   Name wrongKeyName3("/TestKeyChain/PrepareIdentityCertificate/ksk-1234");
   shared_ptr<IdentityCertificate> idCert5
     = keyChain.prepareUnsignedIdentityCertificate(wrongKeyName3, identity,
-						  time::now() / 1000000,
-						  time::now() / 1000000 + 630720000,
+						  time::system_clock::now(),
+						  time::system_clock::now() + time::days(365),
 						  subjectDescription);
   BOOST_CHECK(!static_cast<bool>(idCert5));
 
diff --git a/tests/security/test-sec-public-info-sqlite3.cpp b/tests/security/test-sec-public-info-sqlite3.cpp
index 8928ebf..c50183d 100644
--- a/tests/security/test-sec-public-info-sqlite3.cpp
+++ b/tests/security/test-sec-public-info-sqlite3.cpp
@@ -22,7 +22,9 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identity("/TestSecPublicInfoSqlite3/Delete/" + boost::lexical_cast<string>(time::now()));
+  Name identity("/TestSecPublicInfoSqlite3/Delete");
+  identity.appendVersion();
+
   Name certName1;
   BOOST_REQUIRE_NO_THROW(certName1 = keyChain.createIdentity(identity));
 
diff --git a/tests/security/test-sec-tpm-file.cpp b/tests/security/test-sec-tpm-file.cpp
index 146a1e1..70fada8 100644
--- a/tests/security/test-sec-tpm-file.cpp
+++ b/tests/security/test-sec-tpm-file.cpp
@@ -24,7 +24,7 @@
 {
   SecTpmFile tpm;
   
-  Name keyName("/TestSecTpmFile/Delete/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmFile/Delete/ksk-" + boost::lexical_cast<string>(time::toUnixTimestamp(time::system_clock::now())));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
@@ -40,7 +40,7 @@
 {
   SecTpmFile tpm;
 
-  Name keyName("/TestSecTpmFile/SignVerify/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmFile/SignVerify/ksk-" + boost::lexical_cast<string>(time::toUnixTimestamp(time::system_clock::now())));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   Data data("/tmp/test/1");
@@ -107,7 +107,7 @@
 
   SecTpmFile tpm;
 
-  Name keyName("/TestSecTpmFile/ImportKey/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmFile/ImportKey/ksk-" + boost::lexical_cast<string>(time::toUnixTimestamp(time::system_clock::now())));
 
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
diff --git a/tests/security/test-sec-tpm-osx.cpp b/tests/security/test-sec-tpm-osx.cpp
index d75eec1..a08dc48 100644
--- a/tests/security/test-sec-tpm-osx.cpp
+++ b/tests/security/test-sec-tpm-osx.cpp
@@ -25,7 +25,8 @@
 {
   SecTpmOsx tpm;
   
-  Name keyName("/TestSecTpmOsx/Delete/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmOsx/Delete/ksk-" + boost::lexical_cast<string>(
+                                                time::toUnixTimestamp(time::system_clock::now()).count()));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
@@ -41,7 +42,8 @@
 {
   SecTpmOsx tpm;
 
-  Name keyName("/TestSecTpmOsx/SignVerify/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmOsx/SignVerify/ksk-" + boost::lexical_cast<string>(
+                                                    time::toUnixTimestamp(time::system_clock::now()).count()));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   Data data("/TestSecTpmOsx/SignVaerify/Data/1");
@@ -102,7 +104,8 @@
 
   SecTpmOsx tpm;
 
-  Name keyName("/TestSecTpmOsx/ExportImportKey/ksk-" + boost::lexical_cast<string>(time::now()));
+  Name keyName("/TestSecTpmOsx/ExportImportKey/ksk-" + boost::lexical_cast<string>(
+                                                         time::toUnixTimestamp(time::system_clock::now()).count()));
   
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
 
diff --git a/tests/security/test-signed-interest.cpp b/tests/security/test-signed-interest.cpp
index f6898b9..db051c3 100644
--- a/tests/security/test-signed-interest.cpp
+++ b/tests/security/test-signed-interest.cpp
@@ -21,22 +21,24 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identityName("/TestSignedInterest/SignVerify/" + boost::lexical_cast<string>(time::now()));
+  Name identityName("/TestSignedInterest/SignVerify");
+  identityName.appendVersion();
+
   Name certificateName;
   BOOST_REQUIRE_NO_THROW(certificateName = keyChain.createIdentity(identityName));
 
   Interest interest("/TestSignedInterest/SignVerify/Interest1");
   BOOST_CHECK_NO_THROW(keyChain.signByIdentity(interest, identityName));
-  
+
   Block interestBlock(interest.wireEncode().wire(), interest.wireEncode().size());
 
   Interest interest2;
   interest2.wireDecode(interestBlock);
-  
+
   shared_ptr<PublicKey> publicKey;
   BOOST_REQUIRE_NO_THROW(publicKey = keyChain.getPublicKeyFromTpm(keyChain.getDefaultKeyNameForIdentity(identityName)));
   bool result = Validator::verifySignature(interest2, *publicKey);
-  
+
   BOOST_CHECK_EQUAL(result, true);
 
   keyChain.deleteIdentity(identityName);
@@ -48,7 +50,7 @@
   CommandInterestFixture()
     : m_validity(false)
   {}
-  
+
   void
   validated(const shared_ptr<const Interest>& interest)
   { m_validity = true; }
@@ -56,7 +58,7 @@
   void
   validationFailed(const shared_ptr<const Interest>& interest, const string& failureInfo)
   {
-    m_validity = false; 
+    m_validity = false;
   }
 
   void
@@ -64,12 +66,14 @@
   { m_validity = false; }
 
   bool m_validity;
-}; 
+};
 
 BOOST_FIXTURE_TEST_CASE (CommandInterest, CommandInterestFixture)
 {
   KeyChain keyChain;
-  Name identity("/TestCommandInterest/Validation/" + boost::lexical_cast<string>(time::now()));
+  Name identity("/TestCommandInterest/Validation");
+  identity.appendVersion();
+
   Name certName;
   BOOST_REQUIRE_NO_THROW(certName = keyChain.createIdentity(identity));
 
@@ -84,38 +88,39 @@
   validator.validate(*commandInterest1,
   		     bind(&CommandInterestFixture::validated, this, _1),
   		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
-  
+
   BOOST_CHECK_EQUAL(m_validity, true);
-  
+
   //Test an outdated command
   reset();
   shared_ptr<Interest> commandInterest2 = make_shared<Interest>("/TestCommandInterest/Validation/Command2");
-  int64_t timestamp = time::now() / 1000000;
-  timestamp -= 5000;
+  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
+  timestamp -= time::seconds(5);
+
   Name commandName = commandInterest2->getName();
   commandName
-    .append(name::Component::fromNumber(timestamp))
-    .append(name::Component::fromNumber(random::generateWord64()));
+    .appendNumber(timestamp.count())
+    .appendNumber(random::generateWord64());
   commandInterest2->setName(commandName);
-  
+
   keyChain.signByIdentity(*commandInterest2, identity);
   validator.validate(*commandInterest2,
   		     bind(&CommandInterestFixture::validated, this, _1),
   		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
-  
+
   BOOST_CHECK_EQUAL(m_validity, false);
-  
+
   //Test an unauthorized command
   Name identity2("/TestCommandInterest/Validation2");
   Name certName2;
   BOOST_REQUIRE_NO_THROW(certName2 = keyChain.createIdentity(identity2));
-  
+
   shared_ptr<Interest> commandInterest3 = make_shared<Interest>("/TestCommandInterest/Validation/Command3");
   generator.generateWithIdentity(*commandInterest3, identity2);
   validator.validate(*commandInterest3,
   		     bind(&CommandInterestFixture::validated, this, _1),
   		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
-  
+
   BOOST_CHECK_EQUAL(m_validity, false);
 
   //Test another unauthorized command
@@ -124,7 +129,7 @@
   validator.validate(*commandInterest4,
   		     bind(&CommandInterestFixture::validated, this, _1),
   		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
-  
+
   BOOST_CHECK_EQUAL(m_validity, false);
 
   BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity));
diff --git a/tests/security/test-validator.cpp b/tests/security/test-validator.cpp
index bf55bda..c909c06 100644
--- a/tests/security/test-validator.cpp
+++ b/tests/security/test-validator.cpp
@@ -31,7 +31,9 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identity("/TestValidator/Null/" + boost::lexical_cast<std::string>(time::now()));
+  Name identity("/TestValidator/Null");
+  identity.appendVersion();
+
   BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
 
   Name dataName = identity;
diff --git a/tests/test-data.cpp b/tests/test-data.cpp
index b5b2083..19241b5 100644
--- a/tests/test-data.cpp
+++ b/tests/test-data.cpp
@@ -118,7 +118,7 @@
 
   BOOST_REQUIRE_EQUAL(d.getName().toUri(), "/local/ndn/prefix");
   BOOST_REQUIRE_EQUAL(d.getContentType(), static_cast<uint32_t>(MetaInfo::TYPE_DEFAULT));
-  BOOST_REQUIRE_EQUAL(d.getFreshnessPeriod(), 10000);
+  BOOST_REQUIRE_EQUAL(d.getFreshnessPeriod(), time::seconds(10));
 
   BOOST_REQUIRE_EQUAL(std::string(reinterpret_cast<const char*>(d.getContent().value()), d.getContent().value_size()), "SUCCESS!");
 
@@ -143,7 +143,7 @@
   
   ndn::Data d(ndn::Name("/local/ndn/prefix"));
   d.setContentType(MetaInfo::TYPE_DEFAULT);
-  d.setFreshnessPeriod(10000);
+  d.setFreshnessPeriod(time::seconds(10));
   
   d.setContent(Content1, sizeof(Content1));
 
@@ -201,7 +201,7 @@
 {
   MetaInfo meta;
   meta.setType(MetaInfo::TYPE_DEFAULT);
-  meta.setFreshnessPeriod(10000);
+  meta.setFreshnessPeriod(time::seconds(10));
 
   BOOST_REQUIRE_NO_THROW(meta.wireEncode());
   BOOST_REQUIRE_EQUAL_COLLECTIONS(MetaInfo1, MetaInfo1+sizeof(MetaInfo1),
@@ -222,17 +222,17 @@
 {
   MetaInfo meta(Block(MetaInfo1, sizeof(MetaInfo1)));
   BOOST_CHECK_EQUAL(meta.getType(), static_cast<uint32_t>(MetaInfo::TYPE_DEFAULT));
-  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), 10000);
+  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), time::seconds(10));
   BOOST_CHECK_EQUAL(meta.getFinalBlockId(), name::Component());
 
   meta.wireDecode(Block(MetaInfo2, sizeof(MetaInfo2)));
   BOOST_CHECK_EQUAL(meta.getType(), static_cast<uint32_t>(MetaInfo::TYPE_DEFAULT));
-  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), 10000);
+  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), time::seconds(10));
   BOOST_CHECK_EQUAL(meta.getFinalBlockId(), name::Component("hello,world!"));
 
   meta.wireDecode(Block(MetaInfo3, sizeof(MetaInfo3)));
   BOOST_CHECK_EQUAL(meta.getType(), static_cast<uint32_t>(MetaInfo::TYPE_LINK));
-  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), 10000);
+  BOOST_CHECK_EQUAL(meta.getFreshnessPeriod(), time::seconds(10));
   BOOST_CHECK_EQUAL(meta.getFinalBlockId(), name::Component("hello,world!"));
 }
 
diff --git a/tests/test-interest.cpp b/tests/test-interest.cpp
index 0c2db34..eca8066 100644
--- a/tests/test-interest.cpp
+++ b/tests/test-interest.cpp
@@ -63,7 +63,7 @@
 
   BOOST_REQUIRE_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
   BOOST_REQUIRE_EQUAL(i.getScope(), 1);
-  BOOST_REQUIRE_EQUAL(i.getInterestLifetime(), 1000);
+  BOOST_REQUIRE_EQUAL(i.getInterestLifetime(), time::milliseconds(1000));
   BOOST_REQUIRE_EQUAL(i.getMinSuffixComponents(), 1);
   BOOST_REQUIRE_EQUAL(i.getMaxSuffixComponents(), 1);
   BOOST_REQUIRE_EQUAL(i.getChildSelector(), 1);
@@ -83,7 +83,7 @@
 
   BOOST_REQUIRE_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
   BOOST_REQUIRE_EQUAL(i.getScope(), 1);
-  BOOST_REQUIRE_EQUAL(i.getInterestLifetime(), 1000);
+  BOOST_REQUIRE_EQUAL(i.getInterestLifetime(), time::milliseconds(1000));
   BOOST_REQUIRE_EQUAL(i.getMinSuffixComponents(), 1);
   BOOST_REQUIRE_EQUAL(i.getMaxSuffixComponents(), 1);
   BOOST_REQUIRE_EQUAL(i.getChildSelector(), 1);
@@ -96,7 +96,7 @@
 {
   ndn::Interest i(ndn::Name("/local/ndn/prefix"));
   i.setScope(1);
-  i.setInterestLifetime(1000);
+  i.setInterestLifetime(time::milliseconds(1000));
   i.setMinSuffixComponents(1);
   i.setMaxSuffixComponents(1);
   i.setChildSelector(1);
diff --git a/tests/util/test-io.cpp b/tests/util/test-io.cpp
index acbdc38..1e8b0bd 100644
--- a/tests/util/test-io.cpp
+++ b/tests/util/test-io.cpp
@@ -16,7 +16,9 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keychain;
 
-  Name identity("/TestIO/Basic/" + boost::lexical_cast<std::string>(time::now()));
+  Name identity("/TestIO/Basic");
+  identity.appendVersion();
+
   Name certName;
   BOOST_REQUIRE_NO_THROW(certName = keychain.createIdentity(identity));
   shared_ptr<IdentityCertificate> idCert;
diff --git a/tests/util/test-scheduler.cpp b/tests/util/test-scheduler.cpp
index 957ad98..66417da 100644
--- a/tests/util/test-scheduler.cpp
+++ b/tests/util/test-scheduler.cpp
@@ -21,7 +21,7 @@
     , count4(0)
   {
   }
-    
+
   void
   event1()
   {
@@ -47,7 +47,7 @@
   {
     ++count4;
   }
-  
+
   int count1;
   int count2;
   int count3;
@@ -56,22 +56,22 @@
 
 BOOST_FIXTURE_TEST_CASE(Events, SchedulerFixture)
 {
-  boost::asio::io_service io; 
+  boost::asio::io_service io;
 
   Scheduler scheduler(io);
-  scheduler.scheduleEvent(time::seconds(0.5), bind(&SchedulerFixture::event1, this));
-  
-  EventId i = scheduler.scheduleEvent(time::seconds(1.0), bind(&SchedulerFixture::event2, this));
+  scheduler.scheduleEvent(time::milliseconds(500), bind(&SchedulerFixture::event1, this));
+
+  EventId i = scheduler.scheduleEvent(time::seconds(1), bind(&SchedulerFixture::event2, this));
   scheduler.cancelEvent(i);
 
-  scheduler.scheduleEvent(time::seconds(0.25), bind(&SchedulerFixture::event3, this));
+  scheduler.scheduleEvent(time::milliseconds(250), bind(&SchedulerFixture::event3, this));
 
-  i = scheduler.scheduleEvent(time::seconds(0.05), bind(&SchedulerFixture::event2, this));
+  i = scheduler.scheduleEvent(time::milliseconds(50), bind(&SchedulerFixture::event2, this));
   scheduler.cancelEvent(i);
 
-  i = scheduler.schedulePeriodicEvent(time::seconds(1.5), time::seconds(0.5), bind(&SchedulerFixture::event4, this));
+  i = scheduler.schedulePeriodicEvent(time::milliseconds(1500), time::milliseconds(500), bind(&SchedulerFixture::event4, this));
   scheduler.scheduleEvent(time::seconds(4), bind(&Scheduler::cancelEvent, &scheduler, i));
-  
+
   io.run();
 
   BOOST_CHECK_EQUAL(count1, 1);
@@ -82,9 +82,9 @@
 
 BOOST_AUTO_TEST_CASE(CancelEmptyEvent)
 {
-  boost::asio::io_service io; 
+  boost::asio::io_service io;
   Scheduler scheduler(io);
-  
+
   EventId i;
   scheduler.cancelEvent(i);
 }
@@ -109,7 +109,7 @@
 
 BOOST_FIXTURE_TEST_CASE(SelfCancel, SelfCancelFixture)
 {
-  m_selfEventId = m_scheduler.scheduleEvent(time::seconds(0.1),
+  m_selfEventId = m_scheduler.scheduleEvent(time::milliseconds(100),
                                             bind(&SelfCancelFixture::cancelSelf, this));
 
   BOOST_REQUIRE_NO_THROW(m_io.run());
@@ -126,8 +126,8 @@
   void
   reschedule()
   {
-    EventId eventId = m_scheduler.scheduleEvent(time::seconds(0.1),
-                                                  bind(&SelfRescheduleFixture::reschedule, this));
+    EventId eventId = m_scheduler.scheduleEvent(time::milliseconds(100),
+                                                bind(&SelfRescheduleFixture::reschedule, this));
     m_scheduler.cancelEvent(m_selfEventId);
     m_selfEventId = eventId;
 
@@ -141,11 +141,11 @@
   reschedule2()
   {
     m_scheduler.cancelEvent(m_selfEventId);
-    
-    
+
+
     if(m_count < 5)
       {
-        m_selfEventId = m_scheduler.scheduleEvent(time::seconds(0.1),
+        m_selfEventId = m_scheduler.scheduleEvent(time::milliseconds(100),
                                                   bind(&SelfRescheduleFixture::reschedule2, this));
         m_count++;
       }
@@ -156,23 +156,23 @@
   {
     m_count++;
   }
-  
+
   void
   reschedule3()
   {
     m_scheduler.cancelEvent(m_selfEventId);
-    
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
-    m_scheduler.scheduleEvent(time::seconds(0.1),
+    m_scheduler.scheduleEvent(time::milliseconds(100),
                               bind(&SelfRescheduleFixture::doNothing, this));
   }
 
@@ -180,7 +180,7 @@
   Scheduler m_scheduler;
   EventId m_selfEventId;
   int m_count;
-  
+
 };
 
 BOOST_FIXTURE_TEST_CASE(Reschedule, SelfRescheduleFixture)
diff --git a/tests/util/test-time.cpp b/tests/util/test-time.cpp
index be4cc77..6351bb1 100644
--- a/tests/util/test-time.cpp
+++ b/tests/util/test-time.cpp
@@ -11,15 +11,27 @@
 
 BOOST_AUTO_TEST_SUITE(TestTime)
 
-BOOST_AUTO_TEST_CASE (Simple)
+BOOST_AUTO_TEST_CASE (SystemClock)
 {
-  MillisecondsSince1970 value = getNowMilliseconds();
-  BOOST_CHECK_GT(value, 1390966967032);
+  time::system_clock::TimePoint value = time::system_clock::now();
+  time::system_clock::TimePoint referenceTime =
+    time::fromUnixTimestamp(time::milliseconds(1390966967032));
 
-  BOOST_CHECK_EQUAL(toIsoString(1390966967032), "20140129T034247.032000");
-  BOOST_CHECK_EQUAL(fromIsoString("20140129T034247.032000"), 1390966967032);
+  BOOST_CHECK_GT(value, referenceTime);
 
-  BOOST_CHECK_EQUAL(fromIsoString("20140129T034247.032000Z"), 1390966967032);
+  BOOST_CHECK_EQUAL(time::toIsoString(referenceTime), "20140129T034247.032000");
+  BOOST_CHECK_EQUAL(time::fromIsoString("20140129T034247.032000"), referenceTime);
+
+  BOOST_CHECK_EQUAL(time::fromIsoString("20140129T034247.032000Z"), referenceTime);
+}
+
+BOOST_AUTO_TEST_CASE (SteadyClock)
+{
+  time::steady_clock::TimePoint oldValue = time::steady_clock::now();
+  usleep(100);
+  time::steady_clock::TimePoint newValue = time::steady_clock::now();
+
+  BOOST_CHECK_GT(newValue, oldValue);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tools/ndncatchunks3.cpp b/tools/ndncatchunks3.cpp
index c912f26..cb4750a 100644
--- a/tools/ndncatchunks3.cpp
+++ b/tools/ndncatchunks3.cpp
@@ -18,36 +18,39 @@
  * Author: Wentao Shang <wentao@cs.ucla.edu>
  */
 
-
 #include "face.hpp"
 
 class Consumer
 {
 public:
-  Consumer (const std::string &data_name, int pipe_size, int total_seg, int scope = -1, bool mustBeFresh = true)
-    : m_data_name (data_name), m_pipe_size (pipe_size), m_total_seg (total_seg),
-      m_next_seg (0), m_total_size (0), m_output (false)
-	  , m_scope(scope)
-      , m_mustBeFresh(mustBeFresh)
+  Consumer(const std::string& data_name, int pipe_size, int total_seg, int scope = -1, bool mustBeFresh = true)
+    : m_data_name (data_name)
+    , m_pipe_size (pipe_size)
+    , m_total_seg (total_seg)
+    , m_next_seg (0)
+    , m_total_size (0)
+    , m_output (false)
+    , m_scope(scope)
+    , m_mustBeFresh(mustBeFresh)
   {
   }
 
   inline void
-  enable_output ()
+  enable_output()
   {
     m_output = true;
   }
 
   void
-  run ();
-  
+  run();
+
 private:
   void
-  on_data (const ndn::Interest& interest, ndn::Data& data);
+  on_data(const ndn::Interest& interest, ndn::Data& data);
 
   void
-  on_timeout (const ndn::Interest& interest);
-  
+  on_timeout(const ndn::Interest& interest);
+
   ndn::Face m_face;
   ndn::Name m_data_name;
   int m_pipe_size;
@@ -61,25 +64,25 @@
 };
 
 void
-Consumer::run ()
+Consumer::run()
 {
   try
     {
       for (int i = 0; i < m_pipe_size; i++)
 	{
-	  ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
-	  inst.setInterestLifetime (4000);
+	  ndn::Interest interest(ndn::Name(m_data_name).appendSegment (m_next_seg++));
+	  interest.setInterestLifetime(ndn::time::milliseconds(4000));
 	  if (m_scope >= 0)
-		  inst.setScope (m_scope);
-	  inst.setMustBeFresh (m_mustBeFresh);
-	  
-	  m_face.expressInterest (inst,
-				  ndn::bind (&Consumer::on_data, this, _1, _2),
-				  ndn::bind (&Consumer::on_timeout, this, _1));
+            interest.setScope(m_scope);
+	  interest.setMustBeFresh(m_mustBeFresh);
+
+	  m_face.expressInterest (interest,
+				  ndn::bind(&Consumer::on_data, this, _1, _2),
+				  ndn::bind(&Consumer::on_timeout, this, _1));
 	}
-      
+
       // processEvents will block until the requested data received or timeout occurs
-      m_face.processEvents ();
+      m_face.processEvents();
     }
   catch (std::exception& e)
     {
@@ -88,10 +91,10 @@
 }
 
 void
-Consumer::on_data (const ndn::Interest& interest, ndn::Data& data)
+Consumer::on_data(const ndn::Interest& interest, ndn::Data& data)
 {
-  const ndn::Block& content = data.getContent ();
-  const ndn::Name& name = data.getName ();
+  const ndn::Block& content = data.getContent();
+  const ndn::Name& name = data.getName();
 
   if (m_output)
     {
@@ -99,8 +102,8 @@
     }
 
   m_total_size += content.value_size ();
-  
-  if ((int) (name.rbegin ()->toSegment ()) + 1 == m_total_seg)
+
+  if ((int)(name.rbegin ()->toSegment ()) + 1 == m_total_seg)
     {
       std::cerr << "Last segment received." << std::endl;
       std::cerr << "Total # bytes of content received: " << m_total_size << std::endl;
@@ -108,21 +111,21 @@
   else
     {
       // Send interest for next segment
-      ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
-	  if (m_scope >= 0)
-	      inst.setScope (m_scope);
-      inst.setInterestLifetime (4000);
-      inst.setMustBeFresh (m_mustBeFresh);
-      
-      m_face.expressInterest (inst,
-			      ndn::bind (&Consumer::on_data, this, _1, _2),
-			      ndn::bind (&Consumer::on_timeout, this, _1));  
+      ndn::Interest interest(ndn::Name(m_data_name).appendSegment (m_next_seg++));
+      if (m_scope >= 0)
+        interest.setScope(m_scope);
+      interest.setInterestLifetime(ndn::time::milliseconds(4000));
+      interest.setMustBeFresh(m_mustBeFresh);
+
+      m_face.expressInterest (interest,
+			      ndn::bind(&Consumer::on_data, this, _1, _2),
+			      ndn::bind(&Consumer::on_timeout, this, _1));
     }
 }
 
 
 void
-Consumer::on_timeout (const ndn::Interest& interest)
+Consumer::on_timeout(const ndn::Interest& interest)
 {
   //XXX: currently no retrans
   std::cerr << "TIMEOUT: last interest sent for segment #" << (m_next_seg - 1) << std::endl;
@@ -138,7 +141,7 @@
 
 
 int
-main (int argc, char **argv)
+main(int argc, char **argv)
 {
   std::string name;
   int pipe_size = 1;
@@ -165,7 +168,7 @@
 	case 'o':
 	  output = true;
 	  break;
-        default: 
+        default:
 	  return usage(argv[0]);
         }
     }
@@ -174,17 +177,17 @@
     {
       name = argv[optind];
     }
-  
+
   if (name.empty())
     {
       return usage(argv[0]);
     }
-  
+
   Consumer consumer (name, pipe_size, total_seg);
 
   if (output)
     consumer.enable_output ();
-  
+
   consumer.run ();
 
   return 0;
diff --git a/tools/ndnputchunks3.cpp b/tools/ndnputchunks3.cpp
index be03453..d631798 100644
--- a/tools/ndnputchunks3.cpp
+++ b/tools/ndnputchunks3.cpp
@@ -26,23 +26,23 @@
 class Producer
 {
 public:
-  Producer (const char* name)
-  : m_name (name)
-  , m_verbose (false)
+  Producer(const char* name)
+    : m_name(name)
+    , m_verbose(false)
   {
     int segnum = 0;
     char* buf = new char[MAX_SEG_SIZE];
     do
       {
-        std::cin.read (buf, MAX_SEG_SIZE);
+        std::cin.read(buf, MAX_SEG_SIZE);
         int got = std::cin.gcount ();
 
         if (got > 0)
           {
             ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data> (ndn::Name(m_name).appendSegment (segnum));
-            data->setFreshnessPeriod (10000); // 10 sec
-            data->setContent (reinterpret_cast<const uint8_t*>(buf), got);
-            
+            data->setFreshnessPeriod(ndn::time::milliseconds(10000)); // 10 sec
+            data->setContent(reinterpret_cast<const uint8_t*>(buf), got);
+
             m_keychain.sign(*data);
             m_store.push_back(data);
             segnum++;
@@ -55,76 +55,77 @@
   }
 
   void
-  onInterest (const ndn::Name& name, const ndn::Interest& interest)
+  onInterest(const ndn::Name& name, const ndn::Interest& interest)
   {
     if (m_verbose)
       std::cerr << "<< I: " << interest << std::endl;
-    
-    size_t segnum = static_cast<size_t>(interest.getName ().rbegin ()->toSegment ());
+
+    size_t segnum = static_cast<size_t>(interest.getName().rbegin()->toSegment());
 
     if (segnum < m_store.size())
       {
-        m_face.put (*m_store[segnum]);
+        m_face.put(*m_store[segnum]);
       }
   }
 
   void
-  onRegisterFailed (const ndn::Name& prefix, const std::string& reason)
+  onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
   {
     std::cerr << "ERROR: Failed to register prefix in local hub's daemon (" << reason << ")" << std::endl;
-    m_face.shutdown ();
+    m_face.shutdown();
   }
-  
+
   void
-  run ()
+  run()
   {
     if (m_store.empty())
       {
         std::cerr << "Nothing to serve. Exiting." << std::endl;
         return;
       }
-    
-    m_face.setInterestFilter (m_name,
-                              ndn::bind (&Producer::onInterest, this, _1, _2),
-                              ndn::bind (&Producer::onRegisterFailed, this, _1, _2));
-    m_face.processEvents ();
+
+    m_face.setInterestFilter(m_name,
+                             ndn::bind(&Producer::onInterest, this, _1, _2),
+                             ndn::bind(&Producer::onRegisterFailed, this, _1, _2));
+    m_face.processEvents();
   }
 
 private:
   ndn::Name m_name;
   ndn::Face m_face;
   ndn::KeyChain m_keychain;
-  
+
   std::vector< ndn::shared_ptr<ndn::Data> > m_store;
 
   bool m_verbose;
 };
 
 int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
 {
   if (argc < 2)
     {
       std::cerr << "Usage: ./ndnputchunks [data_prefix]\n";
       return -1;
     }
-  
+
   try
     {
-      ndn::MillisecondsSince1970 time = ndn::getNow();
-      
+      ndn::time::steady_clock::TimePoint startTime = ndn::time::steady_clock::now();
+
       std::cerr << "Preparing the input..." << std::endl;
-      Producer producer (argv[1]);
-      std::cerr << "Ready... (took " << ((ndn::getNow() - time)/1000) << " seconds)" << std::endl;
-      while(true)
+      Producer producer(argv[1]);
+      std::cerr << "Ready... (took " << (ndn::time::steady_clock::now() - startTime) << std::endl;
+
+      while (true)
         {
           try
             {
-              producer.run (); // this will exit when daemon dies... so try to connect again if possible
+              producer.run(); // this will exit when daemon dies... so try to connect again if possible
             }
           catch (std::exception& e)
             {
-              std::cerr << "ERROR: " << e.what () << std::endl;
+              std::cerr << "ERROR: " << e.what() << std::endl;
               // and keep going
               sleep (1);
             }
@@ -132,7 +133,7 @@
     }
   catch (std::exception& e)
     {
-      std::cerr << "ERROR: " << e.what () << std::endl;
+      std::cerr << "ERROR: " << e.what() << std::endl;
     }
   return 0;
 }
diff --git a/tools/ndnsec-cert-gen.hpp b/tools/ndnsec-cert-gen.hpp
index 023df7e..8b6e460 100644
--- a/tools/ndnsec-cert-gen.hpp
+++ b/tools/ndnsec-cert-gen.hpp
@@ -103,26 +103,26 @@
       return 1;
     }
 
-  Time notBefore;
-  Time notAfter;
+  time::system_clock::TimePoint notBefore;
+  time::system_clock::TimePoint notAfter;
   try{
     if (0 == vm.count("not-before"))
       {
-        notBefore = boost::posix_time::second_clock::universal_time();
+        notBefore = time::system_clock::now();
       }
     else
       {
-        notBefore = boost::posix_time::from_iso_string(notBeforeStr.substr(0, 8) + "T" + notBeforeStr.substr(8, 6));
+        notBefore = time::fromIsoString(notBeforeStr.substr(0, 8) + "T" + notBeforeStr.substr(8, 6));
       }
 
 
     if (0 == vm.count("not-after"))
       {
-        notAfter = notBefore + boost::posix_time::hours(24*365);
+        notAfter = notBefore + time::days(365);
       }
     else
       {
-        notAfter = boost::posix_time::from_iso_string(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6));
+        notAfter = time::fromIsoString(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6));
         if(notAfter < notBefore)
           {
             std::cerr << "not-before is later than not-after" << std::endl;
@@ -195,8 +195,8 @@
           CertificateSubjectDescription subDescryptName("2.5.4.41", sName);
           IdentityCertificate certificate;
           certificate.setName(certName);
-          certificate.setNotBefore((notBefore-ndn::UNIX_EPOCH_TIME).total_milliseconds());
-          certificate.setNotAfter((notAfter-ndn::UNIX_EPOCH_TIME).total_milliseconds());
+          certificate.setNotBefore(notBefore);
+          certificate.setNotAfter(notAfter);
           certificate.setPublicKeyInfo(selfSignedCertificate->getPublicKeyInfo());
           certificate.addSubjectDescription(subDescryptName);
           for(int i = 0; i < otherSubDescrypt.size(); i++)
diff --git a/wscript b/wscript
index 65db4a7..76d9ce7 100644
--- a/wscript
+++ b/wscript
@@ -197,6 +197,7 @@
     # Unit tests
     if bld.env['WITH_TESTS']:
         bld.recurse('tests')
+        bld.recurse('tests-integrated')
 
     if bld.env['WITH_TOOLS']:
         bld.recurse("tools examples")