Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkOncePtr.h"
      9 #include "SkString.h"
     10 #include "SkTime.h"
     11 #include "SkTypes.h"
     12 
     13 void SkTime::DateTime::toISO8601(SkString* dst) const {
     14     if (dst) {
     15         int timeZoneMinutes = SkToInt(fTimeZoneMinutes);
     16         char timezoneSign = timeZoneMinutes >= 0 ? '+' : '-';
     17         int timeZoneHours = SkTAbs(timeZoneMinutes) / 60;
     18         timeZoneMinutes = SkTAbs(timeZoneMinutes) % 60;
     19         dst->printf("%04u-%02u-%02uT%02u:%02u:%02u%c%02d:%02d",
     20                     static_cast<unsigned>(fYear), static_cast<unsigned>(fMonth),
     21                     static_cast<unsigned>(fDay), static_cast<unsigned>(fHour),
     22                     static_cast<unsigned>(fMinute),
     23                     static_cast<unsigned>(fSecond), timezoneSign, timeZoneHours,
     24                     timeZoneMinutes);
     25     }
     26 }
     27 
     28 
     29 #ifdef SK_BUILD_FOR_WIN32
     30 
     31 #include "Windows.h"
     32 void SkTime::GetDateTime(DateTime* dt) {
     33     if (dt) {
     34         SYSTEMTIME st;
     35         GetSystemTime(&st);
     36         dt->fTimeZoneMinutes = 0;
     37         dt->fYear       = st.wYear;
     38         dt->fMonth      = SkToU8(st.wMonth);
     39         dt->fDayOfWeek  = SkToU8(st.wDayOfWeek);
     40         dt->fDay        = SkToU8(st.wDay);
     41         dt->fHour       = SkToU8(st.wHour);
     42         dt->fMinute     = SkToU8(st.wMinute);
     43         dt->fSecond     = SkToU8(st.wSecond);
     44     }
     45 }
     46 
     47 #else // SK_BUILD_FOR_WIN32
     48 
     49 #include <time.h>
     50 void SkTime::GetDateTime(DateTime* dt) {
     51     if (dt) {
     52         time_t m_time;
     53         time(&m_time);
     54         struct tm* tstruct;
     55         tstruct = gmtime(&m_time);
     56         dt->fTimeZoneMinutes = 0;
     57         dt->fYear       = tstruct->tm_year + 1900;
     58         dt->fMonth      = SkToU8(tstruct->tm_mon + 1);
     59         dt->fDayOfWeek  = SkToU8(tstruct->tm_wday);
     60         dt->fDay        = SkToU8(tstruct->tm_mday);
     61         dt->fHour       = SkToU8(tstruct->tm_hour);
     62         dt->fMinute     = SkToU8(tstruct->tm_min);
     63         dt->fSecond     = SkToU8(tstruct->tm_sec);
     64     }
     65 }
     66 #endif // SK_BUILD_FOR_WIN32
     67 
     68 #if defined(_MSC_VER)
     69     // TODO: try std::chrono again with MSVC 2015?
     70     #include <intrin.h>
     71     SK_DECLARE_STATIC_ONCE_PTR(double, ns_per_tick);
     72     double SkTime::GetNSecs() {
     73         uint64_t ticks = __rdtsc();
     74         return ticks * *ns_per_tick.get([]{
     75             LARGE_INTEGER khz;  // The docs say this returns Hz, but it returns KHz.
     76             QueryPerformanceFrequency(&khz);
     77             return new double(1e6 / khz.QuadPart);
     78         });
     79     }
     80 #elif defined(__MACH__)
     81     // TODO: fold into std::chrono when available?
     82     #include <mach/mach_time.h>
     83     SK_DECLARE_STATIC_ONCE_PTR(double, ns_per_tick);
     84     double SkTime::GetNSecs() {
     85         uint64_t ticks = mach_absolute_time();
     86         return ticks * *ns_per_tick.get([]{
     87             mach_timebase_info_data_t timebase;
     88             (void)mach_timebase_info(&timebase);
     89             return new double(timebase.numer * 1.0 / timebase.denom);
     90         });
     91     }
     92 #else
     93     // This std::chrono code looks great on Linux and Android,
     94     // but MSVC 2013 returned mostly garbage (0ns times, etc).
     95     #include <chrono>
     96     double SkTime::GetNSecs() {
     97         auto now = std::chrono::high_resolution_clock::now();
     98         std::chrono::duration<double, std::nano> ns = now.time_since_epoch();
     99         return ns.count();
    100     }
    101 #endif
    102