summaryrefslogtreecommitdiffstats
path: root/base/time
diff options
context:
space:
mode:
authorricea <ricea@chromium.org>2014-10-29 04:35:45 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-29 11:36:11 +0000
commitfa874fd422dd79886729d6884b032b44572c43ee (patch)
tree466f522bff083c2cfe57fd176d804b6dace40b5a /base/time
parentb8aecf83be3b90d288a0a71a8571f0dd3f99bec5 (diff)
downloadchromium_src-fa874fd422dd79886729d6884b032b44572c43ee.zip
chromium_src-fa874fd422dd79886729d6884b032b44572c43ee.tar.gz
chromium_src-fa874fd422dd79886729d6884b032b44572c43ee.tar.bz2
Add logging support for base::Time* types.
Define operator<<(ostream&,Time) to permit Time, TimeDelta and TimeTicks types to be used in logging assertions such as DCHECK_EQ(). BUG=425941 TEST=base_unittests Review URL: https://codereview.chromium.org/669083002 Cr-Commit-Position: refs/heads/master@{#301815}
Diffstat (limited to 'base/time')
-rw-r--r--base/time/time.cc31
-rw-r--r--base/time/time.h15
-rw-r--r--base/time/time_unittest.cc105
3 files changed, 148 insertions, 3 deletions
diff --git a/base/time/time.cc b/base/time/time.cc
index f731356..ce9d12c 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -4,12 +4,15 @@
#include "base/time/time.h"
+#include <ios>
#include <limits>
#include <ostream>
+#include <sstream>
#include "base/float_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "base/third_party/nspr/prtime.h"
namespace base {
@@ -94,6 +97,10 @@ int64 TimeDelta::InMicroseconds() const {
return delta_;
}
+std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) {
+ return os << time_delta.InSecondsF() << "s";
+}
+
// Time -----------------------------------------------------------------------
// static
@@ -230,6 +237,20 @@ bool Time::FromStringInternal(const char* time_string,
return true;
}
+std::ostream& operator<<(std::ostream& os, Time time) {
+ Time::Exploded exploded;
+ time.UTCExplode(&exploded);
+ // Use StringPrintf because iostreams formatting is painful.
+ return os << StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%03d UTC",
+ exploded.year,
+ exploded.month,
+ exploded.day_of_month,
+ exploded.hour,
+ exploded.minute,
+ exploded.second,
+ exploded.millisecond);
+}
+
// Local helper class to hold the conversion from Time to TickTime at the
// time of the Unix epoch.
class UnixEpochSingleton {
@@ -253,6 +274,16 @@ TimeTicks TimeTicks::UnixEpoch() {
return leaky_unix_epoch_singleton_instance.Get().unix_epoch();
}
+std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks) {
+ // This function formats a TimeTicks object as "bogo-microseconds".
+ // The origin and granularity of the count are platform-specific, and may very
+ // from run to run. Although bogo-microseconds usually roughly correspond to
+ // real microseconds, the only real guarantee is that the number never goes
+ // down during a single run.
+ const TimeDelta as_time_delta = time_ticks - TimeTicks();
+ return os << as_time_delta.InMicroseconds() << " bogo-microseconds";
+}
+
// Time::Exploded -------------------------------------------------------------
inline bool is_in_range(int value, int lo, int hi) {
diff --git a/base/time/time.h b/base/time/time.h
index 3cf3746..641f465 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -19,12 +19,18 @@
//
// These classes are represented as only a 64-bit value, so they can be
// efficiently passed by value.
+//
+// Definitions of operator<< are provided to make these types work with
+// DCHECK_EQ() and other log macros. For human-readable formatting, see
+// "base/i18n/time_formatting.h".
#ifndef BASE_TIME_TIME_H_
#define BASE_TIME_TIME_H_
#include <time.h>
+#include <iosfwd>
+
#include "base/base_export.h"
#include "base/basictypes.h"
#include "build/build_config.h"
@@ -206,6 +212,9 @@ inline TimeDelta operator*(int64 a, TimeDelta td) {
return TimeDelta(a * td.delta_);
}
+// For logging use only.
+BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta);
+
// Time -----------------------------------------------------------------------
// Represents a wall clock time in UTC.
@@ -561,6 +570,9 @@ inline Time TimeDelta::operator+(Time t) const {
return Time(t.us_ + delta_);
}
+// For logging use only.
+BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time);
+
// TimeTicks ------------------------------------------------------------------
class BASE_EXPORT TimeTicks {
@@ -723,6 +735,9 @@ inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
return TimeTicks(t.ticks_ + delta_);
}
+// For logging use only.
+BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks);
+
} // namespace base
#endif // BASE_TIME_TIME_H_
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index d8f1e5e..ef80e438 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -6,6 +6,8 @@
#include <time.h>
+#include <string>
+
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
@@ -13,9 +15,9 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
+namespace base {
+
+namespace {
// Specialized test fixture allowing time strings without timezones to be
// tested by comparing them to a known time in the local zone.
@@ -780,3 +782,100 @@ TEST(TimeDelta, WindowsEpoch) {
// We can't test 1601 epoch, since the system time functions on Linux
// only compute years starting from 1900.
}
+
+// We could define this separately for Time, TimeTicks and TimeDelta but the
+// definitions would be identical anyway.
+template <class Any>
+std::string AnyToString(Any any) {
+ std::ostringstream oss;
+ oss << any;
+ return oss.str();
+}
+
+TEST(TimeDeltaLogging, DCheckEqCompiles) {
+ DCHECK_EQ(TimeDelta(), TimeDelta());
+}
+
+TEST(TimeDeltaLogging, EmptyIsZero) {
+ TimeDelta zero;
+ EXPECT_EQ("0s", AnyToString(zero));
+}
+
+TEST(TimeDeltaLogging, FiveHundredMs) {
+ TimeDelta five_hundred_ms = TimeDelta::FromMilliseconds(500);
+ EXPECT_EQ("0.5s", AnyToString(five_hundred_ms));
+}
+
+TEST(TimeDeltaLogging, MinusTenSeconds) {
+ TimeDelta minus_ten_seconds = TimeDelta::FromSeconds(-10);
+ EXPECT_EQ("-10s", AnyToString(minus_ten_seconds));
+}
+
+TEST(TimeDeltaLogging, DoesNotMessUpFormattingFlags) {
+ std::ostringstream oss;
+ std::ios_base::fmtflags flags_before = oss.flags();
+ oss << TimeDelta();
+ EXPECT_EQ(flags_before, oss.flags());
+}
+
+TEST(TimeDeltaLogging, DoesNotMakeStreamBad) {
+ std::ostringstream oss;
+ oss << TimeDelta();
+ EXPECT_TRUE(oss.good());
+}
+
+TEST(TimeLogging, DCheckEqCompiles) {
+ DCHECK_EQ(Time(), Time());
+}
+
+TEST(TimeLogging, ChromeBirthdate) {
+ Time birthdate;
+ ASSERT_TRUE(Time::FromString("Tue, 02 Sep 2008 09:42:18 GMT", &birthdate));
+ EXPECT_EQ("2008-09-02 09:42:18.000 UTC", AnyToString(birthdate));
+}
+
+TEST(TimeLogging, DoesNotMessUpFormattingFlags) {
+ std::ostringstream oss;
+ std::ios_base::fmtflags flags_before = oss.flags();
+ oss << Time();
+ EXPECT_EQ(flags_before, oss.flags());
+}
+
+TEST(TimeLogging, DoesNotMakeStreamBad) {
+ std::ostringstream oss;
+ oss << Time();
+ EXPECT_TRUE(oss.good());
+}
+
+TEST(TimeTicksLogging, DCheckEqCompiles) {
+ DCHECK_EQ(TimeTicks(), TimeTicks());
+}
+
+TEST(TimeTicksLogging, ZeroTime) {
+ TimeTicks zero;
+ EXPECT_EQ("0 bogo-microseconds", AnyToString(zero));
+}
+
+TEST(TimeTicksLogging, FortyYearsLater) {
+ TimeTicks forty_years_later =
+ TimeTicks() + TimeDelta::FromDays(365.25 * 40);
+ EXPECT_EQ("1262304000000000 bogo-microseconds",
+ AnyToString(forty_years_later));
+}
+
+TEST(TimeTicksLogging, DoesNotMessUpFormattingFlags) {
+ std::ostringstream oss;
+ std::ios_base::fmtflags flags_before = oss.flags();
+ oss << TimeTicks();
+ EXPECT_EQ(flags_before, oss.flags());
+}
+
+TEST(TimeTicksLogging, DoesNotMakeStreamBad) {
+ std::ostringstream oss;
+ oss << TimeTicks();
+ EXPECT_TRUE(oss.good());
+}
+
+} // namespace
+
+} // namespace base