Commit | Line | Data |
---|---|---|
a386e246 SKC |
1 | #ifndef _BABELTRACE_UTC_H |
2 | #define _BABELTRACE_UTC_H | |
3 | ||
4 | /* | |
5 | * Copyright (C) 2011-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
6 | * | |
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | * of this software and associated documentation files (the "Software"), to deal | |
9 | * in the Software without restriction, including without limitation the rights | |
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | * copies of the Software, and to permit persons to whom the Software is | |
12 | * furnished to do so, subject to the following conditions: | |
13 | * | |
14 | * The above copyright notice and this permission notice shall be included in | |
15 | * all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 | * SOFTWARE. | |
24 | */ | |
25 | ||
26 | #include <time.h> | |
27 | ||
28 | /* If set, use GNU or BSD timegm(3) */ | |
29 | #if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) | |
30 | ||
31 | static inline | |
03f61dea | 32 | time_t bt_timegm(struct tm *tm) |
a386e246 SKC |
33 | { |
34 | return timegm(tm); | |
35 | } | |
36 | ||
3d2f08e7 MJ |
37 | #elif defined(__MINGW32__) |
38 | ||
39 | static inline | |
40 | time_t bt_timegm(struct tm *tm) | |
41 | { | |
42 | return _mkgmtime(tm); | |
43 | } | |
44 | ||
a386e246 SKC |
45 | #else |
46 | ||
bcd785aa | 47 | #include <errno.h> |
a386e246 SKC |
48 | |
49 | /* | |
bcd785aa MJ |
50 | * This is a simple implementation of timegm() it just turns the "struct tm" into |
51 | * a GMT time_t. It does not normalize any of the fields of the "struct tm", nor | |
52 | * does it set tm_wday or tm_yday. | |
a386e246 SKC |
53 | */ |
54 | ||
bcd785aa MJ |
55 | static inline |
56 | int bt_leapyear(int year) | |
57 | { | |
58 | return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); | |
59 | } | |
60 | ||
a386e246 | 61 | static inline |
03f61dea | 62 | time_t bt_timegm(struct tm *tm) |
a386e246 | 63 | { |
bcd785aa MJ |
64 | int year, month, total_days; |
65 | ||
66 | int monthlen[2][12] = { | |
67 | /* Days per month for a regular year */ | |
68 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, | |
69 | /* Days per month for a leap year */ | |
70 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, | |
71 | }; | |
72 | ||
73 | if ((tm->tm_mon >= 12) || | |
74 | (tm->tm_mday >= 32) || | |
75 | (tm->tm_hour >= 24) || | |
76 | (tm->tm_min >= 60) || | |
77 | (tm->tm_sec >= 61)) { | |
78 | errno = EOVERFLOW; | |
79 | return (time_t) -1; | |
80 | } | |
81 | ||
82 | /* Add 365 days for each year since 1970 */ | |
83 | total_days = 365 * (tm->tm_year - 70); | |
84 | ||
85 | /* Add one day for each leap year since 1970 */ | |
86 | for (year = 70; year < tm->tm_year; year++) { | |
87 | if (bt_leapyear(1900 + year)) { | |
88 | total_days++; | |
a386e246 SKC |
89 | } |
90 | } | |
91 | ||
bcd785aa MJ |
92 | /* Add days for each remaining month */ |
93 | for (month = 0; month < tm->tm_mon; month++) { | |
94 | total_days += monthlen[bt_leapyear(1900 + year)][month]; | |
a386e246 | 95 | } |
bcd785aa MJ |
96 | |
97 | /* Add remaining days */ | |
98 | total_days += tm->tm_mday - 1; | |
99 | ||
100 | return ((((total_days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec); | |
a386e246 SKC |
101 | } |
102 | ||
103 | #endif | |
104 | ||
105 | #endif /* _BABELTRACE_UTC_H */ |