µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
timegm.c File Reference
#include <time.h>
#include <stdlib.h>

Go to the source code of this file.

Macros

#define _DAYS_IN_MONTH(x)   ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
 
#define _DAYS_IN_YEAR(year)   (_ISLEAP (year) ? 366 : 365)
 
#define _ISLEAP(y)    (((y) % 4) == 0 && (((y) % 100) != 0 || (((y) + 1900) % 400) == 0))
 
#define _SEC_IN_DAY   86400L
 
#define _SEC_IN_HOUR   3600L
 
#define _SEC_IN_MINUTE   60L
 

Functions

time_t timegm (struct tm *tim_p)
 
static void validate_structure (struct tm *tim_p)
 

Variables

static const int _DAYS_BEFORE_MONTH [12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }
 
static const int DAYS_IN_MONTH [12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
 

Macro Definition Documentation

◆ _DAYS_IN_MONTH

#define _DAYS_IN_MONTH (   x)    ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])

Definition at line 41 of file timegm.c.

◆ _DAYS_IN_YEAR

#define _DAYS_IN_YEAR (   year)    (_ISLEAP (year) ? 366 : 365)

Definition at line 54 of file timegm.c.

◆ _ISLEAP

#define _ISLEAP (   y)     (((y) % 4) == 0 && (((y) % 100) != 0 || (((y) + 1900) % 400) == 0))

Definition at line 52 of file timegm.c.

◆ _SEC_IN_DAY

#define _SEC_IN_DAY   86400L

Definition at line 31 of file timegm.c.

◆ _SEC_IN_HOUR

#define _SEC_IN_HOUR   3600L

Definition at line 30 of file timegm.c.

◆ _SEC_IN_MINUTE

#define _SEC_IN_MINUTE   60L

As there is no timegm() function neither in newlib nor in POSIX, we add one here (based on a simplified newlib mktime()).

It is used in Chan FatFS to convert dates fields.

Definition at line 29 of file timegm.c.

Function Documentation

◆ timegm()

time_t timegm ( struct tm *  tim_p)

Definition at line 67 of file timegm.c.

68{
69 time_t tim = 0;
70 long days = 0;
71 int year;
72
73 /* validate structure */
74 validate_structure (tim_p);
75
76 /* compute hours, minutes, seconds */
77 tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE)
78 + (tim_p->tm_hour * _SEC_IN_HOUR);
79
80 /* compute days in year */
81 days += tim_p->tm_mday - 1;
82#pragma GCC diagnostic push
83#if defined(__clang__)
84#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
85#endif
86 days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
87#pragma GCC diagnostic pop
88 if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
89 days++;
90
91 /* compute day of the year */
92 tim_p->tm_yday = (int)days;
93
94 if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000)
95 return (time_t)-1;
96
97 /* compute days in other years */
98 if ((year = tim_p->tm_year) > 70)
99 {
100 for (year = 70; year < tim_p->tm_year; year++)
101 days += _DAYS_IN_YEAR (year);
102 }
103 else if (year < 70)
104 {
105 for (year = 69; year > tim_p->tm_year; year--)
106 days -= _DAYS_IN_YEAR (year);
107 days -= _DAYS_IN_YEAR (year);
108 }
109
110 /* compute total seconds */
111 tim += (days * _SEC_IN_DAY);
112
113 /* compute day of the week */
114 if ((tim_p->tm_wday = (int)((days + 4) % 7)) < 0)
115 tim_p->tm_wday += 7;
116
117 return tim;
118}
static void validate_structure(struct tm *tim_p)
Definition timegm.c:125
#define _DAYS_IN_YEAR(year)
Definition timegm.c:54
static const int _DAYS_BEFORE_MONTH[12]
Definition timegm.c:49
#define _SEC_IN_DAY
Definition timegm.c:31
#define _SEC_IN_MINUTE
Definition timegm.c:29
#define _SEC_IN_HOUR
Definition timegm.c:30

References _DAYS_BEFORE_MONTH, _DAYS_IN_YEAR, _SEC_IN_DAY, _SEC_IN_HOUR, _SEC_IN_MINUTE, and validate_structure().

◆ validate_structure()

static void validate_structure ( struct tm *  tim_p)
static

Definition at line 125 of file timegm.c.

126{
127 div_t res;
128 int days_in_feb = 28;
129
130#pragma GCC diagnostic push
131#if defined(__clang__)
132#elif defined(__GNUC__)
133// For div()
134#pragma GCC diagnostic ignored "-Waggregate-return"
135#endif
136 /* calculate time & date to account for out of range values */
137 if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
138 {
139 res = div (tim_p->tm_sec, 60);
140 tim_p->tm_min += res.quot;
141 if ((tim_p->tm_sec = res.rem) < 0)
142 {
143 tim_p->tm_sec += 60;
144 --tim_p->tm_min;
145 }
146 }
147
148 if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
149 {
150 res = div (tim_p->tm_min, 60);
151 tim_p->tm_hour += res.quot;
152 if ((tim_p->tm_min = res.rem) < 0)
153 {
154 tim_p->tm_min += 60;
155 --tim_p->tm_hour;
156 }
157 }
158
159 if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
160 {
161 res = div (tim_p->tm_hour, 24);
162 tim_p->tm_mday += res.quot;
163 if ((tim_p->tm_hour = res.rem) < 0)
164 {
165 tim_p->tm_hour += 24;
166 --tim_p->tm_mday;
167 }
168 }
169
170 if (tim_p->tm_mon < 0 || tim_p->tm_mon > 11)
171 {
172 res = div (tim_p->tm_mon, 12);
173 tim_p->tm_year += res.quot;
174 if ((tim_p->tm_mon = res.rem) < 0)
175 {
176 tim_p->tm_mon += 12;
177 --tim_p->tm_year;
178 }
179 }
180#pragma GCC diagnostic pop
181
182 if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
183 days_in_feb = 29;
184
185#pragma GCC diagnostic push
186#if defined(__clang__)
187#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
188#endif
189 if (tim_p->tm_mday <= 0)
190 {
191 while (tim_p->tm_mday <= 0)
192 {
193 if (--tim_p->tm_mon == -1)
194 {
195 tim_p->tm_year--;
196 tim_p->tm_mon = 11;
197 days_in_feb
198 = ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? 29 : 28);
199 }
200 tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
201 }
202 }
203 else
204 {
205 while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
206 {
207 tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
208 if (++tim_p->tm_mon == 12)
209 {
210 tim_p->tm_year++;
211 tim_p->tm_mon = 0;
212 days_in_feb
213 = ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? 29 : 28);
214 }
215 }
216 }
217#pragma GCC diagnostic pop
218}
#define _DAYS_IN_MONTH(x)
Definition timegm.c:41

References _DAYS_IN_MONTH, and _DAYS_IN_YEAR.

Referenced by timegm().

Variable Documentation

◆ _DAYS_BEFORE_MONTH

const int _DAYS_BEFORE_MONTH[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }
static

Definition at line 48 of file timegm.c.

Referenced by timegm().

◆ DAYS_IN_MONTH

const int DAYS_IN_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
static

Definition at line 37 of file timegm.c.