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);