Upgraded the rest of Time.

Change-Id: I0ee083837e51d8f74a798b7ba14a3b6bb3859f35
diff --git a/aos/common/actions/action_test.cc b/aos/common/actions/action_test.cc
index 21da2c7..1538d03 100644
--- a/aos/common/actions/action_test.cc
+++ b/aos/common/actions/action_test.cc
@@ -2,6 +2,7 @@
 
 #include <memory>
 #include <thread>
+#include <chrono>
 
 #include "gtest/gtest.h"
 
@@ -13,13 +14,14 @@
 #include "aos/common/event.h"
 #include "aos/testing/test_shm.h"
 
-using ::aos::time::Time;
-
 namespace aos {
 namespace common {
 namespace actions {
 namespace testing {
 
+
+namespace chrono = ::std::chrono;
+
 class TestActorIndex
     : public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
  public:
@@ -135,7 +137,7 @@
 
   ASSERT_FALSE(actions::test_action.status.FetchLatest());
   ::std::thread init_thread([&nop_act]() { nop_act.Initialize(); });
-  ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.1));
+  ::std::this_thread::sleep_for(chrono::milliseconds(100));
   ASSERT_TRUE(actions::test_action.goal.MakeWithBuilder().run(1).Send());
   init_thread.join();
   ASSERT_TRUE(actions::test_action.status.FetchLatest());
diff --git a/aos/common/actions/actor.h b/aos/common/actions/actor.h
index 5d0c70d..d2d05fc 100644
--- a/aos/common/actions/actor.h
+++ b/aos/common/actions/actor.h
@@ -4,12 +4,13 @@
 #include <stdio.h>
 #include <inttypes.h>
 
+#include <chrono>
 #include <functional>
 
+#include "aos/common/controls/control_loop.h"
 #include "aos/common/logging/logging.h"
 #include "aos/common/logging/queue_logging.h"
 #include "aos/common/time.h"
-#include "aos/common/controls/control_loop.h"
 #include "aos/common/util/phased_loop.h"
 
 namespace aos {
@@ -65,13 +66,14 @@
   // Returns false if the action was canceled or failed, and true if the wait
   // succeeded.
   bool WaitOrCancel(monotonic_clock::duration duration) {
-    return !WaitUntil([]() {
-      ::aos::time::PhasedLoopXMS(
-          ::std::chrono::duration_cast<::std::chrono::milliseconds>(
-              ::aos::controls::kLoopFrequency).count(),
-          2500);
-      return false;
-    }, ::aos::monotonic_clock::now() + duration);
+    ::aos::time::PhasedLoop phased_loop(::aos::controls::kLoopFrequency,
+                                        ::std::chrono::milliseconds(5) / 2);
+    return !WaitUntil(
+        [&phased_loop]() {
+          phased_loop.SleepUntilNext();
+          return false;
+        },
+        ::aos::monotonic_clock::now() + duration);
   }
 
   // Returns true if the action should be canceled.
diff --git a/aos/common/condition_test.cc b/aos/common/condition_test.cc
index 0e7bfe4..f8e4e65 100644
--- a/aos/common/condition_test.cc
+++ b/aos/common/condition_test.cc
@@ -5,6 +5,7 @@
 #include <sys/wait.h>
 
 #include <atomic>
+#include <chrono>
 #include <thread>
 
 #include "gtest/gtest.h"
@@ -21,18 +22,16 @@
 #include "aos/common/util/thread.h"
 #include "aos/testing/prevent_exit.h"
 
-using ::aos::time::Time;
-
 namespace aos {
 namespace testing {
 
+namespace chrono = ::std::chrono;
+
 class ConditionTestCommon : public ::testing::Test {
  public:
   ConditionTestCommon() {}
 
-  void Settle() {
-    time::SleepFor(::Time::InSeconds(0.008));
-  }
+  void Settle() { ::std::this_thread::sleep_for(chrono::milliseconds(8)); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ConditionTestCommon);
@@ -132,16 +131,22 @@
   };
 
   // This amount gets added to any passed in delay to make the test repeatable.
-  static constexpr ::Time kMinimumDelay = ::Time::InSeconds(0.15);
-  static constexpr ::Time kDefaultTimeout = ::Time::InSeconds(0.15);
+  static constexpr chrono::milliseconds kMinimumDelay =
+      chrono::milliseconds(150);
+  static constexpr chrono::milliseconds kDefaultTimeout =
+      chrono::milliseconds(150);
 
   // delay is how long to wait before doing action to condition.
   // timeout is how long to wait after delay before deciding that it's hung.
-  ConditionTestProcess(const ::Time &delay, Action action, Condition *condition,
-                       const ::Time &timeout = kDefaultTimeout)
-    : delay_(kMinimumDelay + delay), action_(action), condition_(condition),
-      timeout_(delay_ + timeout), child_(-1),
-      shared_(static_cast<Shared *>(shm_malloc(sizeof(Shared)))) {
+  ConditionTestProcess(chrono::milliseconds delay, Action action,
+                       Condition *condition,
+                       chrono::milliseconds timeout = kDefaultTimeout)
+      : delay_(kMinimumDelay + delay),
+        action_(action),
+        condition_(condition),
+        timeout_(delay_ + timeout),
+        child_(-1),
+        shared_(static_cast<Shared *>(shm_malloc(sizeof(Shared)))) {
     new (shared_) Shared();
   }
   ~ConditionTestProcess() {
@@ -179,15 +184,17 @@
       return ::testing::AssertionFailure() << "already returned";
     }
     if (shared_->delayed) {
-      if (shared_->start_time > ::Time::Now() + timeout_) {
+      if (shared_->start_time > monotonic_clock::now() + timeout_) {
         Kill();
         return ::testing::AssertionSuccess() << "already been too long";
       }
     } else {
       CHECK_EQ(0, futex_wait(&shared_->done_delaying));
     }
-    time::SleepFor(::Time::InSeconds(0.01));
-    if (!shared_->finished) time::SleepUntil(shared_->start_time + timeout_);
+    ::std::this_thread::sleep_for(chrono::milliseconds(10));
+    if (!shared_->finished) {
+      ::std::this_thread::sleep_until(shared_->start_time + timeout_);
+    }
     if (shared_->finished) {
       Join();
       return ::testing::AssertionFailure() << "completed within timeout";
@@ -204,14 +211,17 @@
  private:
   struct Shared {
     Shared()
-      : started(false), delayed(false), done_delaying(0), start_time(0, 0),
-        finished(false), ready(0) {
-    }
+        : started(false),
+          delayed(false),
+          done_delaying(0),
+          start_time(monotonic_clock::epoch()),
+          finished(false),
+          ready(0) {}
 
     volatile bool started;
     volatile bool delayed;
     aos_futex done_delaying;
-    ::Time start_time;
+    monotonic_clock::time_point start_time;
     volatile bool finished;
     aos_futex ready;
   };
@@ -223,8 +233,8 @@
       ASSERT_EQ(1, futex_set(&shared_->ready));
       ASSERT_FALSE(condition_->m()->Lock());
     }
-    time::SleepFor(delay_);
-    shared_->start_time = ::Time::Now();
+    ::std::this_thread::sleep_for(delay_);
+    shared_->start_time = monotonic_clock::now();
     shared_->delayed = true;
     ASSERT_NE(-1, futex_set(&shared_->done_delaying));
     if (action_ != Action::kWaitLockStart) {
@@ -253,10 +263,10 @@
     Join();
   }
 
-  const ::Time delay_;
+  const chrono::milliseconds delay_;
   const Action action_;
   Condition *const condition_;
-  const ::Time timeout_;
+  const chrono::milliseconds timeout_;
 
   pid_t child_;
 
@@ -264,13 +274,13 @@
 
   DISALLOW_COPY_AND_ASSIGN(ConditionTestProcess);
 };
-constexpr ::Time ConditionTestProcess::kMinimumDelay;
-constexpr ::Time ConditionTestProcess::kDefaultTimeout;
+constexpr chrono::milliseconds ConditionTestProcess::kMinimumDelay;
+constexpr chrono::milliseconds ConditionTestProcess::kDefaultTimeout;
 
 // Makes sure that the testing framework and everything work for a really simple
 // Wait() and then Signal().
 TEST_F(ConditionTest, Basic) {
-  ConditionTestProcess child(::Time(0, 0),
+  ConditionTestProcess child(chrono::milliseconds(0),
                              ConditionTestProcess::Action::kWait,
                              &shared_->condition);
   child.Start();
@@ -282,7 +292,7 @@
 
 // Makes sure that the worker child locks before it tries to Wait() etc.
 TEST_F(ConditionTest, Locking) {
-  ConditionTestProcess child(::Time(0, 0),
+  ConditionTestProcess child(chrono::milliseconds(0),
                              ConditionTestProcess::Action::kWait,
                              &shared_->condition);
   ASSERT_FALSE(shared_->mutex.Lock());
@@ -299,7 +309,7 @@
 // Tests that the work child only catches a Signal() after the mutex gets
 // unlocked.
 TEST_F(ConditionTest, LockFirst) {
-  ConditionTestProcess child(::Time(0, 0),
+  ConditionTestProcess child(chrono::milliseconds(0),
                              ConditionTestProcess::Action::kWait,
                              &shared_->condition);
   ASSERT_FALSE(shared_->mutex.Lock());
@@ -317,7 +327,7 @@
 
 // Tests that the mutex gets relocked after Wait() returns.
 TEST_F(ConditionTest, Relocking) {
-  ConditionTestProcess child(::Time(0, 0),
+  ConditionTestProcess child(chrono::milliseconds(0),
                              ConditionTestProcess::Action::kWaitNoUnlock,
                              &shared_->condition);
   child.Start();
@@ -330,13 +340,13 @@
 
 // Tests that Signal() stops exactly 1 Wait()er.
 TEST_F(ConditionTest, SignalOne) {
-  ConditionTestProcess child1(::Time(0, 0),
+  ConditionTestProcess child1(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
-  ConditionTestProcess child2(::Time(0, 0),
+  ConditionTestProcess child2(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
-  ConditionTestProcess child3(::Time(0, 0),
+  ConditionTestProcess child3(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
   auto number_finished = [&]() { return (child1.IsFinished() ? 1 : 0) +
@@ -362,13 +372,13 @@
 
 // Tests that Brodcast() wakes multiple Wait()ers.
 TEST_F(ConditionTest, Broadcast) {
-  ConditionTestProcess child1(::Time(0, 0),
+  ConditionTestProcess child1(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
-  ConditionTestProcess child2(::Time(0, 0),
+  ConditionTestProcess child2(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
-  ConditionTestProcess child3(::Time(0, 0),
+  ConditionTestProcess child3(chrono::milliseconds(0),
                               ConditionTestProcess::Action::kWait,
                               &shared_->condition);
   child1.Start();
diff --git a/aos/common/controls/control_loop-tmpl.h b/aos/common/controls/control_loop-tmpl.h
index 81b5d20..474c5ce 100644
--- a/aos/common/controls/control_loop-tmpl.h
+++ b/aos/common/controls/control_loop-tmpl.h
@@ -63,8 +63,7 @@
       // If the driver's station reports being disabled, we're probably not
       // actually going to send motor values regardless of what the FPGA
       // reports.
-      last_pwm_sent_ = monotonic_clock::time_point(
-          ::std::chrono::nanoseconds(::aos::robot_state->sent_time.ToNSec()));
+      last_pwm_sent_ = ::aos::robot_state->sent_time;
     }
   }
 
diff --git a/aos/common/event.cc b/aos/common/event.cc
index af9c9c5..ffb62b4 100644
--- a/aos/common/event.cc
+++ b/aos/common/event.cc
@@ -1,5 +1,7 @@
 #include "aos/common/event.h"
 
+#include <chrono>
+
 #include "aos/common/type_traits.h"
 #include "aos/common/logging/logging.h"
 
@@ -20,8 +22,14 @@
   }
 }
 
-bool Event::WaitTimeout(const ::aos::time::Time &timeout) {
-  const auto timeout_timespec = timeout.ToTimespec();
+bool Event::WaitTimeout(monotonic_clock::duration timeout) {
+  ::std::chrono::seconds sec =
+      ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
+  ::std::chrono::nanoseconds nsec =
+      ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
+  struct timespec timeout_timespec;
+  timeout_timespec.tv_sec = sec.count();
+  timeout_timespec.tv_nsec = nsec.count();
   while (true) {
     if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
       return true;
diff --git a/aos/common/event.h b/aos/common/event.h
index b3ee87b..559aad5 100644
--- a/aos/common/event.h
+++ b/aos/common/event.h
@@ -42,7 +42,7 @@
   // Waits for the event to be set or until timeout has elapsed. Returns
   // immediately if it is already set.
   // Returns true if the event was Set or false if the timeout expired.
-  bool WaitTimeout(const ::aos::time::Time &timeout);
+  bool WaitTimeout(monotonic_clock::duration timeout);
 
   // Wakes up all Wait()ers and sets the event (atomically).
   void Set();
diff --git a/aos/common/event_test.cc b/aos/common/event_test.cc
index 91af403..764dd49 100644
--- a/aos/common/event_test.cc
+++ b/aos/common/event_test.cc
@@ -1,15 +1,19 @@
 #include "aos/common/event.h"
 
+#include <chrono>
 #include <thread>
 
 #include "gtest/gtest.h"
 
-#include "aos/testing/test_logging.h"
 #include "aos/common/time.h"
+#include "aos/testing/test_logging.h"
 
 namespace aos {
 namespace testing {
 
+namespace chrono = ::std::chrono;
+namespace this_thread = ::std::this_thread;
+
 class EventTest : public ::testing::Test {
  public:
   Event test_event_;
@@ -50,38 +54,38 @@
 
 // Tests that an event blocks correctly.
 TEST_F(EventTest, Blocks) {
-  time::Time start_time, finish_time;
+  monotonic_clock::time_point start_time, finish_time;
   // Without this, it sometimes manages to fail under tsan.
   Event started;
   ::std::thread thread([this, &start_time, &finish_time, &started]() {
-    start_time = time::Time::Now();
+    start_time = monotonic_clock::now();
     started.Set();
     test_event_.Wait();
-    finish_time = time::Time::Now();
+    finish_time = monotonic_clock::now();
   });
-  static const time::Time kWaitTime = time::Time::InSeconds(0.05);
+  static constexpr auto kWaitTime = chrono::milliseconds(50);
   started.Wait();
-  time::SleepFor(kWaitTime);
+  this_thread::sleep_for(kWaitTime);
   test_event_.Set();
   thread.join();
   EXPECT_GE(finish_time - start_time, kWaitTime);
 }
 
 TEST_F(EventTest, WaitTimeout) {
-  EXPECT_FALSE(test_event_.WaitTimeout(time::Time::InSeconds(0.05)));
+  EXPECT_FALSE(test_event_.WaitTimeout(chrono::milliseconds(50)));
 
-  time::Time start_time, finish_time;
+  monotonic_clock::time_point start_time, finish_time;
   // Without this, it sometimes manages to fail under tsan.
   Event started;
   ::std::thread thread([this, &start_time, &finish_time, &started]() {
-    start_time = time::Time::Now();
+    start_time = monotonic_clock::now();
     started.Set();
-    EXPECT_TRUE(test_event_.WaitTimeout(time::Time::InSeconds(0.5)));
-    finish_time = time::Time::Now();
+    EXPECT_TRUE(test_event_.WaitTimeout(chrono::milliseconds(500)));
+    finish_time = monotonic_clock::now();
   });
-  static const time::Time kWaitTime = time::Time::InSeconds(0.05);
+  constexpr auto kWaitTime = chrono::milliseconds(50);
   started.Wait();
-  time::SleepFor(kWaitTime);
+  this_thread::sleep_for(kWaitTime);
   test_event_.Set();
   thread.join();
   EXPECT_GE(finish_time - start_time, kWaitTime);
diff --git a/aos/common/logging/binary_log_writer.cc b/aos/common/logging/binary_log_writer.cc
index 10641fb..076d72d 100644
--- a/aos/common/logging/binary_log_writer.cc
+++ b/aos/common/logging/binary_log_writer.cc
@@ -1,27 +1,28 @@
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
-#include <time.h>
 #include <string.h>
-#include <string>
-#include <unistd.h>
 #include <sys/types.h>
-#include <pwd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <mntent.h>
+#include <time.h>
+#include <unistd.h>
+#include <string>
 
+#include <chrono>
 #include <map>
 #include <unordered_set>
 
-#include "aos/common/logging/implementations.h"
-#include "aos/common/logging/binary_log_file.h"
-#include "aos/linux_code/init.h"
-#include "aos/linux_code/configuration.h"
-#include "aos/linux_code/ipc_lib/queue.h"
-#include "aos/common/queue_types.h"
 #include "aos/common/die.h"
+#include "aos/common/logging/binary_log_file.h"
+#include "aos/common/logging/implementations.h"
+#include "aos/common/queue_types.h"
 #include "aos/common/time.h"
+#include "aos/linux_code/configuration.h"
+#include "aos/linux_code/init.h"
+#include "aos/linux_code/ipc_lib/queue.h"
 
 namespace aos {
 namespace logging {
@@ -213,8 +214,7 @@
       // again so the queue can buffer up some logs. This avoids lots of context
       // switches and mutex contention which happens if we're constantly reading
       // new messages as they come in.
-      static constexpr auto kSleepTime = ::aos::time::Time::InSeconds(0.1);
-      ::aos::time::SleepFor(kSleepTime);
+      ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
       continue;
     }
 
diff --git a/aos/common/logging/implementations.cc b/aos/common/logging/implementations.cc
index 2f17f7a..697dec9 100644
--- a/aos/common/logging/implementations.cc
+++ b/aos/common/logging/implementations.cc
@@ -4,6 +4,7 @@
 #include <inttypes.h>
 
 #include <algorithm>
+#include <chrono>
 
 #include "aos/common/die.h"
 #include "aos/common/once.h"
@@ -16,6 +17,8 @@
 namespace logging {
 namespace {
 
+namespace chrono = ::std::chrono;
+
 // The root LogImplementation. It only logs to stderr/stdout.
 // Some of the things specified in the LogImplementation documentation doesn't
 // apply here (mostly the parts about being able to use LOG) because this is the
@@ -84,9 +87,14 @@
   memcpy(message->name, context->name, context->name_size);
   message->name_length = context->name_size;
 
-  time::Time now = time::Time::Now();
-  message->seconds = now.sec();
-  message->nseconds = now.nsec();
+  monotonic_clock::time_point monotonic_now = monotonic_clock::now();
+  message->seconds =
+      chrono::duration_cast<chrono::seconds>(monotonic_now.time_since_epoch())
+          .count();
+  message->nseconds =
+      chrono::duration_cast<chrono::nanoseconds>(
+          monotonic_now.time_since_epoch() - chrono::seconds(message->seconds))
+          .count();
 
   message->sequence = context->sequence++;
 }
@@ -325,9 +333,9 @@
 RawQueue *queue = NULL;
 
 int dropped_messages = 0;
-::aos::time::Time dropped_start, backoff_start;
+monotonic_clock::time_point dropped_start, backoff_start;
 // Wait this long after dropping a message before even trying to write any more.
-constexpr ::aos::time::Time kDropBackoff = ::aos::time::Time::InSeconds(0.1);
+constexpr chrono::milliseconds kDropBackoff = chrono::milliseconds(100);
 
 LogMessage *GetMessageOrDie() {
   LogMessage *message = static_cast<LogMessage *>(queue->GetMessage());
@@ -340,8 +348,8 @@
 
 void Write(LogMessage *msg) {
   if (__builtin_expect(dropped_messages > 0, false)) {
-    ::aos::time::Time message_time =
-        ::aos::time::Time(msg->seconds, msg->nseconds);
+    monotonic_clock::time_point message_time(
+        chrono::seconds(msg->seconds) + chrono::nanoseconds(msg->nseconds));
     if (message_time - backoff_start < kDropBackoff) {
       ++dropped_messages;
       queue->FreeMessage(msg);
@@ -349,10 +357,16 @@
     }
 
     LogMessage *dropped_message = GetMessageOrDie();
+    chrono::seconds dropped_start_sec = chrono::duration_cast<chrono::seconds>(
+        dropped_start.time_since_epoch());
+    chrono::nanoseconds dropped_start_nsec =
+        chrono::duration_cast<chrono::nanoseconds>(
+            dropped_start.time_since_epoch() - dropped_start_sec);
     internal::FillInMessageVarargs(
         ERROR, dropped_message,
         "%d logs starting at %" PRId32 ".%" PRId32 " dropped\n",
-        dropped_messages, dropped_start.sec(), dropped_start.nsec());
+        dropped_messages, static_cast<int32_t>(dropped_start_sec.count()),
+        static_cast<int32_t>(dropped_start_nsec.count()));
     if (queue->WriteMessage(dropped_message, RawQueue::kNonBlock)) {
       dropped_messages = 0;
     } else {
@@ -367,8 +381,9 @@
   }
   if (!queue->WriteMessage(msg, RawQueue::kNonBlock)) {
     if (dropped_messages == 0) {
-      dropped_start = backoff_start =
-          ::aos::time::Time(msg->seconds, msg->nseconds);
+      monotonic_clock::time_point message_time(
+          chrono::seconds(msg->seconds) + chrono::nanoseconds(msg->nseconds));
+      dropped_start = backoff_start = message_time;
     }
     ++dropped_messages;
   }
diff --git a/aos/common/logging/implementations_test.cc b/aos/common/logging/implementations_test.cc
index bbee5b7..aade0d1 100644
--- a/aos/common/logging/implementations_test.cc
+++ b/aos/common/logging/implementations_test.cc
@@ -1,7 +1,8 @@
-#include <string>
-
 #include <inttypes.h>
 
+#include <chrono>
+#include <string>
+
 #include "gtest/gtest.h"
 
 #include "aos/common/logging/implementations.h"
@@ -16,6 +17,8 @@
 namespace logging {
 namespace testing {
 
+namespace chrono = ::std::chrono;
+
 class TestLogImplementation : public SimpleLogImplementation {
   __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
   void DoLog(log_level level, const char *format, va_list ap) override {
@@ -168,23 +171,25 @@
   //static const long kTimingCycles = 5000000;
   static const long kTimingCycles = 5000;
 
-  time::Time start = time::Time::Now();
+  monotonic_clock::time_point start = monotonic_clock::now();
   for (long i = 0; i < kTimingCycles; ++i) {
     LOG(INFO, "a\n");
   }
-  time::Time end = time::Time::Now();
-  time::Time diff = end - start;
+  monotonic_clock::time_point end = monotonic_clock::now();
+  auto diff = end - start;
   printf("short message took %" PRId64 " nsec for %ld\n",
-         diff.ToNSec(), kTimingCycles);
+         chrono::duration_cast<chrono::nanoseconds>(diff).count(),
+         kTimingCycles);
 
-  start = time::Time::Now();
+  start = monotonic_clock::now();
   for (long i = 0; i < kTimingCycles; ++i) {
     LOG(INFO, "something longer than just \"a\" to log to test timing\n");
   }
-  end = time::Time::Now();
+  end = monotonic_clock::now();
   diff = end - start;
   printf("long message took %" PRId64 " nsec for %ld\n",
-         diff.ToNSec(), kTimingCycles);
+         chrono::duration_cast<chrono::nanoseconds>(diff).count(),
+         kTimingCycles);
 }
 
 TEST(LoggingPrintFormatTest, Time) {
diff --git a/aos/common/logging/log_streamer.cc b/aos/common/logging/log_streamer.cc
index ab37e02..74e680b 100644
--- a/aos/common/logging/log_streamer.cc
+++ b/aos/common/logging/log_streamer.cc
@@ -1,40 +1,47 @@
-#include <stdio.h>
-#include <stdlib.h>
 #include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <string>
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <chrono>
+#include <string>
 
+#include "aos/common/logging/implementations.h"
+#include "aos/common/logging/logging.h"
+#include "aos/common/time.h"
 #include "aos/linux_code/init.h"
 #include "aos/linux_code/ipc_lib/queue.h"
-#include "aos/common/logging/logging.h"
-#include "aos/common/logging/implementations.h"
-#include "aos/common/time.h"
 
 namespace aos {
 namespace logging {
 namespace linux_code {
 namespace {
 
+namespace chrono = ::std::chrono;
+
 int LogStreamerMain() {
   InitNRT();
 
   RawQueue *queue = GetLoggingQueue();
 
-  const time::Time now = time::Time::Now();
+  const monotonic_clock::time_point now = monotonic_clock::now();
+  chrono::seconds sec =
+      chrono::duration_cast<chrono::seconds>(now.time_since_epoch());
+  chrono::nanoseconds nsec =
+      chrono::duration_cast<chrono::nanoseconds>(now.time_since_epoch() - sec);
   printf("starting at %" PRId32 "s%" PRId32 "ns-----------------------------\n",
-         now.sec(), now.nsec());
+         static_cast<int32_t>(sec.count()), static_cast<int32_t>(nsec.count()));
 
   while (true) {
     const LogMessage *const msg = static_cast<const LogMessage *>(
         queue->ReadMessage(RawQueue::kNonBlock));
     if (msg == NULL) {
-      ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.1));
+      ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
     } else {
       internal::PrintMessage(stdout, *msg);
 
diff --git a/aos/common/logging/replay.cc b/aos/common/logging/replay.cc
index 7180c96..6b55e51 100644
--- a/aos/common/logging/replay.cc
+++ b/aos/common/logging/replay.cc
@@ -1,9 +1,13 @@
 #include "aos/common/logging/replay.h"
 
+#include <chrono>
+
 namespace aos {
 namespace logging {
 namespace linux_code {
 
+namespace chrono = ::std::chrono;
+
 bool LogReplayer::ProcessMessage() {
   const LogFileMessageHeader *message = reader_->ReadNextMessage(false);
   if (message == nullptr) return true;
@@ -32,8 +36,9 @@
   if (handler == handlers_.end()) return false;
 
   handler->second->HandleStruct(
-      ::aos::time::Time(message->time_sec, message->time_nsec), type_id,
-      position,
+      monotonic_clock::time_point(chrono::seconds(message->time_sec) +
+                                  chrono::nanoseconds(message->time_nsec)),
+      type_id, position,
       message->message_size -
           (sizeof(type_id) + sizeof(message_length) + message_length));
   return false;
diff --git a/aos/common/logging/replay.h b/aos/common/logging/replay.h
index 38f7120..1a8418f 100644
--- a/aos/common/logging/replay.h
+++ b/aos/common/logging/replay.h
@@ -80,8 +80,9 @@
    public:
     virtual ~StructHandlerInterface() {}
 
-    virtual void HandleStruct(::aos::time::Time log_time, uint32_t type_id,
-                              const void *data, size_t data_size) = 0;
+    virtual void HandleStruct(::aos::monotonic_clock::time_point log_time,
+                              uint32_t type_id, const void *data,
+                              size_t data_size) = 0;
   };
 
   // Converts struct log messages to a message type and passes it to an
@@ -92,8 +93,9 @@
     TypedStructHandler(::std::function<void(const T &message)> handler)
         : handler_(handler) {}
 
-    void HandleStruct(::aos::time::Time log_time, uint32_t type_id,
-                      const void *data, size_t data_size) override {
+    void HandleStruct(::aos::monotonic_clock::time_point log_time,
+                      uint32_t type_id, const void *data,
+                      size_t data_size) override {
       CHECK_EQ(type_id, T::GetType()->id);
       T message;
       CHECK_EQ(data_size, T::Size());
diff --git a/aos/common/mutex_test.cc b/aos/common/mutex_test.cc
index 8cc4e73..3717109 100644
--- a/aos/common/mutex_test.cc
+++ b/aos/common/mutex_test.cc
@@ -1,25 +1,29 @@
 #include "aos/common/mutex.h"
 
-#include <sched.h>
 #include <math.h>
 #include <pthread.h>
+#include <sched.h>
 
+#include <chrono>
 #include <thread>
 
 #include "gtest/gtest.h"
 
-#include "aos/linux_code/ipc_lib/aos_sync.h"
 #include "aos/common/die.h"
+#include "aos/common/time.h"
 #include "aos/common/util/death_test_log_implementation.h"
 #include "aos/common/util/thread.h"
-#include "aos/common/time.h"
+#include "aos/linux_code/ipc_lib/aos_sync.h"
+#include "aos/linux_code/ipc_lib/core_lib.h"
 #include "aos/testing/test_logging.h"
 #include "aos/testing/test_shm.h"
-#include "aos/linux_code/ipc_lib/core_lib.h"
 
 namespace aos {
 namespace testing {
 
+namespace chrono = ::std::chrono;
+namespace this_thread = ::std::this_thread;
+
 class MutexTest : public ::testing::Test {
  public:
   Mutex test_mutex_;
@@ -169,8 +173,9 @@
 
 class AdderThread : public ::aos::util::Thread {
  public:
-  AdderThread(int *counter, Mutex *mutex, ::aos::time::Time sleep_before_time,
-              ::aos::time::Time sleep_after_time)
+  AdderThread(int *counter, Mutex *mutex,
+              monotonic_clock::duration sleep_before_time,
+              monotonic_clock::duration sleep_after_time)
       : counter_(counter),
         mutex_(mutex),
         sleep_before_time_(sleep_before_time),
@@ -178,15 +183,15 @@
 
  private:
   virtual void Run() override {
-    ::aos::time::SleepFor(sleep_before_time_);
+    this_thread::sleep_for(sleep_before_time_);
     MutexLocker locker(mutex_);
     ++(*counter_);
-    ::aos::time::SleepFor(sleep_after_time_);
+    this_thread::sleep_for(sleep_after_time_);
   }
 
   int *const counter_;
   Mutex *const mutex_;
-  const ::aos::time::Time sleep_before_time_, sleep_after_time_;
+  const monotonic_clock::duration sleep_before_time_, sleep_after_time_;
 };
 
 }  // namespace
@@ -196,10 +201,11 @@
 TEST_F(MutexTest, ThreadSanitizerContended) {
   int counter = 0;
   AdderThread threads[2]{
-      {&counter, &test_mutex_, ::aos::time::Time::InSeconds(0.2),
-       ::aos::time::Time::InSeconds(0)},
-      {&counter, &test_mutex_, ::aos::time::Time::InSeconds(0),
-       ::aos::time::Time::InSeconds(0)}, };
+      {&counter, &test_mutex_, chrono::milliseconds(200),
+       chrono::milliseconds(0)},
+      {&counter, &test_mutex_, chrono::milliseconds(0),
+       chrono::milliseconds(0)},
+  };
   for (auto &c : threads) {
     c.Start();
   }
@@ -235,10 +241,10 @@
 TEST_F(MutexTest, ThreadSanitizerUncontended) {
   int counter = 0;
   AdderThread threads[2]{
-      {&counter, &test_mutex_, ::aos::time::Time::InSeconds(0),
-       ::aos::time::Time::InSeconds(0)},
-      {&counter, &test_mutex_, ::aos::time::Time::InSeconds(0.2),
-       ::aos::time::Time::InSeconds(0)}, };
+      {&counter, &test_mutex_, chrono::milliseconds(0),
+       chrono::milliseconds(0)},
+      {&counter, &test_mutex_, chrono::milliseconds(200),
+       chrono::milliseconds(0)}, };
   for (auto &c : threads) {
     c.Start();
   }
diff --git a/aos/common/network/socket.cc b/aos/common/network/socket.cc
index b674ff1..80eca70 100644
--- a/aos/common/network/socket.cc
+++ b/aos/common/network/socket.cc
@@ -1,15 +1,18 @@
 #include "aos/common/network/socket.h"
 
-#include <string.h>
 #include <errno.h>
+#include <string.h>
 #include <sys/socket.h>
+#include <chrono>
 
-#include "aos/common/logging/logging.h"
 #include "aos/common/byteorder.h"
+#include "aos/common/logging/logging.h"
 
 namespace aos {
 namespace network {
 
+namespace chrono = ::std::chrono;
+
 int Socket::Connect(NetworkPort port, const char *address, int type) {
   last_ret_ = 0;
   if ((socket_ = socket(AF_INET, type, 0)) < 0) {
@@ -53,8 +56,13 @@
   return ret;
 }
 
-int Socket::Receive(void *buf, int length, time::Time timeout) {
-  timeval timeout_timeval = timeout.ToTimeval();
+int Socket::Receive(void *buf, int length, chrono::microseconds timeout) {
+  timeval timeout_timeval;
+  timeout_timeval.tv_sec = chrono::duration_cast<chrono::seconds>(timeout).count();
+  timeout_timeval.tv_usec =
+      chrono::duration_cast<chrono::microseconds>(
+          timeout - chrono::seconds(timeout_timeval.tv_sec))
+          .count();
   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(socket_, &fds);
diff --git a/aos/common/network/socket.h b/aos/common/network/socket.h
index 9e8eaf5..9bda8aa 100644
--- a/aos/common/network/socket.h
+++ b/aos/common/network/socket.h
@@ -1,15 +1,15 @@
 #ifndef AOS_COMMON_NETWORK_SOCKET_H_
 #define AOS_COMMON_NETWORK_SOCKET_H_
 
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
 #include <unistd.h>
-#include <stdio.h>
+#include <chrono>
 
-#include "aos/common/time.h"
 #include "aos/common/network_port.h"
 
 namespace aos {
@@ -28,7 +28,7 @@
   // No timeout.
   int Receive(void *buf, int length);
   // timeout is relative
-  int Receive(void *buf, int length, time::Time timeout);
+  int Receive(void *buf, int length, ::std::chrono::microseconds timeout);
 
  protected:
   int Connect(NetworkPort port, const char *address, int type = SOCK_DGRAM);
diff --git a/aos/common/queue.cc b/aos/common/queue.cc
index 893e62b..ba85a72 100644
--- a/aos/common/queue.cc
+++ b/aos/common/queue.cc
@@ -1,37 +1,47 @@
 #include "aos/common/queue.h"
 
-#include "aos/common/byteorder.h"
 #include <inttypes.h>
+#include <chrono>
+
+#include "aos/common/byteorder.h"
 
 namespace aos {
 
-void Message::Zero() {
-  sent_time.set_sec(0);
-  sent_time.set_nsec(0);
-}
+namespace chrono = ::std::chrono;
+
+void Message::Zero() { sent_time = monotonic_clock::min_time; }
 
 size_t Message::Deserialize(const char *buffer) {
   int32_t sec;
   int32_t nsec;
   to_host(&buffer[0], &sec);
   to_host(&buffer[4], &nsec);
-  sent_time.set_sec(sec);
-  sent_time.set_nsec(nsec);
+  sent_time = monotonic_clock::time_point(chrono::seconds(sec) +
+                                          chrono::nanoseconds(nsec));
   return Size();
 }
 // Serializes the common fields into the buffer.
 size_t Message::Serialize(char *buffer) const {
   // TODO(aschuh): to_network shouldn't need a pointer.
-  int32_t sec = sent_time.sec();
-  int32_t nsec = sent_time.nsec();
+  int32_t sec =
+      chrono::duration_cast<chrono::seconds>(sent_time.time_since_epoch())
+          .count();
+  int32_t nsec = chrono::duration_cast<chrono::nanoseconds>(
+                     sent_time.time_since_epoch() - chrono::seconds(sec))
+                     .count();
   to_network(&sec, &buffer[0]);
   to_network(&nsec, &buffer[4]);
   return Size();
 }
 
 size_t Message::Print(char *buffer, int length) const {
-  return snprintf(buffer, length, "%" PRId32 ".%09" PRId32 "s",
-                  sent_time.sec(), sent_time.nsec());
+  int32_t sec =
+      chrono::duration_cast<chrono::seconds>(sent_time.time_since_epoch())
+          .count();
+  int32_t nsec = chrono::duration_cast<chrono::nanoseconds>(
+                     sent_time.time_since_epoch() - chrono::seconds(sec))
+                     .count();
+  return snprintf(buffer, length, "%" PRId32 ".%09" PRId32 "s", sec, nsec);
 }
 
 }  // namespace aos
diff --git a/aos/common/queue.h b/aos/common/queue.h
index 5f5d8b0..7f43a3e 100644
--- a/aos/common/queue.h
+++ b/aos/common/queue.h
@@ -16,16 +16,15 @@
 // thing for the whole thing.
 class Message {
  public:
-  typedef ::aos::time::Time Time;
   // The time that the message was sent at.
-  Time sent_time;
+  monotonic_clock::time_point sent_time;
 
-  Message() : sent_time(0, 0) {}
+  Message() : sent_time(monotonic_clock::min_time) {}
 
   // Zeros out the time.
   void Zero();
   // Returns the size of the common fields.
-  static size_t Size() { return sizeof(Time); }
+  static size_t Size() { return sizeof(sent_time); }
 
   // Deserializes the common fields from the buffer.
   size_t Deserialize(const char *buffer);
@@ -33,7 +32,7 @@
   size_t Serialize(char *buffer) const;
 
   // Populates sent_time with the current time.
-  void SetTimeToNow() { sent_time = Time::Now(); }
+  void SetTimeToNow() { sent_time = monotonic_clock::now(); }
 
   // Writes the contents of the message to the provided buffer.
   size_t Print(char *buffer, int length) const;
@@ -198,18 +197,11 @@
   void FetchAnother();
 
   // Returns the age of the message.
-  const time::Time Age() const {
-    return time::Time::Now() - queue_msg_->sent_time;
+  const monotonic_clock::duration Age() const {
+    return monotonic_clock::now() - queue_msg_->sent_time;
   }
 
-  // Returns true if the latest value in the queue is newer than age mseconds.
-  // DEPRECATED(brians): Use IsNewerThan(const time::Time&) instead.
-  bool IsNewerThanMS(int age) const {
-    // TODO(aschuh): Log very verbosely if something is _ever_ stale.
-    return IsNewerThan(time::Time::InMS(age));
-  }
-
-  bool IsNewerThan(const time::Time &age) const {
+  bool IsNewerThan(const monotonic_clock::duration age) const {
     return get() != nullptr && Age() < age;
   }
 
diff --git a/aos/common/queue_test.cc b/aos/common/queue_test.cc
index dc8c62c..eb109ba 100644
--- a/aos/common/queue_test.cc
+++ b/aos/common/queue_test.cc
@@ -1,20 +1,21 @@
 #include <unistd.h>
 
+#include <chrono>
 #include <memory>
 
 #include "gtest/gtest.h"
 
+#include "aos/common/die.h"
 #include "aos/common/test_queue.q.h"
 #include "aos/common/util/thread.h"
-#include "aos/common/die.h"
 #include "aos/testing/test_shm.h"
 
-using ::aos::time::Time;
-
 namespace aos {
 namespace common {
 namespace testing {
 
+namespace chrono = ::std::chrono;
+
 class QueueTest : public ::testing::Test {
  protected:
   void SetUp() override {
@@ -54,7 +55,7 @@
   usleep(50000);
   my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
   t.Join();
-  EXPECT_LE(t.threaded_test_queue.Age(), time::Time::InMS(57));
+  EXPECT_LE(t.threaded_test_queue.Age(), chrono::milliseconds(57));
 }
 
 // Tests that we can send a message with the message pointer and get it back.
@@ -76,7 +77,7 @@
   ASSERT_TRUE(my_test_queue.FetchLatest());
   EXPECT_EQ(true, my_test_queue->test_bool);
   EXPECT_EQ(0x971, my_test_queue->test_int);
-  EXPECT_EQ(true, my_test_queue.IsNewerThanMS(10000));
+  EXPECT_EQ(true, my_test_queue.IsNewerThan(chrono::milliseconds(10000)));
 }
 
 // Tests that multiple queue instances don't break each other.
@@ -202,10 +203,9 @@
   my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
 
   ASSERT_TRUE(my_test_queue.FetchLatest());
-  EXPECT_TRUE(my_test_queue.IsNewerThanMS(100));
-  const Time age = my_test_queue.Age();
-  EXPECT_EQ(0, age.sec());
-  EXPECT_GE(100000000, age.nsec());
+  EXPECT_TRUE(my_test_queue.IsNewerThan(chrono::milliseconds(100)));
+  const auto age = my_test_queue.Age();
+  EXPECT_GE(chrono::nanoseconds(100000000), age);
 }
 
 
@@ -257,8 +257,7 @@
 
   EXPECT_FALSE(msg.test_bool);
   EXPECT_EQ(0, msg.test_int);
-  EXPECT_EQ(0, msg.sent_time.sec());
-  EXPECT_EQ(0, msg.sent_time.nsec());
+  EXPECT_EQ(monotonic_clock::min_time, msg.sent_time);
 }
 
 TEST_F(MessageTest, Size) {
@@ -286,7 +285,8 @@
   char printdata[1024];
   msg.test_bool = true;
   msg.test_int = 2056;
-  msg.sent_time = Time(971, 254);
+  msg.sent_time = monotonic_clock::time_point(chrono::seconds(971) +
+                                              chrono::nanoseconds(254));
 
   std::string golden("971.000000254s, T, 2056");
   EXPECT_EQ(golden.size(), msg.Print(printdata, sizeof(printdata)));
@@ -304,7 +304,7 @@
 
 TEST_F(MessageTest, SetNow) {
   msg.SetTimeToNow();
-  EXPECT_LE(msg.sent_time - Time::Now(), Time::InMS(20));
+  EXPECT_LE(msg.sent_time - monotonic_clock::now(), chrono::milliseconds(20));
 }
 
 // Tests that EqualsNoTime works.
diff --git a/aos/common/time.cc b/aos/common/time.cc
index 7cfc4bc..e8bd25b 100644
--- a/aos/common/time.cc
+++ b/aos/common/time.cc
@@ -1,9 +1,10 @@
 #include "aos/common/time.h"
 
-#include <atomic>
-
-#include <string.h>
 #include <inttypes.h>
+#include <string.h>
+
+#include <atomic>
+#include <chrono>
 
 // We only use global_core from here, which is weak, so we don't really have a
 // dependency on it.
@@ -12,6 +13,8 @@
 #include "aos/common/logging/logging.h"
 #include "aos/common/mutex.h"
 
+namespace chrono = ::std::chrono;
+
 namespace std {
 namespace this_thread {
 template <>
@@ -57,34 +60,8 @@
 // Current time when time is mocked.
 monotonic_clock::time_point current_mock_time = monotonic_clock::epoch();
 
-// TODO(aschuh): This doesn't include SleepFor and SleepUntil.
-// TODO(aschuh): Create a clock source object and change the default?
-//  That would let me create a MockTime clock source.
-
-Time NowImpl(clockid_t clock) {
-  timespec temp;
-  if (clock_gettime(clock, &temp) != 0) {
-    PLOG(FATAL, "clock_gettime(%jd, %p) failed",
-         static_cast<uintmax_t>(clock), &temp);
-  }
-
-  const timespec offset = (&global_core == nullptr || global_core == nullptr ||
-                           global_core->mem_struct == nullptr)
-                              ? timespec{0, 0}
-                              : global_core->mem_struct->time_offset;
-  return Time(temp) + Time(offset);
-}
-
 }  // namespace
 
-const int32_t Time::kNSecInSec;
-const int32_t Time::kNSecInMSec;
-const int32_t Time::kNSecInUSec;
-const int32_t Time::kMSecInSec;
-const int32_t Time::kUSecInSec;
-
-const Time Time::kZero{0, 0};
-
 void EnableMockTime(monotonic_clock::time_point now) {
   MutexLocker time_mutex_locker(&time_mutex);
   mock_time_enabled = true;
@@ -112,162 +89,13 @@
   SetMockTime(monotonic_clock::now() + amount);
 }
 
-Time Time::Now(clockid_t clock) {
-  {
-    if (mock_time_enabled.load(::std::memory_order_relaxed)) {
-      MutexLocker time_mutex_locker(&time_mutex);
-      return Time::InNS(
-          ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
-              current_mock_time.time_since_epoch()).count());
-    }
-  }
-  return NowImpl(clock);
-}
-
-void Time::CheckImpl(int32_t nsec) {
-  static_assert(aos::shm_ok<Time>::value,
-                "it should be able to go through shared memory");
-  if (nsec >= kNSecInSec || nsec < 0) {
-    LOG(FATAL, "0 <= nsec(%" PRId32 ") < %" PRId32 " isn't true.\n",
-        nsec, kNSecInSec);
-  }
-}
-
-Time &Time::operator+=(const Time &rhs) {
-  sec_ += rhs.sec_;
-  nsec_ += rhs.nsec_;
-  if (nsec_ >= kNSecInSec) {
-    nsec_ -= kNSecInSec;
-    sec_ += 1;
-  }
-  return *this;
-}
-const Time Time::operator+(const Time &rhs) const {
-  return Time(*this) += rhs;
-}
-Time &Time::operator-=(const Time &rhs) {
-  sec_ -= rhs.sec_;
-  nsec_ -= rhs.nsec_;
-  if (nsec_ < 0) {
-    nsec_ += kNSecInSec;
-    sec_ -= 1;
-  }
-  return *this;
-}
-const Time Time::operator-(const Time &rhs) const {
-  return Time(*this) -= rhs;
-}
-Time &Time::operator*=(int32_t rhs) {
-  const int64_t temp = static_cast<int64_t>(nsec_) *
-      static_cast<int64_t>(rhs);
-  sec_ *= rhs;  // better not overflow, or the result is just too big
-  nsec_ = temp % kNSecInSec;
-  sec_ += (temp - nsec_) / kNSecInSec;
-  if (nsec_ < 0) {
-    nsec_ += kNSecInSec;
-    sec_ -= 1;
-  }
-  return *this;
-}
-const Time Time::operator*(int32_t rhs) const {
-  return Time(*this) *= rhs;
-}
-Time &Time::operator/=(int32_t rhs) {
-  nsec_ = (sec_ % rhs) * (kNSecInSec / rhs) + nsec_ / rhs;
-  sec_ /= rhs;
-  if (nsec_ < 0) {
-    nsec_ += kNSecInSec;
-    sec_ -= 1;
-  }
-  return *this;
-}
-const Time Time::operator/(int32_t rhs) const {
-  return Time(*this) /= rhs;
-}
-double Time::operator/(const Time &rhs) const {
-  return ToSeconds() / rhs.ToSeconds();
-}
-Time &Time::operator%=(int32_t rhs) {
-  nsec_ = ToNSec() % rhs;
-  const int wraps = nsec_ / ((rhs / kNSecInSec + 1) * kNSecInSec);
-  sec_ = wraps + rhs / kNSecInSec;
-  nsec_ -= kNSecInSec * wraps;
-  if (nsec_ < 0) {
-    nsec_ += kNSecInSec;
-    sec_ -= 1;
-  }
-  return *this;
-}
-const Time Time::operator%(int32_t rhs) const {
-  return Time(*this) %= rhs;
-}
-
-const Time Time::operator-() const {
-  return Time(-sec_ - 1, kNSecInSec - nsec_);
-}
-
-bool Time::operator==(const Time &rhs) const {
-  return sec_ == rhs.sec_ && nsec_ == rhs.nsec_;
-}
-bool Time::operator!=(const Time &rhs) const {
-  return !(*this == rhs);
-}
-bool Time::operator<(const Time &rhs) const {
-  return sec_ < rhs.sec_ || (sec_ == rhs.sec_ && nsec_ < rhs.nsec_);
-}
-bool Time::operator>(const Time &rhs) const {
-  return sec_ > rhs.sec_ || (sec_ == rhs.sec_ && nsec_ > rhs.nsec_);
-}
-bool Time::operator<=(const Time &rhs) const {
-  return sec_ < rhs.sec_ || (sec_ == rhs.sec_ && nsec_ <= rhs.nsec_);
-}
-bool Time::operator>=(const Time &rhs) const {
-  return sec_ > rhs.sec_ || (sec_ == rhs.sec_ && nsec_ >= rhs.nsec_);
-}
-
-bool Time::IsWithin(const Time &other, int64_t amount) const {
-  const int64_t temp = ToNSec() - other.ToNSec();
-  return temp <= amount && temp >= -amount;
-}
-
-std::ostream &operator<<(std::ostream &os, const Time& time) {
-  return os << "Time{" << time.sec_ << "s, " << time.nsec_ << "ns}";
-}
-
-void SleepFor(const Time &time, clockid_t clock) {
-  timespec converted(time.ToTimespec()), remaining;
-  int failure = EINTR;
-  do {
-    // This checks whether the last time through the loop actually failed or got
-    // interrupted.
-    if (failure != EINTR) {
-      PELOG(FATAL, failure, "clock_nanosleep(%jd, 0, %p, %p) failed",
-            static_cast<intmax_t>(clock), &converted, &remaining);
-    }
-    failure = clock_nanosleep(clock, 0, &converted, &remaining);
-    memcpy(&converted, &remaining, sizeof(converted));
-  } while (failure != 0);
-}
-
-void SleepUntil(const Time &time, clockid_t clock) {
-  timespec converted(time.ToTimespec());
-  int failure;
-  while ((failure = clock_nanosleep(clock, TIMER_ABSTIME,
-                                    &converted, NULL)) != 0) {
-    if (failure != EINTR) {
-      PELOG(FATAL, failure, "clock_nanosleep(%jd, TIMER_ABSTIME, %p, NULL)"
-            " failed", static_cast<intmax_t>(clock), &converted);
-    }
-  }
-}
-
-void OffsetToNow(const Time &now) {
+void OffsetToNow(monotonic_clock::time_point now) {
   CHECK_NOTNULL(&global_core);
   CHECK_NOTNULL(global_core);
   CHECK_NOTNULL(global_core->mem_struct);
-  global_core->mem_struct->time_offset.tv_nsec = 0;
-  global_core->mem_struct->time_offset.tv_sec = 0;
-  global_core->mem_struct->time_offset = (now - Time::Now()).ToTimespec();
+  const auto offset = now - monotonic_clock::now();
+  global_core->mem_struct->time_offset =
+      chrono::duration_cast<chrono::nanoseconds>(offset).count();
 }
 
 }  // namespace time
@@ -287,8 +115,14 @@
     PLOG(FATAL, "clock_gettime(%jd, %p) failed",
          static_cast<uintmax_t>(CLOCK_MONOTONIC), &current_time);
   }
+  const chrono::nanoseconds offset =
+      (&global_core == nullptr || global_core == nullptr ||
+       global_core->mem_struct == nullptr)
+          ? chrono::nanoseconds(0)
+          : chrono::nanoseconds(global_core->mem_struct->time_offset);
+
   return time_point(::std::chrono::seconds(current_time.tv_sec) +
-                    ::std::chrono::nanoseconds(current_time.tv_nsec));
+                    ::std::chrono::nanoseconds(current_time.tv_nsec)) + offset;
 }
 
 
diff --git a/aos/common/time.h b/aos/common/time.h
index ab64916..e541932 100644
--- a/aos/common/time.h
+++ b/aos/common/time.h
@@ -52,244 +52,23 @@
 // Disables mocking time.
 void DisableMockTime();
 
-// A nice structure for representing times.
-// 0 <= nsec_ < kNSecInSec should always be true. All functions here will make
-// sure that that is true if it was on all inputs (including *this).
-//
-// Negative times are supported so that all of the normal arithmetic identities
-// work. nsec_ is still always positive.
-//
-// The arithmetic and comparison operators are overloaded because they make
-// complete sense and are very useful. The default copy and assignment stuff is
-// left because it works fine. Multiplication of Times by Times is
-// not implemented because I can't think of any uses for them and there are
-// multiple ways to do it. Division of Times by Times is implemented as the
-// ratio of them. Multiplication, division, and modulus of Times by integers are
-// implemented as interpreting the argument as nanoseconds. Modulus takes the
-// sign from the first operand.
-struct Time {
-#ifdef SWIG
-// All of the uses of constexpr here can safely be simply removed.
-// NOTE: This means that relying on the fact that constexpr implicitly makes
-// member functions const is not valid, so they all have to be explicitly marked
-// const.
-#define constexpr
-#endif  // SWIG
- public:
-  static const int32_t kNSecInSec = 1000000000;
-  static const int32_t kNSecInMSec = 1000000;
-  static const int32_t kNSecInUSec = 1000;
-  static const int32_t kMSecInSec = 1000;
-  static const int32_t kUSecInSec = 1000000;
-
-  static const Time kZero;
-
-  explicit constexpr Time(int32_t sec = 0, int32_t nsec = 0)
-      : sec_(sec), nsec_(CheckConstexpr(nsec)) {
-  }
-  #ifndef SWIG
-  explicit constexpr Time(const struct timespec &value)
-      : sec_(value.tv_sec), nsec_(CheckConstexpr(value.tv_nsec)) {
-  }
-  struct timespec ToTimespec() const {
-    struct timespec ans;
-    ans.tv_sec = sec_;
-    ans.tv_nsec = nsec_;
-    return ans;
-  }
-  explicit constexpr Time(const struct timeval &value)
-      : sec_(value.tv_sec), nsec_(CheckConstexpr(value.tv_usec * kNSecInUSec)) {
-  }
-  struct timeval ToTimeval() const {
-    struct timeval ans;
-    ans.tv_sec = sec_;
-    ans.tv_usec = nsec_ / kNSecInUSec;
-    return ans;
-  }
-  #endif  // SWIG
-
-  // CLOCK_MONOTONIC on linux and CLOCK_REALTIME on the cRIO because the
-  // cRIO doesn't have any others.
-  // CLOCK_REALTIME is the default realtime clock and CLOCK_MONOTONIC doesn't
-  // change when somebody changes the wall clock (like the ntp deamon or
-  // whatever). See clock_gettime(2) for details.
-  //
-  // This is the clock that code that just wants to sleep for a certain amount
-  // of time or measure how long something takes should use.
-  #ifndef __VXWORKS__
-  static const clockid_t kDefaultClock = CLOCK_MONOTONIC;
-  #else
-  static const clockid_t kDefaultClock = CLOCK_REALTIME;
-  #endif
-  // Creates a Time representing the current value of the specified clock or
-  // dies.
-  static Time Now(clockid_t clock = kDefaultClock);
-
-  // Constructs a Time representing seconds.
-  static constexpr Time InSeconds(double seconds) {
-    return (seconds < 0.0) ?
-        Time(static_cast<int32_t>(seconds) - 1,
-             (seconds - static_cast<int32_t>(seconds) + 1.0) * kNSecInSec) :
-        Time(static_cast<int32_t>(seconds),
-             (seconds - static_cast<int32_t>(seconds)) * kNSecInSec);
-  }
-
-  // Constructs a time representing microseconds.
-  static constexpr Time InNS(int64_t nseconds) {
-    return (nseconds < 0)
-               ? Time((nseconds - 1) / static_cast<int64_t>(kNSecInSec) - 1,
-                      (((nseconds - 1) % kNSecInSec) + 1) + kNSecInSec)
-               : Time(nseconds / static_cast<int64_t>(kNSecInSec),
-                      nseconds % kNSecInSec);
-  }
-
-  // Constructs a time representing microseconds.
-  static constexpr Time InUS(int useconds) {
-    return (useconds < 0)
-               ? Time((useconds + 1) / kUSecInSec - 1,
-                      (((useconds + 1) % kUSecInSec) - 1) * kNSecInUSec +
-                          kNSecInSec)
-               : Time(useconds / kUSecInSec,
-                      (useconds % kUSecInSec) * kNSecInUSec);
-  }
-
-  // Constructs a time representing mseconds.
-  static constexpr Time InMS(int mseconds) {
-    return (mseconds < 0)
-               ? Time((mseconds + 1) / kMSecInSec - 1,
-                      (((mseconds + 1) % kMSecInSec) - 1) * kNSecInMSec +
-                          kNSecInSec)
-               : Time(mseconds / kMSecInSec,
-                      (mseconds % kMSecInSec) * kNSecInMSec);
-  }
-
-  // Construct a time representing the period of hertz.
-  static constexpr ::std::chrono::nanoseconds FromRate(int hertz) {
-    return ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
-               ::std::chrono::seconds(1)) /
-           hertz;
-  }
-
-  // Checks whether or not this time is within amount nanoseconds of other.
-  bool IsWithin(const Time &other, int64_t amount) const;
-
-  // Returns the time represented all in nanoseconds.
-  int64_t constexpr ToNSec() const {
-    return static_cast<int64_t>(sec_) * static_cast<int64_t>(kNSecInSec) +
-        static_cast<int64_t>(nsec_);
-  }
-#ifdef __VXWORKS__
-  // Returns the time represented all in system clock ticks. The system clock
-  // rate is retrieved using sysClkRateGet().
-  int ToTicks() const {
-    return ToNSec() / static_cast<int64_t>(kNSecInSec / sysClkRateGet());
-  }
-  // Constructs a Time representing ticks.
-  static Time InTicks(int ticks) {
-    return Time::InSeconds(static_cast<double>(ticks) / sysClkRateGet());
-  }
-#endif
-
-  // Returns the time represented in milliseconds.
-  int64_t constexpr ToMSec() const {
-    return static_cast<int64_t>(sec_) * static_cast<int64_t>(kMSecInSec) +
-        (static_cast<int64_t>(nsec_) / static_cast<int64_t>(kNSecInMSec));
-  }
-
-  // Returns the time represent in microseconds.
-  int64_t constexpr ToUSec() const {
-    return static_cast<int64_t>(sec_) * static_cast<int64_t>(kUSecInSec) +
-        (static_cast<int64_t>(nsec_) / static_cast<int64_t>(kNSecInUSec));
-  }
-
-  // Returns the time represented in fractional seconds.
-  double constexpr ToSeconds() const {
-    return static_cast<double>(sec_) + static_cast<double>(nsec_) / kNSecInSec;
-  }
-
-  #ifndef SWIG
-  Time &operator+=(const Time &rhs);
-  Time &operator-=(const Time &rhs);
-  Time &operator*=(int32_t rhs);
-  Time &operator/=(int32_t rhs);
-  Time &operator%=(int32_t rhs);
-  Time &operator%=(double rhs) = delete;
-  Time &operator*=(double rhs) = delete;
-  Time &operator/=(double rhs) = delete;
-  const Time operator*(double rhs) const = delete;
-  const Time operator/(double rhs) const = delete;
-  const Time operator%(double rhs) const = delete;
-  #endif
-  const Time operator+(const Time &rhs) const;
-  const Time operator-(const Time &rhs) const;
-  const Time operator*(int32_t rhs) const;
-  const Time operator/(int32_t rhs) const;
-  double operator/(const Time &rhs) const;
-  const Time operator%(int32_t rhs) const;
-
-  const Time operator-() const;
-
-  bool operator==(const Time &rhs) const;
-  bool operator!=(const Time &rhs) const;
-  bool operator<(const Time &rhs) const;
-  bool operator>(const Time &rhs) const;
-  bool operator<=(const Time &rhs) const;
-  bool operator>=(const Time &rhs) const;
-
-  #ifndef SWIG
-  // For gtest etc.
-  friend std::ostream &operator<<(std::ostream &os, const Time &time);
-  #endif  // SWIG
-
-  int32_t constexpr sec() const { return sec_; }
-  void set_sec(int32_t sec) { sec_ = sec; }
-  int32_t constexpr nsec() const { return nsec_; }
-  void set_nsec(int32_t nsec) {
-    nsec_ = nsec;
-    Check();
-  }
-
-  // Absolute value.
-  Time abs() const {
-    if (*this > Time(0, 0)) return *this;
-    if (nsec_ == 0) return Time(-sec_, 0);
-    return Time(-sec_ - 1, kNSecInSec - nsec_);
-  }
-
- private:
-  int32_t sec_, nsec_;
-
-  // LOG(FATAL)s if nsec is >= kNSecInSec or negative.
-  static void CheckImpl(int32_t nsec);
-  void Check() { CheckImpl(nsec_); }
-  // A constexpr version of CheckImpl that returns the given value when it
-  // succeeds or evaluates to non-constexpr and returns 0 when it fails.
-  // This will result in the usual LOG(FATAL) if this is used where it isn't
-  // required to be constexpr or a compile error if it is.
-  static constexpr int32_t CheckConstexpr(int32_t nsec) {
-    return (nsec >= kNSecInSec || nsec < 0) ? CheckImpl(nsec), 0 : nsec;
-  }
-
-#ifdef SWIG
-#undef constexpr
-#endif  // SWIG
-};
-
-// Sleeps for the amount of time represented by time counted by clock.
-void SleepFor(const Time &time, clockid_t clock = Time::kDefaultClock);
-// Sleeps until clock is at the time represented by time.
-void SleepUntil(const Time &time, clockid_t clock = Time::kDefaultClock);
-
-// Sets the global offset for all times so ::aos::time::Time::Now() will return
+// Sets the global offset for all times so monotonic_clock::now() will return
 // now.
 // There is no synchronization here, so this is only safe when only a single
 // task is running.
 // This is only allowed when the shared memory core infrastructure has been
 // initialized in this process.
-void OffsetToNow(const Time &now);
+void OffsetToNow(const monotonic_clock::time_point now);
 
-// RAII class that freezes Time::Now() (to avoid making large numbers of
-// syscalls to find the real time).
+// Construct a time representing the period of hertz.
+constexpr ::std::chrono::nanoseconds FromRate(int hertz) {
+  return ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
+             ::std::chrono::seconds(1)) /
+         hertz;
+}
+
+// RAII class that freezes monotonic_clock::now() (to avoid making large numbers
+// of syscalls to find the real time).
 class TimeFreezer {
  public:
   TimeFreezer() { EnableMockTime(monotonic_clock::now()); }
diff --git a/aos/common/time_test.cc b/aos/common/time_test.cc
index e1811db..94102a2 100644
--- a/aos/common/time_test.cc
+++ b/aos/common/time_test.cc
@@ -11,251 +11,9 @@
 namespace time {
 namespace testing {
 
-TEST(TimeTest, timespecConversions) {
-  timespec start{1234, 5678};  // NOLINT
-  Time time(start);
-  EXPECT_EQ(start.tv_sec, static_cast<time_t>(time.sec()));
-  EXPECT_EQ(start.tv_nsec, time.nsec());
-  timespec end = time.ToTimespec();
-  EXPECT_EQ(start.tv_sec, end.tv_sec);
-  EXPECT_EQ(start.tv_nsec, end.tv_nsec);
-}
-
-TEST(TimeTest, timevalConversions) {
-  timeval start{1234, 5678};  // NOLINT
-  Time time(start);
-  EXPECT_EQ(start.tv_sec, static_cast<long>(time.sec()));
-  EXPECT_EQ(start.tv_usec, time.nsec() / Time::kNSecInUSec);
-  timeval end = time.ToTimeval();
-  EXPECT_EQ(start.tv_sec, end.tv_sec);
-  EXPECT_EQ(start.tv_usec, end.tv_usec);
-}
-
-TEST(TimeDeathTest, ConstructorChecking) {
-  logging::Init();
-  EXPECT_DEATH(
-      {
-        logging::AddImplementation(new util::DeathTestLogImplementation());
-        Time(0, -1);
-      },
-      ".*0 <= nsec\\(-1\\) < 10+ .*");
-  EXPECT_DEATH(
-      {
-        logging::AddImplementation(new util::DeathTestLogImplementation());
-        Time(0, Time::kNSecInSec);
-      },
-      ".*0 <= nsec\\(10+\\) < 10+ .*");
-}
-
-// It's kind of hard not to test Now and SleepFor at the same time.
-TEST(TimeTest, NowAndSleepFor) {
-  // without this, it tends to fail the first time (ends up sleeping for way
-  // longer than it should the second time, where it actually matters)
-  SleepFor(Time(0, Time::kNSecInSec / 10));
-  Time start = Time::Now();
-  static constexpr Time kSleepTime = Time(0, Time::kNSecInSec * 2 / 10);
-  SleepFor(kSleepTime);
-  Time difference = Time::Now() - start;
-  EXPECT_GE(difference, kSleepTime);
-  EXPECT_LT(difference, kSleepTime + Time(0, Time::kNSecInSec / 100));
-}
-
-TEST(TimeTest, AbsoluteSleep) {
-  Time start = Time::Now();
-  SleepFor(Time(0, Time::kNSecInSec / 10));
-  static constexpr Time kSleepTime = Time(0, Time::kNSecInSec * 2 / 10);
-  SleepUntil(start + kSleepTime);
-  Time difference = Time::Now() - start;
-  EXPECT_GE(difference, kSleepTime);
-  EXPECT_LT(difference, kSleepTime + Time(0, Time::kNSecInSec / 100));
-}
-
-TEST(TimeTest, Addition) {
-  Time t(54, 500);
-  EXPECT_EQ(MACRO_DARG(Time(54, 5500)), t + MACRO_DARG(Time(0, 5000)));
-  EXPECT_EQ(MACRO_DARG(Time(56, 500)), t + MACRO_DARG(Time(2, 0)));
-  EXPECT_EQ(MACRO_DARG(Time(57, 6500)), t + MACRO_DARG(Time(3, 6000)));
-  EXPECT_EQ(MACRO_DARG(Time(50, 300)),
-            t + MACRO_DARG(Time(-5, Time::kNSecInSec - 200)));
-  EXPECT_EQ(Time(-46, 500), t + Time(-100, 0));
-  EXPECT_EQ(Time(-47, Time::kNSecInSec - 500),
-            Time(-101, Time::kNSecInSec - 1000) + t);
-}
-TEST(TimeTest, Subtraction) {
-  Time t(54, 500);
-  EXPECT_EQ(MACRO_DARG(Time(54, 300)), t - MACRO_DARG(Time(0, 200)));
-  EXPECT_EQ(MACRO_DARG(Time(42, 500)), t - MACRO_DARG(Time(12, 0)));
-  EXPECT_EQ(MACRO_DARG(Time(50, 100)), t - MACRO_DARG(Time(4, 400)));
-  EXPECT_EQ(MACRO_DARG(Time(53, 600)),
-            t - MACRO_DARG(Time(0, Time::kNSecInSec - 100)));
-  EXPECT_EQ(MACRO_DARG(Time(55, 800)),
-            t - MACRO_DARG(Time(-2, Time::kNSecInSec - 300)));
-  EXPECT_EQ(Time(54, 5500), t - Time(-1, Time::kNSecInSec - 5000));
-  EXPECT_EQ(Time(-50, Time::kNSecInSec - 300),
-            Time(5, 200) - t);
-}
-
-TEST(TimeTest, Multiplication) {
-  Time t(54, Time::kNSecInSec / 3);
-  EXPECT_EQ(MACRO_DARG(Time(108, Time::kNSecInSec / 3 * 2)), t * 2);
-  EXPECT_EQ(MACRO_DARG(Time(271, Time::kNSecInSec / 3 * 2 - 1)), t * 5);
-  EXPECT_EQ(Time(-109, Time::kNSecInSec / 3 + 1), t * -2);
-  EXPECT_EQ(Time(-55, Time::kNSecInSec / 3 * 2 + 1), t * -1);
-  EXPECT_EQ(Time(-218, Time::kNSecInSec / 3 * 2 + 2), (t * -1) * 4);
-}
-TEST(TimeTest, DivisionByInt) {
-  EXPECT_EQ(Time(5, Time::kNSecInSec / 10 * 4 + 50), Time(54, 500) / 10);
-  EXPECT_EQ(Time(2, Time::kNSecInSec / 4 * 3),
-            Time(5, Time::kNSecInSec / 2) / 2);
-  EXPECT_EQ(Time(-3, Time::kNSecInSec / 4 * 3),
-            Time(-5, Time::kNSecInSec / 2) / 2);
-}
-TEST(TimeTest, DivisionByTime) {
-  EXPECT_DOUBLE_EQ(2, Time(10, 0) / Time(5, 0));
-  EXPECT_DOUBLE_EQ(9, Time(27, 0) / Time(3, 0));
-  EXPECT_DOUBLE_EQ(9.25, Time(37, 0) / Time(4, 0));
-  EXPECT_DOUBLE_EQ(5.25, Time(36, Time::kNSecInSec / 4 * 3) / Time(7, 0));
-  EXPECT_DOUBLE_EQ(-5.25, Time(-37, Time::kNSecInSec / 4) / Time(7, 0));
-  EXPECT_DOUBLE_EQ(-5.25, Time(36, Time::kNSecInSec / 4 * 3) / Time(-7, 0));
-}
-
-TEST(TimeTest, Negation) {
-  EXPECT_EQ(Time(-5, 1234), -Time(4, Time::kNSecInSec - 1234));
-  EXPECT_EQ(Time(5, Time::kNSecInSec * 2 / 3 + 1),
-            -Time(-6, Time::kNSecInSec / 3));
-}
-
-TEST(TimeTest, Comparisons) {
-  EXPECT_TRUE(Time(971, 254) > Time(971, 253));
-  EXPECT_TRUE(Time(971, 254) >= Time(971, 253));
-  EXPECT_TRUE(Time(971, 254) < Time(971, 255));
-  EXPECT_TRUE(Time(971, 254) <= Time(971, 255));
-  EXPECT_TRUE(Time(971, 254) >= Time(971, 253));
-  EXPECT_TRUE(Time(971, 254) <= Time(971, 254));
-  EXPECT_TRUE(Time(971, 254) >= Time(971, 254));
-  EXPECT_TRUE(Time(972, 254) > Time(971, 254));
-  EXPECT_TRUE(Time(971, 254) < Time(972, 254));
-
-  EXPECT_TRUE(Time(-971, 254) > Time(-971, 253));
-  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 253));
-  EXPECT_TRUE(Time(-971, 254) < Time(-971, 255));
-  EXPECT_TRUE(Time(-971, 254) <= Time(-971, 255));
-  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 253));
-  EXPECT_TRUE(Time(-971, 254) <= Time(-971, 254));
-  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 254));
-  EXPECT_TRUE(Time(-972, 254) < Time(-971, 254));
-  EXPECT_TRUE(Time(-971, 254) > Time(-972, 254));
-}
-
-TEST(TimeTest, Within) {
-  EXPECT_TRUE(MACRO_DARG(Time(55, 5000).IsWithin(Time(55, 4900), 100)));
-  EXPECT_FALSE(MACRO_DARG(Time(55, 5000).IsWithin(Time(55, 4900), 99)));
-  EXPECT_TRUE(MACRO_DARG(Time(5, 0).IsWithin(Time(4, Time::kNSecInSec - 200),
-                                             250)));
-  EXPECT_TRUE(Time(-5, Time::kNSecInSec - 200).IsWithin(Time(-4, 0), 250));
-  EXPECT_TRUE(Time(-5, 200).IsWithin(Time(-5, 0), 250));
-}
-
-TEST(TimeTest, Modulus) {
-  EXPECT_EQ(MACRO_DARG(Time(0, Time::kNSecInSec / 10 * 2)),
-            MACRO_DARG(Time(50, 0) % (Time::kNSecInSec / 10 * 3)));
-  EXPECT_EQ(Time(-1, Time::kNSecInSec / 10 * 8),
-            Time(-50, 0) % (Time::kNSecInSec / 10 * 3));
-  EXPECT_EQ(Time(-1, Time::kNSecInSec / 10 * 8),
-            Time(-50, 0) % (-Time::kNSecInSec / 10 * 3));
-  EXPECT_EQ(Time(0, Time::kNSecInSec / 10 * 2),
-            Time(50, 0) % (-Time::kNSecInSec / 10 * 3));
-  EXPECT_EQ(Time(1, Time::kNSecInSec / 10),
-            Time(60, Time::kNSecInSec / 10) % (Time::kNSecInSec / 10 * 12));
-}
-
-TEST(TimeTest, InSeconds) {
-  EXPECT_EQ(MACRO_DARG(Time(2, Time::kNSecInSec / 100 * 55 - 1)),
-            Time::InSeconds(2.55));
-  EXPECT_EQ(MACRO_DARG(Time(-3, Time::kNSecInSec / 100 * 45)),
-            Time::InSeconds(-2.55));
-}
-
-TEST(TimeTest, ToSeconds) {
-  EXPECT_DOUBLE_EQ(13.23, Time::InSeconds(13.23).ToSeconds());
-  EXPECT_NEAR(-13.23, Time::InSeconds(-13.23).ToSeconds(),
-              1.0 / Time::kNSecInSec * 2);
-}
-
-TEST(TimeTest, InMS) {
-  Time t = Time::InMS(254971);
-  EXPECT_EQ(254, t.sec());
-  EXPECT_EQ(971000000, t.nsec());
-
-  Time t2 = Time::InMS(-254971);
-  EXPECT_EQ(-255, t2.sec());
-  EXPECT_EQ(Time::kNSecInSec - 971000000, t2.nsec());
-
-  Time t3 = Time::InMS(-1000);
-  EXPECT_EQ(-1, t3.sec());
-  EXPECT_EQ(0, t3.nsec());
-
-  Time t4 = Time::InMS(1000);
-  EXPECT_EQ(1, t4.sec());
-  EXPECT_EQ(0, t4.nsec());
-
-  Time t5 = Time::InMS(1001);
-  EXPECT_EQ(1, t5.sec());
-  EXPECT_EQ(Time::kNSecInMSec, t5.nsec());
-
-  Time t6 = Time::InMS(-1001);
-  EXPECT_EQ(-2, t6.sec());
-  EXPECT_EQ(Time::kNSecInSec - Time::kNSecInMSec, t6.nsec());
-
-  Time t7 = Time::InMS(-999);
-  EXPECT_EQ(-1, t7.sec());
-  EXPECT_EQ(Time::kNSecInMSec, t7.nsec());
-
-  Time t8 = Time::InMS(999);
-  EXPECT_EQ(0, t8.sec());
-  EXPECT_EQ(Time::kNSecInSec - Time::kNSecInMSec, t8.nsec());
-}
-
-TEST(TimeTest, ToMSec) {
-  EXPECT_EQ(254971, Time(254, 971000000).ToMSec());
-  EXPECT_EQ(-254971, Time(-255, Time::kNSecInSec - 971000000).ToMSec());
-}
-
-TEST(TimeTest, InNS) {
-  Time t = Time::InNS(static_cast<int64_t>(973254111971ll));
-  EXPECT_EQ(973, t.sec());
-  EXPECT_EQ(254111971, t.nsec());
-
-  Time t2 = Time::InNS(static_cast<int64_t>(-973254111971ll));
-  EXPECT_EQ(-974, t2.sec());
-  EXPECT_EQ(Time::kNSecInSec - 254111971, t2.nsec());
-}
-
-TEST(TimeTest, InUS) {
-  Time t = Time::InUS(254111971);
-  EXPECT_EQ(254, t.sec());
-  EXPECT_EQ(111971000, t.nsec());
-
-  Time t2 = Time::InUS(-254111971);
-  EXPECT_EQ(-255, t2.sec());
-  EXPECT_EQ(Time::kNSecInSec - 111971000, t2.nsec());
-}
-
-TEST(TimeTest, ToUSec) {
-  EXPECT_EQ(254000971, Time(254, 971000).ToUSec());
-  EXPECT_EQ(-254000971, Time(-255, Time::kNSecInSec - 971000).ToUSec());
-}
-
-TEST(TimeTest, Abs) {
-  EXPECT_EQ(MACRO_DARG(Time(971, 1114)), MACRO_DARG(Time(971, 1114).abs()));
-  EXPECT_EQ(MACRO_DARG(Time(253, Time::kNSecInSec * 0.3)),
-            MACRO_DARG(Time(-254, Time::kNSecInSec * 0.7).abs()));
-  EXPECT_EQ(MACRO_DARG(-Time(-971, 973).ToNSec()),
-            MACRO_DARG(Time(970, Time::kNSecInSec - 973).ToNSec()));
-}
 
 TEST(TimeTest, FromRate) {
-  EXPECT_EQ(::std::chrono::milliseconds(10), Time::FromRate(100));
+  EXPECT_EQ(::std::chrono::milliseconds(10), FromRate(100));
 }
 
 // Test the monotonic_clock and sleep_until functions.
diff --git a/aos/common/util/log_interval.h b/aos/common/util/log_interval.h
index 3a7a85f..8823341 100644
--- a/aos/common/util/log_interval.h
+++ b/aos/common/util/log_interval.h
@@ -12,7 +12,7 @@
 // A class to help with logging things that happen a lot only occasionally.
 //
 // Intended use {
-//   static LogInterval interval(::aos::time::Time::InSeconds(0.2));
+//   static LogInterval interval(::std::chrono::millseconds(200));
 //
 //   if (WantToLog()) {
 //     interval.WantToLog();
diff --git a/aos/common/util/phased_loop.cc b/aos/common/util/phased_loop.cc
index 9c81ffb..bea262d 100644
--- a/aos/common/util/phased_loop.cc
+++ b/aos/common/util/phased_loop.cc
@@ -3,13 +3,6 @@
 namespace aos {
 namespace time {
 
-void PhasedLoopXMS(int ms, int offset) {
-  const Time frequency = Time::InMS(ms);
-  SleepUntil((Time::Now() / static_cast<int32_t>(frequency.ToNSec())) *
-             static_cast<int32_t>(frequency.ToNSec()) +
-             frequency + Time::InUS(offset));
-}
-
 int PhasedLoop::Iterate(const monotonic_clock::time_point now) {
   const monotonic_clock::time_point next_time =
       monotonic_clock::time_point(
diff --git a/aos/common/util/phased_loop.h b/aos/common/util/phased_loop.h
index 7614ed2..fbfe954 100644
--- a/aos/common/util/phased_loop.h
+++ b/aos/common/util/phased_loop.h
@@ -8,11 +8,6 @@
 namespace aos {
 namespace time {
 
-// Will not be accurate if ms isn't a factor of 1000.
-// offset is in us.
-// DEPRECATED(Brian): Use PhasedLoop instead.
-void PhasedLoopXMS(int ms, int offset);
-
 // Handles sleeping until a fixed offset from some time interval.
 class PhasedLoop {
  public:
@@ -21,7 +16,7 @@
   //   1.1s
   //   ...
   //   10000.1s
-  // offset must be >= Time::kZero and < interval.
+  // offset must be >= chrono::seconds(0) and < interval.
   PhasedLoop(
       const monotonic_clock::duration interval,
       const monotonic_clock::duration offset = monotonic_clock::duration(0))