Googletest export

Adds ISO8601 timestamps to XML output and RFC3339 timestamps to JSON output.

Adds timestamps to testsuites, testsuite and testcases structured JSON/XML output for better reporting how/where time is spent on tests.

PiperOrigin-RevId: 260039817
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index 0cb5a2e..ff77075 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -588,6 +588,10 @@
   // Returns the elapsed time, in milliseconds.
   TimeInMillis elapsed_time() const { return elapsed_time_; }
 
+  // Gets the time of the test case start, in ms from the start of the
+  // UNIX epoch.
+  TimeInMillis start_timestamp() const { return start_timestamp_; }
+
   // Returns the i-th test part result among all the results. i can range from 0
   // to total_part_count() - 1. If i is not in that range, aborts the program.
   const TestPartResult& GetTestPartResult(int i) const;
@@ -618,6 +622,9 @@
     return test_properties_;
   }
 
+  // Sets the start time.
+  void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }
+
   // Sets the elapsed time.
   void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
 
@@ -661,6 +668,8 @@
   std::vector<TestProperty> test_properties_;
   // Running count of death tests.
   int death_test_count_;
+  // The start time, in milliseconds since UNIX Epoch.
+  TimeInMillis start_timestamp_;
   // The elapsed time, in milliseconds.
   TimeInMillis elapsed_time_;
 
@@ -881,6 +890,10 @@
   // Returns the elapsed time, in milliseconds.
   TimeInMillis elapsed_time() const { return elapsed_time_; }
 
+  // Gets the time of the test suite start, in ms from the start of the
+  // UNIX epoch.
+  TimeInMillis start_timestamp() const { return start_timestamp_; }
+
   // Returns the i-th test among all the tests. i can range from 0 to
   // total_test_count() - 1. If i is not in that range, returns NULL.
   const TestInfo* GetTestInfo(int i) const;
@@ -999,6 +1012,8 @@
   internal::TearDownTestSuiteFunc tear_down_tc_;
   // True iff any test in this test suite should run.
   bool should_run_;
+  // The start time, in milliseconds since UNIX Epoch.
+  TimeInMillis start_timestamp_;
   // Elapsed time, in milliseconds.
   TimeInMillis elapsed_time_;
   // Holds test properties recorded during execution of SetUpTestSuite and
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 0da3cc2..d6b5630 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -2032,9 +2032,7 @@
 
 // Creates an empty TestResult.
 TestResult::TestResult()
-    : death_test_count_(0),
-      elapsed_time_(0) {
-}
+    : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}
 
 // D'tor.
 TestResult::~TestResult() {
@@ -2103,13 +2101,7 @@
 // The list of reserved attributes used in the <testsuite> element of XML
 // output.
 static const char* const kReservedTestSuiteAttributes[] = {
-  "disabled",
-  "errors",
-  "failures",
-  "name",
-  "tests",
-  "time"
-};
+    "disabled", "errors", "failures", "name", "tests", "time", "timestamp"};
 
 // The list of reserved attributes used in the <testcase> element of XML output.
 static const char* const kReservedTestCaseAttributes[] = {
@@ -2117,10 +2109,10 @@
     "value_param", "file", "line"};
 
 // Use a slightly different set for allowed output to ensure existing tests can
-// still RecordProperty("result")
+// still RecordProperty("result") or "RecordProperty(timestamp")
 static const char* const kReservedOutputTestCaseAttributes[] = {
-    "classname",   "name", "status", "time",  "type_param",
-    "value_param", "file", "line", "result"};
+    "classname",   "name", "status", "time",   "type_param",
+    "value_param", "file", "line",   "result", "timestamp"};
 
 template <int kSize>
 std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
@@ -2705,6 +2697,7 @@
         test, &Test::DeleteSelf_, "the test fixture's destructor");
   }
 
+  result_.set_start_timestamp(start);
   result_.set_elapsed_time(internal::GetTimeInMillis() - start);
 
   // Notifies the unit test event listener that a test has just finished.
@@ -2774,6 +2767,7 @@
       set_up_tc_(set_up_tc),
       tear_down_tc_(tear_down_tc),
       should_run_(false),
+      start_timestamp_(0),
       elapsed_time_(0) {}
 
 // Destructor of TestSuite.
