Implement timestampMilliseconds
diff --git a/ndn-cpp/ContentObject.cpp b/ndn-cpp/ContentObject.cpp
index e675e5a..637c066 100644
--- a/ndn-cpp/ContentObject.cpp
+++ b/ndn-cpp/ContentObject.cpp
@@ -41,7 +41,7 @@
 void SignedInfo::get(struct ndn_SignedInfo &signedInfoStruct) const 
 {
   publisherPublicKeyDigest_.get(signedInfoStruct.publisherPublicKeyDigest);
-  // TODO: Implement timestamp
+  signedInfoStruct.timestampMilliseconds = timestampMilliseconds_;
   signedInfoStruct.type = type_;
   signedInfoStruct.freshnessSeconds = freshnessSeconds_;
   
@@ -57,7 +57,7 @@
 void SignedInfo::set(const struct ndn_SignedInfo &signedInfoStruct)
 {
   publisherPublicKeyDigest_.set(signedInfoStruct.publisherPublicKeyDigest);
-  // TODO: Implement timestamp
+  timestampMilliseconds_ = signedInfoStruct.timestampMilliseconds;
   type_ = signedInfoStruct.type;
   freshnessSeconds_ = signedInfoStruct.freshnessSeconds;
   setVector(finalBlockID_, signedInfoStruct.finalBlockID, signedInfoStruct.finalBlockIDLength);
diff --git a/ndn-cpp/ContentObject.hpp b/ndn-cpp/ContentObject.hpp
index 9cf1c3d..6bd5a80 100644
--- a/ndn-cpp/ContentObject.hpp
+++ b/ndn-cpp/ContentObject.hpp
@@ -63,7 +63,7 @@
 
   const PublisherPublicKeyDigest &getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
   
-  // TODO: Implement timestamp
+  double getTimestampMilliseconds() const { return timestampMilliseconds_; }
   
   int getType() const { return type_; }
   
@@ -75,10 +75,10 @@
   
 private:
   PublisherPublicKeyDigest publisherPublicKeyDigest_;
-  // TODO: Implement timestamp
-  int type_;
-  int freshnessSeconds_;
-  std::vector<unsigned char> finalBlockID_;
+  double timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
+  int type_;                     /**< default is ndn_ContentType_DATA. -1 for none */
+  int freshnessSeconds_;         /**< -1 for none */
+  std::vector<unsigned char> finalBlockID_; /** size 0 for none */
   KeyLocator keyLocator_;
 };
   
diff --git a/ndn-cpp/c/ContentObject.h b/ndn-cpp/c/ContentObject.h
index 4d46e53..36ede14 100644
--- a/ndn-cpp/c/ContentObject.h
+++ b/ndn-cpp/c/ContentObject.h
@@ -44,11 +44,11 @@
 
 struct ndn_SignedInfo {
   struct ndn_PublisherPublicKeyDigest publisherPublicKeyDigest;
-  // TODO: Implement timestamp
-  int type;              /**< default is ndn_ContentType_DATA. -1 for none */
-  int freshnessSeconds;  /**< -1 for none */
-	unsigned char *finalBlockID;	    /**< pointer to pre-allocated buffer.  0 for none */
-  unsigned int finalBlockIDLength;  /**< length of finalBlockID.  0 for none */
+  double timestampMilliseconds;    /**< milliseconds since 1/1/1970. -1 for none */
+  int type;                        /**< default is ndn_ContentType_DATA. -1 for none */
+  int freshnessSeconds;            /**< -1 for none */
+	unsigned char *finalBlockID;	   /**< pointer to pre-allocated buffer.  0 for none */
+  unsigned int finalBlockIDLength; /**< length of finalBlockID.  0 for none */
   struct ndn_KeyLocator keyLocator;
 };
 
diff --git a/ndn-cpp/c/encoding/BinaryXMLContentObject.c b/ndn-cpp/c/encoding/BinaryXMLContentObject.c
index ef50532..29b2065 100644
--- a/ndn-cpp/c/encoding/BinaryXMLContentObject.c
+++ b/ndn-cpp/c/encoding/BinaryXMLContentObject.c
@@ -103,7 +103,9 @@
   if (error = ndn_decodeOptionalBinaryXMLPublisherPublicKeyDigest(&signedInfo->publisherPublicKeyDigest, decoder))
     return error;
   
-  // TODO: Implement timeStamp
+  if (error= ndn_BinaryXMLDecoder_readOptionalTimeMillisecondsDTagElement
+      (decoder, ndn_BinaryXML_DTag_Timestamp, &signedInfo->timestampMilliseconds))
+    return error;
   
   // TODO: Implement reading the type and converting to an int.
   signedInfo->type = ndn_ContentType_DATA;
diff --git a/tests/test-encode-decode-ContentObject.cpp b/tests/test-encode-decode-ContentObject.cpp
index fcb7905..97dfa2e 100644
--- a/tests/test-encode-decode-ContentObject.cpp
+++ b/tests/test-encode-decode-ContentObject.cpp
@@ -32,11 +32,9 @@
       0xba, 0x3d, 0xa7, 0x76, 0x1b, 0x0f, 0x8d, 0x61, 0xa4, 0xaa, 0x7e, 0x3b, 0x6d, 0x15, 0xb4, 0x26, 0xfe, 0xb5,
       0xbd, 0xa8, 0x23, 0x89, 0xac, 0xa7, 0x65, 0xa3, 0xb8, 0x1c, 
     0x00, 
-#if 0
     0x02, 0xba, // Timestamp
       0xb5, 0x05, 0x1d, 0xde, 0xe9, 0x5b, 0xdb, 
     0x00, 
-#endif
     0x01, 0xe2, // KeyLocator
       0x01, 0xda, // Key
         0x0a, 0x95, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
@@ -59,15 +57,13 @@
 1
 };
 
-/*
- * 
- */
 int main(int argc, char** argv)
 {
   try {
     ContentObject contentObject;
     contentObject.decode(ContentObject1, sizeof(ContentObject1));
-    cout << "Interest name " << contentObject.getName().to_uri() << endl;
+    cout << "ContentObject name " << contentObject.getName().to_uri() << endl;
+    cout << "ContentObject timestamp (ms) " << contentObject.getSignedInfo().getTimestampMilliseconds() << endl;
     
     vector<unsigned char> encoding;
     contentObject.encode(encoding);
@@ -75,7 +71,8 @@
     
     ContentObject reDecodedContentObject;
     reDecodedContentObject.decode(encoding);
-    cout << "Re-decoded Interest name " << reDecodedContentObject.getName().to_uri() << endl;
+    cout << "Re-decoded ContentObject name " << reDecodedContentObject.getName().to_uri() << endl;
+    cout << "Re-decoded ContentObject timestamp (ms) " << reDecodedContentObject.getSignedInfo().getTimestampMilliseconds() << endl;
   } catch (exception &e) {
     cout << "exception: " << e.what() << endl;
   }