RSS: Update debugging messages
[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         char tz[256];
160
161         /* Skip day of week, to number */
162         for (c = buf; *c != ' '; c++)
163                 ;
164         c++;
165
166         /* Get day of month */
167         tt.tm_mday = atoi(c);
168         for (; *c != ' ' && *c != '-'; c++);
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 42;
199                 break;  /* NOTREACHED */
200         }
201         c += 4;
202
203         tt.tm_year = 0;
204         /* Get year */
205         tt.tm_year = atoi(c);
206         for (; *c != ' '; c++);
207         c++;
208         if (tt.tm_year >= 1900)
209                 tt.tm_year -= 1900;
210
211         /* Get hour */
212         tt.tm_hour = atoi(c);
213         for (; *c != ':'; c++);
214         c++;
215
216         /* Get minute */
217         tt.tm_min = atoi(c);
218         for (; *c != ':'; c++);
219         c++;
220
221         /* Get second */
222         tt.tm_sec = atoi(c);
223         for (; *c && *c != ' '; c++);
224
225         /* Got everything; let's go */
226         /* First, change to UTC */
227         if (getenv("TZ"))
228                 sprintf(tz, "TZ=%s", getenv("TZ"));
229         else
230                 strcpy(tz, "TZ=");
231         putenv("TZ=UTC");
232         tzset();
233         t = mktime(&tt);
234         putenv(tz);
235         tzset();
236         return t;
237 }