15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreFoundation/CFDate.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreFoundation/CFTimeZone.h>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <mach/mach.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mach/mach_time.h>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/sysctl.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h>
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_cftyperef.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/mac/scoped_mach_port.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint64_t ComputeCurrentTicks() {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_IOS)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On iOS mach_absolute_time stops while the device is sleeping. Instead use
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // changes. KERN_BOOTTIME will be updated by the system whenever the system
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clock change.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct timeval boottime;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int mib[2] = {CTL_KERN, KERN_BOOTTIME};
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = sizeof(boottime);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int kr = sysctl(mib, arraysize(mib), &boottime, &size, NULL, 0);
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(KERN_SUCCESS, kr);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta time_difference = base::Time::Now() -
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (base::Time::FromTimeT(boottime.tv_sec) +
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       base::TimeDelta::FromMicroseconds(boottime.tv_usec));
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return time_difference.InMicroseconds();
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64_t absolute_micro;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static mach_timebase_info_data_t timebase_info;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (timebase_info.denom == 0) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Zero-initialization of statics guarantees that denom will be 0 before
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // calling mach_timebase_info.  mach_timebase_info will never set denom to
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // 0 as that would be invalid, so the zero-check can be used to determine
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // whether mach_timebase_info has already been called.  This is
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // recommended by Apple's QA1398.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kern_return_t kr = mach_timebase_info(&timebase_info);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(KERN_SUCCESS, kr);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mach_absolute_time is it when it comes to ticks on the Mac.  Other calls
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // with less precision (such as TickCount) just call through to
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mach_absolute_time.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timebase_info converts absolute time tick units into nanoseconds.  Convert
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to microseconds up front to stave off overflows.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  absolute_micro =
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mach_absolute_time() / base::Time::kNanosecondsPerMicrosecond *
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      timebase_info.numer / timebase_info.denom;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't bother with the rollover handling that the Windows version does.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With numer and denom = 1 (the expected case), the 64-bit absolute time
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // reported in nanoseconds is enough to last nearly 585 years.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return absolute_micro;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(OS_IOS)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)uint64_t ComputeThreadTicks() {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_IOS)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED();
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return 0;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::mac::ScopedMachPort thread(mach_thread_self());
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  mach_msg_type_number_t thread_info_count = THREAD_BASIC_INFO_COUNT;
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  thread_basic_info_data_t thread_info_data;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (thread == MACH_PORT_NULL) {
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DLOG(ERROR) << "Failed to get mach_thread_self()";
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  kern_return_t kr = thread_info(
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      thread,
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      THREAD_BASIC_INFO,
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reinterpret_cast<thread_info_t>(&thread_info_data),
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &thread_info_count);
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(KERN_SUCCESS, kr);
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (thread_info_data.user_time.seconds *
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              base::Time::kMicrosecondsPerSecond) +
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         thread_info_data.user_time.microseconds;
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // defined(OS_IOS)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Time routines in this file use Mach and CoreFoundation APIs, since the
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// POSIX definition of time_t in Mac OS X wraps around after 2038--and
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there are already cookie expiration dates, etc., past that time out in
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the field.  Using CFDate prevents that problem, and using mach_absolute_time
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for TimeTicks gives us nice high-resolution interval timing.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time -----------------------------------------------------------------------
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Core Foundation uses a double second count since 2001-01-01 00:00:00 UTC.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The UNIX epoch is 1970-01-01 00:00:00 UTC.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows uses a Gregorian epoch of 1601.  We need to match this internally
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// so that our time representations match across all platforms.  See bug 14734.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   irb(main):010:0> Time.at(0).getutc()
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   => Thu Jan 01 00:00:00 UTC 1970
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   irb(main):011:0> Time.at(-11644473600).getutc()
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   => Mon Jan 01 00:00:00 UTC 1601
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int64 kWindowsEpochDeltaSeconds = GG_INT64_C(11644473600);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 Time::kWindowsEpochDeltaMicroseconds =
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some functions in time.cc use time_t directly, so we provide an offset
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to convert from time_t (Unix epoch) and internal (Windows epoch).
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::Now() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FromCFAbsoluteTime(CFAbsoluteTimeGetCurrent());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromCFAbsoluteTime(CFAbsoluteTime t) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (t == 0)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Time();  // Consider 0 as a null Time.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (t == std::numeric_limits<CFAbsoluteTime>::max())
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Max();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Time(static_cast<int64>(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (t + kCFAbsoluteTimeIntervalSince1970) * kMicrosecondsPerSecond) +
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kWindowsEpochDeltaMicroseconds);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFAbsoluteTime Time::ToCFAbsoluteTime() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_null())
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;  // Consider 0 as a null Time.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_max())
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::numeric_limits<CFAbsoluteTime>::max();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (static_cast<CFAbsoluteTime>(us_ - kWindowsEpochDeltaMicroseconds) /
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMicrosecondsPerSecond) - kCFAbsoluteTimeIntervalSince1970;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::NowFromSystemTime() {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just use Now() because Now() returns the system time.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Now();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromExploded(bool is_local, const Exploded& exploded) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFGregorianDate date;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.second = exploded.second +
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exploded.millisecond / static_cast<double>(kMillisecondsPerSecond);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.minute = exploded.minute;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.hour = exploded.hour;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.day = exploded.day_of_month;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.month = exploded.month;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  date.year = exploded.year;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_local ? CFTimeZoneCopySystem() : NULL);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFAbsoluteTime seconds = CFGregorianDateGetAbsoluteTime(date, time_zone) +
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kCFAbsoluteTimeIntervalSince1970;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Time(static_cast<int64>(seconds * kMicrosecondsPerSecond) +
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kWindowsEpochDeltaMicroseconds);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Time::Explode(bool is_local, Exploded* exploded) const {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid rounding issues, by only putting the integral number of seconds
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (rounded towards -infinity) into a |CFAbsoluteTime| (which is a |double|).
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 microsecond = us_ % kMicrosecondsPerSecond;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (microsecond < 0)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    microsecond += kMicrosecondsPerSecond;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFAbsoluteTime seconds = ((us_ - microsecond) / kMicrosecondsPerSecond) -
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kWindowsEpochDeltaSeconds -
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kCFAbsoluteTimeIntervalSince1970;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_local ? CFTimeZoneCopySystem() : NULL);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(seconds, time_zone);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 = Monday, ..., 7 = Sunday.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int cf_day_of_week = CFAbsoluteTimeGetDayOfWeek(seconds, time_zone);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->year = date.year;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->month = date.month;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->day_of_week = cf_day_of_week % 7;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->day_of_month = date.day;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->hour = date.hour;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->minute = date.minute;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure seconds are rounded down towards -infinity.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->second = floor(date.second);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate milliseconds ourselves, since we rounded the |seconds|, making
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure to round towards -infinity.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->millisecond =
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (microsecond >= 0) ? microsecond / kMicrosecondsPerMillisecond :
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (microsecond - kMicrosecondsPerMillisecond + 1) /
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               kMicrosecondsPerMillisecond;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeTicks ------------------------------------------------------------------
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::Now() {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return TimeTicks(ComputeCurrentTicks());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::HighResNow() {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Now();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TimeTicks::IsHighResNowFastAndReliable() {
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TimeTicks TimeTicks::ThreadNow() {
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return TimeTicks(ComputeThreadTicks());
229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::NowFromSystemTraceTime() {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return HighResNow();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
237