@@ -2823,11 +2817,11 @@
   internal::HandleExceptionsInMethodIfSupported(
       this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
 
-  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  start_timestamp_ = internal::GetTimeInMillis();
   for (int i = 0; i < total_test_count(); i++) {
     GetMutableTestInfo(i)->Run();
   }
-  elapsed_time_ = internal::GetTimeInMillis() - start;
+  elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_;
 
   impl->os_stack_trace_getter()->UponLeavingGTest();
   internal::HandleExceptionsInMethodIfSupported(
@@ -3788,6 +3782,9 @@
                          : "suppressed");
   OutputXmlAttribute(stream, kTestsuite, "time",
                      FormatTimeInMillisAsSeconds(result.elapsed_time()));
+  OutputXmlAttribute(
+      stream, kTestsuite, "timestamp",
+      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
   OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name);
 
   int failures = 0;
@@ -3838,6 +3835,9 @@
     OutputXmlAttribute(stream, kTestsuite, "errors", "0");
     OutputXmlAttribute(stream, kTestsuite, "time",
                        FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));
+    OutputXmlAttribute(
+        stream, kTestsuite, "timestamp",
+        FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));
     *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
   }
   *stream << ">\n";
@@ -3864,11 +3864,11 @@
       stream, kTestsuites, "disabled",
       StreamableToString(unit_test.reportable_disabled_test_count()));
   OutputXmlAttribute(stream, kTestsuites, "errors", "0");
