2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
13 static time_t my_mktime(struct tm
*tm
)
15 static const int mdays
[] = {
16 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
18 int year
= tm
->tm_year
- 70;
19 int month
= tm
->tm_mon
;
20 int day
= tm
->tm_mday
;
22 if (year
< 0 || year
> 129) /* algo only works for 1970-2099 */
24 if (month
< 0 || month
> 11) /* array bounds */
26 if (month
< 2 || (year
+ 2) % 4)
28 return (year
* 365 + (year
+ 1) / 4 + mdays
[month
] + day
) * 24*60*60UL +
29 tm
->tm_hour
* 60*60 + tm
->tm_min
* 60 + tm
->tm_sec
;
32 static const char *month_names
[] = {
33 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
34 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
37 static const char *weekday_names
[] = {
38 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
42 static char *skipfws(char *str
)
50 /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
51 (i.e. English) day/month names, and it doesn't work correctly with %z. */
52 void parse_date(char *date
, char *result
, int maxlen
)
59 memset(&tm
, 0, sizeof(tm
));
65 if (!strncmp(p
,weekday_names
[i
],3) && p
[3] == ',') {
75 tm
.tm_mday
= strtoul(p
, &p
, 10);
77 if (tm
.tm_mday
< 1 || tm
.tm_mday
> 31)
87 for (i
=0; i
<12; i
++) {
88 if (!strncmp(p
, month_names
[i
], 3) && isspace(p
[3])) {
90 p
= skipfws(p
+strlen(month_names
[i
]));
94 return; /* Error -- bad month */
98 tm
.tm_year
= strtoul(p
, &p
, 10);
100 if (!tm
.tm_year
&& !isspace(*p
))
103 if (tm
.tm_year
> 1900)
111 tm
.tm_hour
= strtoul(p
, &p
, 10);
117 return; /* Error -- bad time */
123 tm
.tm_min
= strtoul(p
, &p
, 10);
135 tm
.tm_sec
= strtoul(p
, &p
, 10);
153 if (!isdigit(p
[1]) || !isdigit(p
[2]) || !isdigit(p
[3]) || !isdigit(p
[4]))
157 i
= strtoul(p
+1, NULL
, 10);
158 offset
*= ((i
% 100) + ((i
/ 100) * 60));
161 if (*p
&& *p
!= '(') /* trailing comment like (EDT) is ok */
164 then
= my_mktime(&tm
); /* mktime uses local timezone */
170 snprintf(result
, maxlen
, "%lu %5.5s", then
, tz
);
173 void datestamp(char *buf
, int bufsize
)
180 offset
= my_mktime(localtime(&now
)) - now
;
183 snprintf(buf
, bufsize
, "%lu %+05d", now
, offset
/60*100 + offset
%60);