2 * Copyright 2010-2016 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Christophe Huriaux, c.huriaux@gmail.com
7 * Adrien Destugues, pulkomandy@gmail.com
17 // The formats used should be, in order of preference (according to RFC2616,
19 // RFC1123 / RFC822: "Sun, 06 Nov 1994 08:49:37 GMT"
20 // RFC1036 / RFC850: "Sunday, 06-Nov-94 08:49:37 GMT"
21 // asctime : "Sun Nov 6 08:49:37 1994"
23 // RFC1123 is the preferred one because it has 4 digit years.
25 // But of course in real life, all possible mixes of the formats are used.
26 // Believe it or not, it's even possible to find some website that gets this
27 // right and use one of the 3 formats above.
28 // Often seen variants are:
29 // - RFC1036 but with 4 digit year,
30 // - Missing or different timezone indicator
32 static const char* kDateFormats
[] = {
34 "%a, %d %b %Y %H:%M:%S", // without timezone
35 "%a, %d %b %Y %H:%M:%S GMT", // canonical
38 "%A, %d-%b-%y %H:%M:%S", // without timezone
39 "%A, %d-%b-%y %H:%M:%S GMT", // canonical
41 // RFC1036 with 4 digit year
42 "%a, %d-%b-%Y %H:%M:%S", // without timezone
43 "%a, %d-%b-%Y %H:%M:%S GMT", // with 4-digit year
44 "%a, %d-%b-%Y %H:%M:%S UTC", // "UTC" timezone
47 "%a %d %b %H:%M:%S %Y"
50 using namespace BPrivate
;
53 BHttpTime::BHttpTime()
56 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED
)
61 BHttpTime::BHttpTime(BDateTime date
)
64 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED
)
69 BHttpTime::BHttpTime(const BString
& dateString
)
71 fDateString(dateString
),
73 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED
)
78 // #pragma mark Date modification
82 BHttpTime::SetString(const BString
& string
)
89 BHttpTime::SetDate(BDateTime date
)
95 // #pragma mark Date conversion
101 struct tm expireTime
;
103 if (fDateString
.Length() < 4)
106 memset(&expireTime
, 0, sizeof(struct tm
));
108 fDateFormat
= B_HTTP_TIME_FORMAT_PARSED
;
110 for (i
= 0; i
< sizeof(kDateFormats
) / sizeof(const char*);
112 const char* result
= strptime(fDateString
.String(), kDateFormats
[i
],
115 // We need to parse the complete value for the "Expires" key.
116 // Otherwise, we consider this to be a session cookie (or try another
117 // one of the date formats).
118 if (result
== fDateString
.String() + fDateString
.Length()) {
124 // Did we identify some valid format?
125 if (fDateFormat
== B_HTTP_TIME_FORMAT_PARSED
)
128 // Now convert the struct tm from strptime into a BDateTime.
129 BTime
time(expireTime
.tm_hour
, expireTime
.tm_min
, expireTime
.tm_sec
);
130 BDate
date(expireTime
.tm_year
+ 1900, expireTime
.tm_mon
+ 1,
132 BDateTime
dateTime(date
, time
);
138 BHttpTime::ToString(int8 format
)
140 BString expirationFinal
;
141 struct tm expirationTm
;
142 expirationTm
.tm_sec
= fDate
.Time().Second();
143 expirationTm
.tm_min
= fDate
.Time().Minute();
144 expirationTm
.tm_hour
= fDate
.Time().Hour();
145 expirationTm
.tm_mday
= fDate
.Date().Day();
146 expirationTm
.tm_mon
= fDate
.Date().Month() - 1;
147 expirationTm
.tm_year
= fDate
.Date().Year() - 1900;
148 // strftime starts weekday count at 0 for Sunday,
149 // while DayOfWeek starts at 1 for Monday and thus uses 7 for Sunday
150 expirationTm
.tm_wday
= fDate
.Date().DayOfWeek() % 7;
151 expirationTm
.tm_yday
= 0;
152 expirationTm
.tm_isdst
= 0;
154 if (format
== B_HTTP_TIME_FORMAT_PARSED
)
155 format
= fDateFormat
;
157 if (format
!= B_HTTP_TIME_FORMAT_PARSED
) {
158 static const uint16 kTimetToStringMaxLength
= 128;
159 char expirationString
[kTimetToStringMaxLength
+ 1];
162 strLength
= strftime(expirationString
, kTimetToStringMaxLength
,
163 kDateFormats
[format
], &expirationTm
);
165 expirationFinal
.SetTo(expirationString
, strLength
);
167 return expirationFinal
;