+  OutputXmlAttribute(stream, kTestsuites, "time",
+                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
   OutputXmlAttribute(
       stream, kTestsuites, "timestamp",
       FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
-  OutputXmlAttribute(stream, kTestsuites, "time",
-                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
 
   if (GTEST_FLAG(shuffle)) {
     OutputXmlAttribute(stream, kTestsuites, "random_seed",
@@ -4156,6 +4156,9 @@
                     ? (result.Skipped() ? "SKIPPED" : "COMPLETED")
                     : "SUPPRESSED",
                 kIndent);
+  OutputJsonKey(stream, kTestsuite, "timestamp",
+                FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
+                kIndent);
   OutputJsonKey(stream, kTestsuite, "time",
                 FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
   OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent,
@@ -4202,6 +4205,10 @@
     OutputJsonKey(stream, kTestsuite, "disabled",
                   test_suite.reportable_disabled_test_count(), kIndent);
     OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
+    OutputJsonKey(
+        stream, kTestsuite, "timestamp",
+        FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),
+        kIndent);
     OutputJsonKey(stream, kTestsuite, "time",
                   FormatTimeInMillisAsDuration(test_suite.elapsed_time()),
                   kIndent, false);
diff --git a/googletest/test/googletest-json-outfiles-test.py b/googletest/test/googletest-json-outfiles-test.py
index b81a03d..8ef47b8 100644
--- a/googletest/test/googletest-json-outfiles-test.py
+++ b/googletest/test/googletest-json-outfiles-test.py
@@ -67,11 +67,14 @@
             0,
         u'time':
             u'*',
+        u'timestamp':
+            u'*',
         u'testsuite': [{
             u'name': u'TestSomeProperties',
             u'status': u'RUN',
             u'result': u'COMPLETED',
             u'time': u'*',
+            u'timestamp': u'*',
             u'classname': u'PropertyOne',
             u'SetUpProp': u'1',
             u'TestSomeProperty': u'1',
@@ -108,10 +111,13 @@
             0,
         u'time':
             u'*',
+        u'timestamp':
+            u'*',
         u'testsuite': [{
             u'name': u'TestSomeProperties',
             u'status': u'RUN',
             u'result': u'COMPLETED',
+            u'timestamp': u'*',
             u'time': u'*',
             u'classname': u'PropertyTwo',
             u'SetUpProp': u'2',
diff --git a/googletest/test/googletest-json-output-unittest.py b/googletest/test/googletest-json-output-unittest.py
index 64d7534..15861f7 100644
--- a/googletest/test/googletest-json-output-unittest.py
+++ b/googletest/test/googletest-json-output-unittest.py
@@ -73,457 +73,474 @@
         u'42',
     u'name':
         u'AllTests',
-    u'testsuites': [
-        {
+    u'testsuites': [{
+        u'name':
+            u'SuccessfulTest',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'Succeeds',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'SuccessfulTest'
+        }]
+    }, {
+        u'name':
+            u'FailedTest',
+        u'tests':
+            1,
+        u'failures':
+            1,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
             u'name':
-                u'SuccessfulTest',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
+                u'Fails',
+            u'status':
+                u'RUN',
+            u'result':
+                u'COMPLETED',
             u'time':
                 u'*',
-            u'testsuite': [{
-                u'name': u'Succeeds',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'SuccessfulTest'
-            }]
-        },
-        {
-            u'name':
+            u'timestamp':
+                u'*',
+            u'classname':
                 u'FailedTest',
-            u'tests':
-                1,
-            u'failures':
-                1,
-            u'disabled':
-                0,
-            u'errors':
-                0,
+            u'failures': [{
+                u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+                            u'Expected equality of these values:\n'
+                            u'  1\n  2' + STACK_TRACE_TEMPLATE,
+                u'type': u''
+            }]
+        }]
+    }, {
+        u'name':
+            u'DisabledTest',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            1,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'DISABLED_test_not_run',
+            u'status': u'NOTRUN',
+            u'result': u'SUPPRESSED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'DisabledTest'
+        }]
+    }, {
+        u'name':
+            u'SkippedTest',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'Skipped',
+            u'status': u'RUN',
+            u'result': u'SKIPPED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'SkippedTest'
+        }]
+    }, {
+        u'name':
+            u'MixedResultTest',
+        u'tests':
+            3,
+        u'failures':
+            1,
+        u'disabled':
+            1,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'Succeeds',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'MixedResultTest'
+        }, {
+            u'name':
+                u'Fails',
+            u'status':
+                u'RUN',
+            u'result':
+                u'COMPLETED',
             u'time':
                 u'*',
-            u'testsuite': [{
-                u'name':
-                    u'Fails',
-                u'status':
-                    u'RUN',
-                u'result':
-                    u'COMPLETED',
-                u'time':
-                    u'*',
-                u'classname':
-                    u'FailedTest',
-                u'failures': [{
-                    u'failure': u'gtest_xml_output_unittest_.cc:*\n'
-                                u'Expected equality of these values:\n'
-                                u'  1\n  2' + STACK_TRACE_TEMPLATE,
-                    u'type': u''
-                }]
-            }]
-        },
-        {
-            u'name':
-                u'DisabledTest',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                1,
-            u'errors':
-                0,
-            u'time':
+            u'timestamp':
                 u'*',
-            u'testsuite': [{
-                u'name': u'DISABLED_test_not_run',
-                u'status': u'NOTRUN',
-                u'result': u'SUPPRESSED',
-                u'time': u'*',
-                u'classname': u'DisabledTest'
-            }]
-        },
-        {
-            u'name':
-                u'SkippedTest',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name': u'Skipped',
-                u'status': u'RUN',
-                u'result': u'SKIPPED',
-                u'time': u'*',
-                u'classname': u'SkippedTest'
-            }]
-        },
-        {
-            u'name':
+            u'classname':
                 u'MixedResultTest',
-            u'tests':
-                3,
-            u'failures':
-                1,
-            u'disabled':
-                1,
-            u'errors':
-                0,
+            u'failures': [{
+                u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+                            u'Expected equality of these values:\n'
+                            u'  1\n  2' + STACK_TRACE_TEMPLATE,
+                u'type': u''
+            }, {
+                u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+                            u'Expected equality of these values:\n'
+                            u'  2\n  3' + STACK_TRACE_TEMPLATE,
+                u'type': u''
+            }]
+        }, {
+            u'name': u'DISABLED_test',
+            u'status': u'NOTRUN',
+            u'result': u'SUPPRESSED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'MixedResultTest'
+        }]
+    }, {
+        u'name':
+            u'XmlQuotingTest',
+        u'tests':
+            1,
+        u'failures':
+            1,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name':
+                u'OutputsCData',
+            u'status':
+                u'RUN',
+            u'result':
+                u'COMPLETED',
             u'time':
                 u'*',
-            u'testsuite': [
-                {
-                    u'name': u'Succeeds',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'MixedResultTest'
-                },
-                {
-                    u'name':
-                        u'Fails',
-                    u'status':
-                        u'RUN',
-                    u'result':
-                        u'COMPLETED',
-                    u'time':
-                        u'*',
-                    u'classname':
-                        u'MixedResultTest',
-                    u'failures':
-                        [{
-                            u'failure': u'gtest_xml_output_unittest_.cc:*\n'
-                                        u'Expected equality of these values:\n'
-                                        u'  1\n  2' + STACK_TRACE_TEMPLATE,
-                            u'type': u''
-                        },
-                         {
-                             u'failure': u'gtest_xml_output_unittest_.cc:*\n'
-                                         u'Expected equality of these values:\n'
-                                         u'  2\n  3' + STACK_TRACE_TEMPLATE,
-                             u'type': u''
-                         }]
-                },
-                {
-                    u'name': u'DISABLED_test',
-                    u'status': u'NOTRUN',
-                    u'result': u'SUPPRESSED',
-                    u'time': u'*',
-                    u'classname': u'MixedResultTest'
-                }
-            ]
-        },
-        {
-            u'name':
+            u'timestamp':
+                u'*',
+            u'classname':
                 u'XmlQuotingTest',
-            u'tests':
-                1,
-            u'failures':
-                1,
-            u'disabled':
-                0,
-            u'errors':
-                0,
+            u'failures': [{
+                u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+                            u'Failed\nXML output: <?xml encoding="utf-8">'
+                            u'<top><![CDATA[cdata text]]></top>' +
+                            STACK_TRACE_TEMPLATE,
+                u'type': u''
+            }]
+        }]
+    }, {
+        u'name':
+            u'InvalidCharactersTest',
+        u'tests':
+            1,
+        u'failures':
+            1,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name':
+                u'InvalidCharactersInMessage',
+            u'status':
+                u'RUN',
+            u'result':
+                u'COMPLETED',
             u'time':
                 u'*',
-            u'testsuite': [{
-                u'name':
-                    u'OutputsCData',
-                u'status':
-                    u'RUN',
-                u'result':
-                    u'COMPLETED',
-                u'time':
-                    u'*',
-                u'classname':
-                    u'XmlQuotingTest',
-                u'failures': [{
-                    u'failure': u'gtest_xml_output_unittest_.cc:*\n'
-                                u'Failed\nXML output: <?xml encoding="utf-8">'
-                                u'<top><![CDATA[cdata text]]></top>' +
-                                STACK_TRACE_TEMPLATE,
-                    u'type': u''
-                }]
-            }]
-        },
-        {
-            u'name':
+            u'timestamp':
+                u'*',
+            u'classname':
                 u'InvalidCharactersTest',
-            u'tests':
-                1,
-            u'failures':
-                1,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name':
-                    u'InvalidCharactersInMessage',
-                u'status':
-                    u'RUN',
-                u'result':
-                    u'COMPLETED',
-                u'time':
-                    u'*',
-                u'classname':
-                    u'InvalidCharactersTest',
-                u'failures': [{
-                    u'failure': u'gtest_xml_output_unittest_.cc:*\n'
-                                u'Failed\nInvalid characters in brackets'
-                                u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
-                    u'type': u''
-                }]
+            u'failures': [{
+                u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+                            u'Failed\nInvalid characters in brackets'
+                            u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
+                u'type': u''
             }]
-        },
-        {
-            u'name':
-                u'PropertyRecordingTest',
-            u'tests':
-                4,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'SetUpTestSuite':
-                u'yes',
-            u'TearDownTestSuite':
-                u'aye',
-            u'testsuite': [{
-                u'name': u'OneProperty',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'PropertyRecordingTest',
-                u'key_1': u'1'
-            },
-                           {
-                               u'name': u'IntValuedProperty',
-                               u'status': u'RUN',
-                               u'result': u'COMPLETED',
-                               u'time': u'*',
-                               u'classname': u'PropertyRecordingTest',
-                               u'key_int': u'1'
-                           },
-                           {
-                               u'name': u'ThreeProperties',
-                               u'status': u'RUN',
-                               u'result': u'COMPLETED',
-                               u'time': u'*',
-                               u'classname': u'PropertyRecordingTest',
-                               u'key_1': u'1',
-                               u'key_2': u'2',
-                               u'key_3': u'3'
-                           },
-                           {
-                               u'name': u'TwoValuesForOneKeyUsesLastValue',
-                               u'status': u'RUN',
-                               u'result': u'COMPLETED',
-                               u'time': u'*',
-                               u'classname': u'PropertyRecordingTest',
-                               u'key_1': u'2'
-                           }]
-        },
-        {
-            u'name':
-                u'NoFixtureTest',
-            u'tests':
-                3,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [
-                {
-                    u'name': u'RecordProperty',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'NoFixtureTest',
-                    u'key': u'1'
-                },
-                {
-                    u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'NoFixtureTest',
-                    u'key_for_utility_int': u'1'
-                },
-                {
-                    u'name':
-                        u'ExternalUtilityThatCallsRecordStringValuedProperty',
-                    u'status':
-                        u'RUN',
-                    u'result':
-                        u'COMPLETED',
-                    u'time':
-                        u'*',
-                    u'classname':
-                        u'NoFixtureTest',
-                    u'key_for_utility_string':
-                        u'1'
-                }
-            ]
-        },
-        {
-            u'name':
-                u'TypedTest/0',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name': u'HasTypeParamAttribute',
-                u'type_param': u'int',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'TypedTest/0'
-            }]
-        },
-        {
-            u'name':
-                u'TypedTest/1',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name': u'HasTypeParamAttribute',
-                u'type_param': u'long',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'TypedTest/1'
-            }]
-        },
-        {
-            u'name':
-                u'Single/TypeParameterizedTestSuite/0',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name': u'HasTypeParamAttribute',
-                u'type_param': u'int',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'Single/TypeParameterizedTestSuite/0'
-            }]
-        },
-        {
-            u'name':
-                u'Single/TypeParameterizedTestSuite/1',
-            u'tests':
-                1,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [{
-                u'name': u'HasTypeParamAttribute',
-                u'type_param': u'long',
-                u'status': u'RUN',
-                u'result': u'COMPLETED',
-                u'time': u'*',
-                u'classname': u'Single/TypeParameterizedTestSuite/1'
-            }]
-        },
-        {
-            u'name':
-                u'Single/ValueParamTest',
-            u'tests':
-                4,
-            u'failures':
-                0,
-            u'disabled':
-                0,
-            u'errors':
-                0,
-            u'time':
-                u'*',
-            u'testsuite': [
-                {
-                    u'name': u'HasValueParamAttribute/0',
-                    u'value_param': u'33',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'Single/ValueParamTest'
-                },
-                {
-                    u'name': u'HasValueParamAttribute/1',
-                    u'value_param': u'42',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'Single/ValueParamTest'
-                },
-                {
-                    u'name': u'AnotherTestThatHasValueParamAttribute/0',
-                    u'value_param': u'33',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'Single/ValueParamTest'
-                },
-                {
-                    u'name': u'AnotherTestThatHasValueParamAttribute/1',
-                    u'value_param': u'42',
-                    u'status': u'RUN',
-                    u'result': u'COMPLETED',
-                    u'time': u'*',
-                    u'classname': u'Single/ValueParamTest'
-                }
-            ]
-        }
-    ]
+        }]
+    }, {
+        u'name':
+            u'PropertyRecordingTest',
+        u'tests':
+            4,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'SetUpTestSuite':
+            u'yes',
+        u'TearDownTestSuite':
+            u'aye',
+        u'testsuite': [{
+            u'name': u'OneProperty',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'PropertyRecordingTest',
+            u'key_1': u'1'
+        }, {
+            u'name': u'IntValuedProperty',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'PropertyRecordingTest',
+            u'key_int': u'1'
+        }, {
+            u'name': u'ThreeProperties',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'PropertyRecordingTest',
+            u'key_1': u'1',
+            u'key_2': u'2',
+            u'key_3': u'3'
+        }, {
+            u'name': u'TwoValuesForOneKeyUsesLastValue',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'PropertyRecordingTest',
+            u'key_1': u'2'
+        }]
+    }, {
+        u'name':
+            u'NoFixtureTest',
+        u'tests':
+            3,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'RecordProperty',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'NoFixtureTest',
+            u'key': u'1'
+        }, {
+            u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'NoFixtureTest',
+            u'key_for_utility_int': u'1'
+        }, {
+            u'name': u'ExternalUtilityThatCallsRecordStringValuedProperty',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'NoFixtureTest',
+            u'key_for_utility_string': u'1'
+        }]
+    }, {
+        u'name':
+            u'TypedTest/0',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'HasTypeParamAttribute',
+            u'type_param': u'int',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'TypedTest/0'
+        }]
+    }, {
+        u'name':
+            u'TypedTest/1',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'HasTypeParamAttribute',
+            u'type_param': u'long',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'TypedTest/1'
+        }]
+    }, {
+        u'name':
+            u'Single/TypeParameterizedTestSuite/0',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'HasTypeParamAttribute',
+            u'type_param': u'int',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/TypeParameterizedTestSuite/0'
+        }]
+    }, {
+        u'name':
+            u'Single/TypeParameterizedTestSuite/1',
+        u'tests':
+            1,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'HasTypeParamAttribute',
+            u'type_param': u'long',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/TypeParameterizedTestSuite/1'
+        }]
+    }, {
+        u'name':
+            u'Single/ValueParamTest',
+        u'tests':
+            4,
+        u'failures':
+            0,
+        u'disabled':
+            0,
+        u'errors':
+            0,
+        u'time':
+            u'*',
+        u'timestamp':
+            u'*',
+        u'testsuite': [{
+            u'name': u'HasValueParamAttribute/0',
+            u'value_param': u'33',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/ValueParamTest'
+        }, {
+            u'name': u'HasValueParamAttribute/1',
+            u'value_param': u'42',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/ValueParamTest'
+        }, {
+            u'name': u'AnotherTestThatHasValueParamAttribute/0',
+            u'value_param': u'33',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/ValueParamTest'
+        }, {
+            u'name': u'AnotherTestThatHasValueParamAttribute/1',
+            u'value_param': u'42',
+            u'status': u'RUN',
+            u'result': u'COMPLETED',
+            u'time': u'*',
+            u'timestamp': u'*',
+            u'classname': u'Single/ValueParamTest'
+        }]
+    }]
 }
 
 EXPECTED_FILTERED = {
@@ -556,11 +573,14 @@
             0,
         u'time':
             u'*',
+        u'timestamp':
+            u'*',
         u'testsuite': [{
             u'name': u'Succeeds',
             u'status': u'RUN',
             u'result': u'COMPLETED',
             u'time': u'*',
+            u'timestamp': u'*',
             u'classname': u'SuccessfulTest',
         }]
     }],
diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py
index eaca1a7..e093f6f 100755
--- a/googletest/test/gtest_xml_outfiles_test.py
+++ b/googletest/test/gtest_xml_outfiles_test.py
@@ -42,8 +42,8 @@
 
 EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
 <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
-  <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="TestSomeProperties" status="run" result="completed" time="*" classname="PropertyOne">
+  <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="TestSomeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyOne">
       <properties>
         <property name="SetUpProp" value="1"/>
         <property name="TestSomeProperty" value="1"/>
@@ -56,8 +56,8 @@
 
 EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
 <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
-  <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="TestSomeProperties" status="run" result="completed" time="*" classname="PropertyTwo">
+  <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="TestSomeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyTwo">
       <properties>
         <property name="SetUpProp" value="2"/>
         <property name="TestSomeProperty" value="2"/>
diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py
index 745a134..63b1af0 100755
--- a/googletest/test/gtest_xml_output_unittest.py
+++ b/googletest/test/gtest_xml_output_unittest.py
@@ -66,20 +66,20 @@
 
 EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
 <testsuites tests="24" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
-  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
   </testsuite>
-  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
-    <testcase name="Fails" status="run" result="completed" time="*" classname="FailedTest">
+  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="Fails" status="run" result="completed" time="*" timestamp="*" classname="FailedTest">
       <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A;  1&#x0A;  2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
 Expected equality of these values:
   1
   2%(stack)s]]></failure>
     </testcase>
   </testsuite>
