1 /* The following methods were adapted from musl.
2 * See musl/COPYRIGHT for license information. */
3
4 #include <errno.h>
5
6 #include "../musl/time/time_impl.h"
7
8
9 static long __timezone = 0;
10 static int dst_off = 0;
11 const char __utc[] = "UTC";
12 static const char *__tzname[2] = { __utc, __utc };
13
14
15 static void
__secs_to_zone(long long t,int local,int * isdst,int * offset,long * oppoff,const char ** zonename)16 __secs_to_zone(long long t, int local, int *isdst, int *offset, long *oppoff, const char **zonename)
17 {
18 *isdst = 0;
19 *offset = -__timezone;
20 if (oppoff) *oppoff = -dst_off;
21 *zonename = __tzname[0];
22 }
23
24
25 struct tm *
__gmtime_r_fallback(const time_t * restrict t,struct tm * restrict tm)26 __gmtime_r_fallback(const time_t *restrict t, struct tm *restrict tm)
27 {
28 if (__secs_to_tm(*t, tm) < 0) {
29 errno = EOVERFLOW;
30 return 0;
31 }
32 tm->tm_isdst = 0;
33 tm->__tm_gmtoff = 0;
34 tm->__tm_zone = __utc;
35 return tm;
36 }
37
38
39 time_t
__mktime_fallback(struct tm * tm)40 __mktime_fallback(struct tm *tm)
41 {
42 struct tm new;
43 long opp;
44 long long t = __tm_to_secs(tm);
45
46 __secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
47
48 if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
49 t -= opp - new.__tm_gmtoff;
50
51 t -= new.__tm_gmtoff;
52 if ((time_t)t != t) goto error;
53
54 __secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
55
56 if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
57
58 *tm = new;
59 return t;
60
61 error:
62 errno = EOVERFLOW;
63 return -1;
64 }
65
66
67 time_t
__timegm_fallback(struct tm * tm)68 __timegm_fallback(struct tm *tm)
69 {
70 struct tm new;
71 long long t = __tm_to_secs(tm);
72 if (__secs_to_tm(t, &new) < 0) {
73 errno = EOVERFLOW;
74 return -1;
75 }
76 *tm = new;
77 tm->tm_isdst = 0;
78 tm->__tm_gmtoff = 0;
79 tm->__tm_zone = __utc;
80 return t;
81 }
82