Clean up the RSS feed. Attempt to read If-Modified-Since header.
[citadel.git] / webcit / fmt_date.c
1 /*
2  * $Id$
3  *
4  * Miscellaneous routines 
5  */
6
7 #include "webcit.h"
8 #include "webserver.h"
9
10 typedef unsigned char byte;
11
12 #define FALSE 0
13 #define TRUE 1
14
15 char *ascmonths[] = {
16         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
17         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
18 };
19
20 char *ascdays[] = {
21         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
22 };
23
24 /*
25  * Format a date/time stamp for output 
26  */
27 void fmt_date(char *buf, time_t thetime, int brief)
28 {
29         struct tm tm;
30         struct tm today_tm;
31         time_t today_timet;
32         int hour;
33         char calhourformat[16];
34
35         get_preference("calhourformat", calhourformat, sizeof calhourformat);
36
37         today_timet = time(NULL);
38         localtime_r(&today_timet, &today_tm);
39
40         localtime_r(&thetime, &tm);
41         hour = tm.tm_hour;
42         if (hour == 0)
43                 hour = 12;
44         else if (hour > 12)
45                 hour = hour - 12;
46
47         buf[0] = 0;
48
49         if (brief) {
50
51                 if ((tm.tm_year == today_tm.tm_year)
52                   &&(tm.tm_mon == today_tm.tm_mon)
53                   &&(tm.tm_mday == today_tm.tm_mday)) {
54                         if (!strcasecmp(calhourformat, "24")) {
55                                 sprintf(buf, "%2d:%02d",
56                                         tm.tm_hour, tm.tm_min
57                                 );
58                         }
59                         else {
60                                 sprintf(buf, "%2d:%02d%s",
61                                         hour, tm.tm_min,
62                                         ((tm.tm_hour >= 12) ? "pm" : "am")
63                                 );
64                         }
65                 }
66                 else {
67                         sprintf(buf, "%s %d %d",
68                                 ascmonths[tm.tm_mon],
69                                 tm.tm_mday,
70                                 tm.tm_year + 1900
71                         );
72                 }
73         }
74         else {
75                 if (!strcasecmp(calhourformat, "24")) {
76                         sprintf(buf, "%s %d %d %2d:%02d",
77                                 ascmonths[tm.tm_mon],
78                                 tm.tm_mday,
79                                 tm.tm_year + 1900,
80                                 tm.tm_hour, tm.tm_min
81                         );
82                 }
83                 else {
84                         sprintf(buf, "%s %d %d %2d:%02d%s",
85                                 ascmonths[tm.tm_mon],
86                                 tm.tm_mday,
87                                 tm.tm_year + 1900,
88                                 hour, tm.tm_min, ((tm.tm_hour >= 12) ? "pm" : "am")
89                         );
90                 }
91         }
92 }
93
94
95
96 /*
97  * Format TIME ONLY for output 
98  */
99 void fmt_time(char *buf, time_t thetime)
100 {
101         struct tm *tm;
102         int hour;
103         char calhourformat[16];
104
105         get_preference("calhourformat", calhourformat, sizeof calhourformat);
106
107         buf[0] = 0;
108         tm = localtime(&thetime);
109         hour = tm->tm_hour;
110         if (hour == 0)
111                 hour = 12;
112         else if (hour > 12)
113                 hour = hour - 12;
114
115         if (!strcasecmp(calhourformat, "24")) {
116                 sprintf(buf, "%2d:%02d",
117                         tm->tm_hour, tm->tm_min
118                 );
119         }
120         else {
121                 sprintf(buf, "%d:%02d%s",
122                         hour, tm->tm_min, ((tm->tm_hour > 12) ? "pm" : "am")
123                 );
124         }
125 }
126
127
128
129
130 /*
131  * Format a date/time stamp to the format used in HTTP headers
132  */
133 void httpdate(char *buf, time_t thetime)
134 {
135         struct tm *tm;
136
137         buf[0] = 0;
138         tm = localtime(&thetime);
139
140         sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d",
141                 ascdays[tm->tm_wday],
142                 tm->tm_mday,
143                 ascmonths[tm->tm_mon],
144                 tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec);
145 }
146
147
148 /*
149  * Break down the timestamp used in HTTP headers
150  * Should read rfc1123 and rfc850 dates OK
151  * FIXME won't read asctime
152  * Doesn't understand timezone, but we only should be using GMT/UTC anyway
153  */
154 time_t httpdate_to_timestamp(const char *buf)
155 {
156         time_t t = 0;
157         struct tm tt;
158         char *c;
159
160 lprintf(3, "datestamp %s\n", buf);
161         /* Skip day of week, to number */
162         for (c = buf; *c < '0' && *c > '9'; c++)
163                 ;
164
165         /* Get day of month */
166         tt.tm_mday = 0;
167         for (; *c != ' ' && *c != '-'; c++)
168                 tt.tm_mday += 10 * (*c - '0');
169         c++;
170
171         /* Get month */
172         switch (*c) {
173         case 'A':       /* April, August */
174                 tt.tm_mon = (c[1] == 'p') ? 3 : 7;
175                 break;
176         case 'D':       /* December */
177                 tt.tm_mon = 11;
178                 break;
179         case 'F':       /* February */
180                 tt.tm_mon = 1;
181                 break;
182         case 'M':       /* March, May */
183                 tt.tm_mon = (c[2] == 'r') ? 2 : 4;
184                 break;
185         case 'J':       /* January, June, July */
186                 tt.tm_mon = (c[2] == 'n') ? ((c[1] == 'a') ? 0 : 5) : 6;
187                 break;
188         case 'N':       /* November */
189                 tt.tm_mon = 10;
190                 break;
191         case 'O':       /* October */
192                 tt.tm_mon = 9;
193                 break;
194         case 'S':       /* September */
195                 tt.tm_mon = 8;
196                 break;
197         default:
198                 return 0;
199                 break;  /* NOTREACHED */
200         }
201         c += 4;
202
203         /* Get year */
204         for (; *c != ' '; c++)
205                 tt.tm_year += 10 * (*c - '0');
206         c++;
207         /* Y2K business for rfc850 dates */
208         if (tt.tm_year > 69)
209                 tt.tm_year += 1900;
210         else
211                 tt.tm_year += 2000;
212
213         /* Get hour */
214         for (; *c != ':'; c++)
215                 tt.tm_hour += 10 * (*c - '0');
216         c++;
217
218         /* Get minute */
219         for (; *c != ':'; c++)
220                 tt.tm_min += 10 * (*c - '0');
221         c++;
222
223         /* Get second */
224         for (; *c && *c != ' '; c++)
225                 tt.tm_sec += 10 * (*c - '0');
226
227         /* Got everything; let's go */
228         t = mktime(&tt);
229         return t;
230 }