-  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
-    <testcase name="Succeeds" status="run" result="completed" time="*" classname="MixedResultTest"/>
-    <testcase name="Fails" status="run" result="completed" time="*" classname="MixedResultTest">
+  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*" timestamp="*">
+    <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest"/>
+    <testcase name="Fails" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest">
       <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A;  1&#x0A;  2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
 Expected equality of these values:
   1
@@ -89,86 +89,86 @@
   2
   3%(stack)s]]></failure>
     </testcase>
-    <testcase name="DISABLED_test" status="notrun" result="suppressed" time="*" classname="MixedResultTest"/>
+    <testcase name="DISABLED_test" status="notrun" result="suppressed" time="*" timestamp="*" classname="MixedResultTest"/>
   </testsuite>
-  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
-    <testcase name="OutputsCData" status="run" result="completed" time="*" classname="XmlQuotingTest">
+  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="OutputsCData" status="run" result="completed" time="*" timestamp="*" classname="XmlQuotingTest">
       <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
 Failed
 XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
     </testcase>
   </testsuite>
-  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
-    <testcase name="InvalidCharactersInMessage" status="run" result="completed" time="*" classname="InvalidCharactersTest">
+  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="InvalidCharactersInMessage" status="run" result="completed" time="*" timestamp="*" classname="InvalidCharactersTest">
       <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
 Failed
 Invalid characters in brackets []%(stack)s]]></failure>
     </testcase>
   </testsuite>
