1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "libcef/common/time_util.h"
6
7 #include <tuple>
8
9 #if BUILDFLAG(IS_WIN)
10 #include <limits>
11
12 namespace {
13
14 // From MSDN, FILETIME "Contains a 64-bit value representing the number of
15 // 100-nanosecond intervals since January 1, 1601 (UTC)." This value must
16 // be less than 0x8000000000000000. Otherwise, the function
17 // FileTimeToSystemTime fails.
18 // From base/time/time_win.cc:
CanConvertToFileTime(int64_t us)19 bool CanConvertToFileTime(int64_t us) {
20 return us >= 0 && us <= (std::numeric_limits<int64_t>::max() / 10);
21 }
22
23 } // namespace
24 #endif // BUILDFLAG(IS_WIN)
25
cef_time_to_basetime(const cef_time_t & cef_time,base::Time & time)26 void cef_time_to_basetime(const cef_time_t& cef_time, base::Time& time) {
27 base::Time::Exploded exploded;
28 exploded.year = cef_time.year;
29 exploded.month = cef_time.month;
30 exploded.day_of_week = cef_time.day_of_week;
31 exploded.day_of_month = cef_time.day_of_month;
32 exploded.hour = cef_time.hour;
33 exploded.minute = cef_time.minute;
34 exploded.second = cef_time.second;
35 exploded.millisecond = cef_time.millisecond;
36 std::ignore = base::Time::FromUTCExploded(exploded, &time);
37 }
38
cef_time_from_basetime(const base::Time & time,cef_time_t & cef_time)39 void cef_time_from_basetime(const base::Time& time, cef_time_t& cef_time) {
40 #if BUILDFLAG(IS_WIN)
41 int64_t t = time.ToDeltaSinceWindowsEpoch().InMicroseconds();
42 if (!CanConvertToFileTime(t))
43 return;
44 #endif
45
46 base::Time::Exploded exploded;
47 time.UTCExplode(&exploded);
48 cef_time.year = exploded.year;
49 cef_time.month = exploded.month;
50 cef_time.day_of_week = exploded.day_of_week;
51 cef_time.day_of_month = exploded.day_of_month;
52 cef_time.hour = exploded.hour;
53 cef_time.minute = exploded.minute;
54 cef_time.second = exploded.second;
55 cef_time.millisecond = exploded.millisecond;
56 }
57
cef_time_to_timet(const cef_time_t * cef_time,time_t * time)58 CEF_EXPORT int cef_time_to_timet(const cef_time_t* cef_time, time_t* time) {
59 if (!cef_time || !time)
60 return 0;
61
62 base::Time base_time;
63 cef_time_to_basetime(*cef_time, base_time);
64 *time = base_time.ToTimeT();
65 return 1;
66 }
67
cef_time_from_timet(time_t time,cef_time_t * cef_time)68 CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time) {
69 if (!cef_time)
70 return 0;
71
72 base::Time base_time = base::Time::FromTimeT(time);
73 cef_time_from_basetime(base_time, *cef_time);
74 return 1;
75 }
76
cef_time_to_doublet(const cef_time_t * cef_time,double * time)77 CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time) {
78 if (!cef_time || !time)
79 return 0;
80
81 base::Time base_time;
82 cef_time_to_basetime(*cef_time, base_time);
83 *time = base_time.ToDoubleT();
84 return 1;
85 }
86
cef_time_from_doublet(double time,cef_time_t * cef_time)87 CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time) {
88 if (!cef_time)
89 return 0;
90
91 base::Time base_time = base::Time::FromDoubleT(time);
92 cef_time_from_basetime(base_time, *cef_time);
93 return 1;
94 }
95
cef_time_now(cef_time_t * cef_time)96 CEF_EXPORT int cef_time_now(cef_time_t* cef_time) {
97 if (!cef_time)
98 return 0;
99
100 base::Time base_time = base::Time::Now();
101 cef_time_from_basetime(base_time, *cef_time);
102 return 1;
103 }
104
cef_time_delta(const cef_time_t * cef_time1,const cef_time_t * cef_time2,long long * delta)105 CEF_EXPORT int cef_time_delta(const cef_time_t* cef_time1,
106 const cef_time_t* cef_time2,
107 long long* delta) {
108 if (!cef_time1 || !cef_time2 || !delta)
109 return 0;
110
111 base::Time base_time1, base_time2;
112 cef_time_to_basetime(*cef_time1, base_time1);
113 cef_time_to_basetime(*cef_time2, base_time2);
114
115 base::TimeDelta time_delta = base_time2 - base_time1;
116 *delta = time_delta.InMilliseconds();
117 return 1;
118 }
119