00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include <unistd.h>
00063 #include <ctype.h>
00064 #include <string.h>
00065
00066 #include "gwlib.h"
00067
00068 static unsigned char *wkday[7] = {
00069 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00070 };
00071
00072 static unsigned char *monthname[12] = {
00073 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00074 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00075 };
00076
00077
00078
00079 static int monthstart[12] = {
00080 0, 31, 59, 90, 120, 151,
00081 181, 212, 243, 273, 304, 334
00082 };
00083
00084
00085 #define MINUTE 60
00086 #define HOUR (60 * MINUTE)
00087 #define DAY (24 * HOUR)
00088
00089 Octstr *date_format_http(unsigned long unixtime)
00090 {
00091 struct tm tm;
00092 unsigned char buffer[30];
00093
00094 tm = gw_gmtime((time_t) unixtime);
00095
00096
00097
00098
00099 if (tm.tm_wday < 0 || tm.tm_wday > 6 ||
00100 tm.tm_mday < 0 || tm.tm_mday > 31 ||
00101 tm.tm_mon < 0 || tm.tm_mon > 11 ||
00102 tm.tm_year < 0 ||
00103 tm.tm_hour < 0 || tm.tm_hour > 23 ||
00104 tm.tm_min < 0 || tm.tm_min > 59 ||
00105 tm.tm_sec < 0 || tm.tm_sec > 61) {
00106 warning(0, "Bad date for timestamp %lu, cannot format.",
00107 unixtime);
00108 return NULL;
00109 }
00110
00111 sprintf(buffer, "%s, %02d %s %04d %02d:%02d:%02d GMT",
00112 wkday[tm.tm_wday], tm.tm_mday, monthname[tm.tm_mon],
00113 tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
00114
00115 return octstr_create(buffer);
00116 }
00117
00118 long date_convert_universal(struct universaltime *t)
00119 {
00120 long date;
00121 int leapyears;
00122 long year;
00123
00124 date = (t->year - 1970) * (365 * DAY);
00125
00126
00127
00128 year = t->year;
00129 if (t->month <= 1)
00130 year--;
00131
00132
00133
00134
00135 leapyears = (year / 4) - (year / 100) + (year / 400) - 477;
00136 date += leapyears * DAY;
00137
00138 date += monthstart[t->month] * DAY;
00139 date += (t->day - 1) * DAY;
00140 date += t->hour * HOUR;
00141 date += t->minute * MINUTE;
00142 date += t->second;
00143
00144 return date;
00145 }
00146
00147 long date_parse_http(Octstr *date)
00148 {
00149 long pos;
00150 struct universaltime t;
00151 Octstr *monthstr = NULL;
00152
00153
00154 pos = octstr_search_char(date, ' ', 0);
00155 if (pos < 0 || pos == octstr_len(date) - 1)
00156 return -1;
00157 pos++;
00158
00159
00160 if (isdigit(octstr_get_char(date, pos)) &&
00161 octstr_get_char(date, pos + 2) == ' ') {
00162 if (octstr_len(date) - pos < (long)strlen("06 Nov 1994 08:49:37 GMT"))
00163 goto error;
00164 if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
00165 goto error;
00166 monthstr = octstr_copy(date, pos + 3, 3);
00167 if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 11)
00168 goto error;
00169 if (octstr_parse_long(&t.hour, date, pos + 12, 10) != pos + 14)
00170 goto error;
00171 if (octstr_parse_long(&t.minute, date, pos + 15, 10) != pos + 17)
00172 goto error;
00173 if (octstr_parse_long(&t.second, date, pos + 18, 10) != pos + 20)
00174 goto error;
00175
00176 } else if (isdigit(octstr_get_char(date, pos)) &&
00177 octstr_get_char(date, pos + 2) == '-') {
00178 if (octstr_len(date) - pos < (long)strlen("06-Nov-94 08:49:37 GMT"))
00179 goto error;
00180 if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
00181 goto error;
00182 monthstr = octstr_copy(date, pos + 3, 3);
00183 if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 9)
00184 goto error;
00185 if (t.year > 60)
00186 t.year += 1900;
00187 else
00188 t.year += 2000;
00189 if (octstr_parse_long(&t.hour, date, pos + 10, 10) != pos + 12)
00190 goto error;
00191 if (octstr_parse_long(&t.minute, date, pos + 13, 10) != pos + 15)
00192 goto error;
00193 if (octstr_parse_long(&t.second, date, pos + 16, 10) != pos + 18)
00194 goto error;
00195
00196 } else {
00197 if (octstr_len(date) - pos < (long)strlen(" 6 08:49:37 1994"))
00198 goto error;
00199 monthstr = octstr_copy(date, pos, 3);
00200 if (octstr_parse_long(&t.day, date, pos + 4, 10) != pos + 6)
00201 goto error;
00202 if (octstr_parse_long(&t.hour, date, pos + 7, 10) != pos + 9)
00203 goto error;
00204 if (octstr_parse_long(&t.minute, date, pos + 10, 10) != pos + 12)
00205 goto error;
00206 if (octstr_parse_long(&t.second, date, pos + 13, 10) != pos + 15)
00207 goto error;
00208 if (octstr_parse_long(&t.year, date, pos + 16, 10) != pos + 20)
00209 goto error;
00210 }
00211
00212 for (t.month = 0; t.month < 12; t.month++) {
00213 if (octstr_str_compare(monthstr, monthname[t.month]) == 0)
00214 break;
00215 }
00216 if (t.month == 12)
00217 goto error;
00218
00219 octstr_destroy(monthstr);
00220 return date_convert_universal(&t);
00221
00222 error:
00223 octstr_destroy(monthstr);
00224 return -1;
00225 }
00226
00227 int date_parse_iso (struct universaltime *ut, Octstr *os)
00228 {
00229 long pos = 0;
00230 int c;
00231
00232
00233 ut->month = 0;
00234 ut->day = 1;
00235 ut->hour = 0;
00236 ut->minute = 0;
00237 ut->second = 0;
00238
00239 if ((pos = octstr_parse_long(&(ut->year), os, pos, 10)) < 0)
00240 return -1;
00241 if (ut->year < 70)
00242 ut->year += 2000;
00243 else if (ut->year < 100)
00244 ut->year += 1900;
00245
00246 while ((c = octstr_get_char(os, pos)) != -1 && !gw_isdigit(c))
00247 pos++;
00248 if ((pos = octstr_parse_long(&(ut->month), os, pos, 10)) < 0)
00249 return 0;
00250
00251
00252 if (ut->month > 0)
00253 ut->month--;
00254
00255 while ((c = octstr_get_char(os, pos)) != -1 && !gw_isdigit(c))
00256 pos++;
00257 if ((pos = octstr_parse_long(&(ut->day), os, pos, 10)) < 0)
00258 return 0;
00259
00260 while ((c = octstr_get_char(os, pos)) != -1 && !gw_isdigit(c))
00261 pos++;
00262 if ((pos = octstr_parse_long(&(ut->hour), os, pos, 10)) < 0)
00263 return 0;
00264
00265 while ((c = octstr_get_char(os, pos)) != -1 && !gw_isdigit(c))
00266 pos++;
00267 if ((pos = octstr_parse_long(&(ut->minute), os, pos, 10)) < 0)
00268 return 0;
00269
00270 while ((c = octstr_get_char(os, pos)) != -1 && !gw_isdigit(c))
00271 pos++;
00272 if ((pos = octstr_parse_long(&(ut->second), os, pos, 10)) < 0)
00273 return 0;
00274
00275 return 0;
00276 }
00277
00278 Octstr* date_create_iso(time_t unixtime)
00279 {
00280 struct tm tm;
00281
00282 tm = gw_gmtime(unixtime);
00283
00284 return octstr_format("%d-%02d-%02dT%02d:%02d:%02dZ",
00285 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
00286 }
00287
00288
00289
00290 long date_universal_now(void)
00291 {
00292 return (long) time(NULL);
00293 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.