-  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
-    <testcase name="DISABLED_test_not_run" status="notrun" result="suppressed" time="*" classname="DisabledTest"/>
+  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*" timestamp="*">
+    <testcase name="DISABLED_test_not_run" status="notrun" result="suppressed" time="*" timestamp="*" classname="DisabledTest"/>
   </testsuite>
-  <testsuite name="SkippedTest" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="Skipped" status="run" result="skipped" time="*" classname="SkippedTest"/>
+  <testsuite name="SkippedTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="Skipped" status="run" result="skipped" time="*" timestamp="*" classname="SkippedTest"/>
   </testsuite>
-  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
-    <testcase name="OneProperty" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
+    <testcase name="OneProperty" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
       <properties>
         <property name="key_1" value="1"/>
       </properties>
     </testcase>
-    <testcase name="IntValuedProperty" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+    <testcase name="IntValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
       <properties>
         <property name="key_int" value="1"/>
       </properties>
     </testcase>
-    <testcase name="ThreeProperties" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+    <testcase name="ThreeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
       <properties>
         <property name="key_1" value="1"/>
         <property name="key_2" value="2"/>
         <property name="key_3" value="3"/>
       </properties>
     </testcase>
-    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
       <properties>
         <property name="key_1" value="2"/>
       </properties>
     </testcase>
   </testsuite>
