]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/time/rfc1123.cc
2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 #include "time/gadgets.h"
13 * Adapted from HTSUtils.c in CERN httpd 3.0 (http://info.cern.ch/httpd/)
14 * by Darren Hardy <hardy@cs.colorado.edu>, November 1994.
26 #define RFC850_STRFTIME "%A, %d-%b-%y %H:%M:%S GMT"
27 #define RFC1123_STRFTIME "%a, %d %b %Y %H:%M:%S GMT"
29 static int make_month(const char *s
);
30 static int make_num(const char *s
);
32 static const char *month_names
[12] = {
33 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
34 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
38 make_num(const char *s
)
40 if (*s
>= '0' && *s
<= '9')
41 return 10 * (*s
- '0') + *(s
+ 1) - '0';
43 return *(s
+ 1) - '0';
47 make_month(const char *s
)
52 month
[0] = xtoupper(*s
);
53 month
[1] = xtolower(*(s
+ 1));
54 month
[2] = xtolower(*(s
+ 2));
56 for (i
= 0; i
< 12; i
++)
57 if (!strncmp(month_names
[i
], month
, 3))
63 tmSaneValues(struct tm
*tm
)
65 if (tm
->tm_sec
< 0 || tm
->tm_sec
> 59)
67 if (tm
->tm_min
< 0 || tm
->tm_min
> 59)
69 if (tm
->tm_hour
< 0 || tm
->tm_hour
> 23)
71 if (tm
->tm_mday
< 1 || tm
->tm_mday
> 31)
73 if (tm
->tm_mon
< 0 || tm
->tm_mon
> 11)
79 parse_date_elements(const char *day
, const char *month
, const char *year
,
80 const char *aTime
, const char *zone
) {
83 memset(&tm
, 0, sizeof(tm
));
85 if (!day
|| !month
|| !year
|| !aTime
|| (zone
&& strcmp(zone
, "GMT")))
87 tm
.tm_mday
= atoi(day
);
88 tm
.tm_mon
= make_month(month
);
91 tm
.tm_year
= atoi(year
);
92 if (strlen(year
) == 4)
94 else if (tm
.tm_year
< 70)
96 else if (tm
.tm_year
> 19000)
98 tm
.tm_hour
= make_num(aTime
);
99 t
= strchr(aTime
, ':');
106 tm
.tm_sec
= atoi(t
+ 1);
107 return tmSaneValues(&tm
) ? &tm
: nullptr;
111 parse_date(const char *str
) {
115 char *wday
= nullptr;
117 char *month
= nullptr;
118 char *year
= nullptr;
119 char *timestr
= nullptr;
120 char *zone
= nullptr;
122 xstrncpy(tmp
, str
, 64);
124 for (t
= strtok(tmp
, ", "); t
; t
= strtok(nullptr, ", ")) {
138 } else if (strchr(t
, ':'))
153 tm
= parse_date_elements(day
, month
, year
, timestr
, zone
);
159 Time::ParseRfc1123(const char *str
)
165 tm
= parse_date(str
);
171 #elif HAVE_TM_TM_GMTOFF
174 struct tm
*local
= localtime(&t
);
175 t
+= local
->tm_gmtoff
;
178 /* some systems do not have tm_gmtoff so we fake it */
182 #if !(defined(_TIMEZONE) || defined(_timezone) || _SQUID_AIX_ || _SQUID_WINDOWS_ || _SQUID_SGI_)
183 extern long timezone
;
186 * The following assumes a fixed DST offset of 1 hour,
187 * which is probably wrong.
189 if (tm
->tm_isdst
> 0)
191 #if defined(_timezone) || _SQUID_WINDOWS_
192 t
-= (_timezone
+ dst
);
194 t
-= (timezone
+ dst
);
202 Time::FormatRfc1123(time_t t
)
204 static char buf
[128];
206 struct tm
*gmt
= gmtime(&t
);
209 strftime(buf
, 127, RFC1123_STRFTIME
, gmt
);