2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "utils/XTimeUtils.h"
15 #include <sys/times.h>
17 #if defined(TARGET_ANDROID) && !defined(__LP64__)
21 #define WIN32_TIME_OFFSET ((unsigned long long)(369 * 365 + 89) * 24 * 3600 * 10000000)
29 * A Leap year is any year that is divisible by four, but not by 100 unless also
32 #define IsLeapYear(y) ((!(y % 4)) ? (((!(y % 400)) && (y % 100)) ? 1 : 0) : 0)
34 uint32_t GetTimeZoneInformation(TimeZoneInformation
* timeZoneInformation
)
36 if (!timeZoneInformation
)
37 return KODI_TIME_ZONE_ID_INVALID
;
40 time_t tt
= time(NULL
);
41 if (localtime_r(&tt
, &t
))
42 timeZoneInformation
->bias
= -t
.tm_gmtoff
/ 60;
44 timeZoneInformation
->standardName
= tzname
[0];
45 timeZoneInformation
->daylightName
= tzname
[1];
47 return KODI_TIME_ZONE_ID_UNKNOWN
;
50 void GetLocalTime(SystemTime
* systemTime
)
52 const time_t t
= time(NULL
);
55 localtime_r(&t
, &now
);
56 systemTime
->year
= now
.tm_year
+ 1900;
57 systemTime
->month
= now
.tm_mon
+ 1;
58 systemTime
->dayOfWeek
= now
.tm_wday
;
59 systemTime
->day
= now
.tm_mday
;
60 systemTime
->hour
= now
.tm_hour
;
61 systemTime
->minute
= now
.tm_min
;
62 systemTime
->second
= now
.tm_sec
;
63 systemTime
->milliseconds
= 0;
66 int FileTimeToLocalFileTime(const FileTime
* fileTime
, FileTime
* localFileTime
)
69 l
.u
.LowPart
= fileTime
->lowDateTime
;
70 l
.u
.HighPart
= fileTime
->highDateTime
;
74 FileTimeToTimeT(fileTime
, &ft
);
75 localtime_r(&ft
, &tm_ft
);
77 l
.QuadPart
+= static_cast<unsigned long long>(tm_ft
.tm_gmtoff
) * 10000000;
79 localFileTime
->lowDateTime
= l
.u
.LowPart
;
80 localFileTime
->highDateTime
= l
.u
.HighPart
;
84 int SystemTimeToFileTime(const SystemTime
* systemTime
, FileTime
* fileTime
)
86 static const int dayoffset
[12] = {0, 31, 59, 90, 120, 151, 182, 212, 243, 273, 304, 334};
87 #if defined(TARGET_DARWIN)
88 static std::mutex timegm_lock
;
91 struct tm sysTime
= {};
92 sysTime
.tm_year
= systemTime
->year
- 1900;
93 sysTime
.tm_mon
= systemTime
->month
- 1;
94 sysTime
.tm_wday
= systemTime
->dayOfWeek
;
95 sysTime
.tm_mday
= systemTime
->day
;
96 sysTime
.tm_hour
= systemTime
->hour
;
97 sysTime
.tm_min
= systemTime
->minute
;
98 sysTime
.tm_sec
= systemTime
->second
;
99 sysTime
.tm_yday
= dayoffset
[sysTime
.tm_mon
] + (sysTime
.tm_mday
- 1);
101 // If this is a leap year, and we're past the 28th of Feb, increment tm_yday.
102 if (IsLeapYear(systemTime
->year
) && (sysTime
.tm_yday
> 58))
105 #if defined(TARGET_DARWIN)
106 std::lock_guard
<std::mutex
> lock(timegm_lock
);
109 #if defined(TARGET_ANDROID) && !defined(__LP64__)
110 time64_t t
= timegm64(&sysTime
);
112 time_t t
= timegm(&sysTime
);
115 LARGE_INTEGER result
;
116 result
.QuadPart
= (long long)t
* 10000000 + (long long)systemTime
->milliseconds
* 10000;
117 result
.QuadPart
+= WIN32_TIME_OFFSET
;
119 fileTime
->lowDateTime
= result
.u
.LowPart
;
120 fileTime
->highDateTime
= result
.u
.HighPart
;
125 long CompareFileTime(const FileTime
* fileTime1
, const FileTime
* fileTime2
)
128 t1
.u
.LowPart
= fileTime1
->lowDateTime
;
129 t1
.u
.HighPart
= fileTime1
->highDateTime
;
132 t2
.u
.LowPart
= fileTime2
->lowDateTime
;
133 t2
.u
.HighPart
= fileTime2
->highDateTime
;
135 if (t1
.QuadPart
== t2
.QuadPart
)
137 else if (t1
.QuadPart
< t2
.QuadPart
)
143 int FileTimeToSystemTime(const FileTime
* fileTime
, SystemTime
* systemTime
)
146 file
.u
.LowPart
= fileTime
->lowDateTime
;
147 file
.u
.HighPart
= fileTime
->highDateTime
;
149 file
.QuadPart
-= WIN32_TIME_OFFSET
;
150 file
.QuadPart
/= 10000; /* to milliseconds */
151 systemTime
->milliseconds
= file
.QuadPart
% 1000;
152 file
.QuadPart
/= 1000; /* to seconds */
154 time_t ft
= file
.QuadPart
;
157 gmtime_r(&ft
, &tm_ft
);
159 systemTime
->year
= tm_ft
.tm_year
+ 1900;
160 systemTime
->month
= tm_ft
.tm_mon
+ 1;
161 systemTime
->dayOfWeek
= tm_ft
.tm_wday
;
162 systemTime
->day
= tm_ft
.tm_mday
;
163 systemTime
->hour
= tm_ft
.tm_hour
;
164 systemTime
->minute
= tm_ft
.tm_min
;
165 systemTime
->second
= tm_ft
.tm_sec
;
170 int LocalFileTimeToFileTime(const FileTime
* localFileTime
, FileTime
* fileTime
)
173 l
.u
.LowPart
= localFileTime
->lowDateTime
;
174 l
.u
.HighPart
= localFileTime
->highDateTime
;
176 l
.QuadPart
+= (unsigned long long) timezone
* 10000000;
178 fileTime
->lowDateTime
= l
.u
.LowPart
;
179 fileTime
->highDateTime
= l
.u
.HighPart
;
185 int FileTimeToTimeT(const FileTime
* localFileTime
, time_t* pTimeT
)
187 if (!localFileTime
|| !pTimeT
)
190 ULARGE_INTEGER fileTime
;
191 fileTime
.u
.LowPart
= localFileTime
->lowDateTime
;
192 fileTime
.u
.HighPart
= localFileTime
->highDateTime
;
194 fileTime
.QuadPart
-= WIN32_TIME_OFFSET
;
195 fileTime
.QuadPart
/= 10000; /* to milliseconds */
196 fileTime
.QuadPart
/= 1000; /* to seconds */
198 time_t ft
= fileTime
.QuadPart
;
201 localtime_r(&ft
, &tm_ft
);
203 *pTimeT
= mktime(&tm_ft
);
207 int TimeTToFileTime(time_t timeT
, FileTime
* localFileTime
)
212 ULARGE_INTEGER result
;
213 result
.QuadPart
= (unsigned long long) timeT
* 10000000;
214 result
.QuadPart
+= WIN32_TIME_OFFSET
;
216 localFileTime
->lowDateTime
= result
.u
.LowPart
;
217 localFileTime
->highDateTime
= result
.u
.HighPart
;