-  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
-     <testcase name="RecordProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+     <testcase name="RecordProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
        <properties>
          <property name="key" value="1"/>
        </properties>
      </testcase>
-     <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+     <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
        <properties>
          <property name="key_for_utility_int" value="1"/>
        </properties>
      </testcase>
-     <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+     <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
        <properties>
          <property name="key_for_utility_string" value="1"/>
        </properties>
      </testcase>
   </testsuite>
-  <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="HasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
-    <testcase name="HasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
-    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
-    <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
+  <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="HasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+    <testcase name="HasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+    <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
   </testsuite>
-  <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="TypedTest/0" />
+  <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/0" />
   </testsuite>
-  <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="TypedTest/1" />
+  <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/1" />
   </testsuite>
-  <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="Single/TypeParameterizedTestSuite/0" />
+  <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/0" />
   </testsuite>
-  <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="Single/TypeParameterizedTestSuite/1" />
+  <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/1" />
   </testsuite>
 </testsuites>""" % {
     'stack': STACK_TRACE_TEMPLATE
@@ -178,25 +178,25 @@
 <testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
             timestamp="*" name="AllTests" ad_hoc_property="42">
   <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
-             errors="0" time="*">
-    <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+             errors="0" time="*" timestamp="*">
+    <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
   </testsuite>
 </testsuites>"""
 
 EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
 <testsuites tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
-  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
   </testsuite>
-  <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
-    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+  <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
+    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
       <properties>
         <property name="key_1" value="2"/>
       </properties>
     </testcase>
   </testsuite>
-  <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
-    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
+  <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
   </testsuite>
 </testsuites>"""
 
diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py
index afcf55e..9914a49 100755
--- a/googletest/test/gtest_xml_test_utils.py
+++ b/googletest/test/gtest_xml_test_utils.py
@@ -169,7 +169,7 @@
     *  The stack traces are removed.
     """
 
-    if element.tagName == 'testsuites':
+    if element.tagName in ('testsuites', 'testsuite', 'testcase'):
       timestamp = element.getAttributeNode('timestamp')
       timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$',
                                '*', timestamp.value)