2 using System.Globalization;
5 namespace System.Web.Util
7 internal static class HttpDate
9 static readonly int[] s_tensDigit = new int[10] { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 };
13 Converts a 2 character string to integer
19 numeric equivalent, 0 on failure.
21 static int atoi2(string s, int startIndex)
24 int tens = s[0 + startIndex] - '0';
25 int ones = s[1 + startIndex] - '0';
27 return s_tensDigit[tens] + ones;
30 throw new FormatException(SR.GetString(SR.Atio2BadString, s, startIndex));
34 static readonly string[] s_days = new string [7] {
35 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
38 static readonly string[] s_months = new string[12] {
39 "Jan", "Feb", "Mar", "Apr",
40 "May", "Jun", "Jul", "Aug",
41 "Sep", "Oct", "Nov", "Dec"
44 // Custom table for make_month() for mapping "Apr" to 4
45 static readonly sbyte[] s_monthIndexTable = new sbyte[64] {
46 -1, (sbyte)'A', 2, 12, -1, -1, -1, 8, // A to G
47 -1, -1, -1, -1, 7, -1, (sbyte)'N', -1, // H to O
48 9, -1, (sbyte)'R', -1, 10, -1, 11, -1, // P to W
49 -1, 5, -1, -1, -1, -1, -1, -1, // X to Z
50 -1, (sbyte)'A', 2, 12, -1, -1, -1, 8, // a to g
51 -1, -1, -1, -1, 7, -1, (sbyte)'N', -1, // h to o
52 9, -1, (sbyte)'R', -1, 10, -1, 11, -1, // p to w
53 -1, 5, -1, -1, -1, -1, -1, -1 // x to z
56 static int make_month(string s, int startIndex)
63 // use the third character as the index
66 i = ((int) s[2 + startIndex] - 0x40) & 0x3F;
67 monthIndex = s_monthIndexTable[i];
69 if ( monthIndex >= 13 ) {
72 // ok, we need to look at the second character
75 if ( monthIndex == (sbyte) 'N' ) {
78 // we got an N which we need to resolve further
82 // if s[1] is 'u' then Jun, if 'a' then Jan
86 if ( s_monthIndexTable[(s[1 + startIndex]-0x40) & 0x3f] == (sbyte) 'A' ) {
92 } else if ( monthIndex == (sbyte) 'R' ) {
95 // if s[1] is 'a' then [....], if 'p' then April
98 if ( s_monthIndexTable[(s[1 + startIndex]-0x40) & 0x3f] == (sbyte) 'A' ) {
104 throw new FormatException(SR.GetString(SR.MakeMonthBadString, s, startIndex));
109 monthString = s_months[monthIndex-1];
111 if ( (s[0 + startIndex] == monthString[0]) &&
112 (s[1 + startIndex] == monthString[1]) &&
113 (s[2 + startIndex] == monthString[2]) ) {
117 } else if ( ((Char.ToUpper(s[0 + startIndex], CultureInfo.InvariantCulture)) == monthString[0]) &&
118 ((Char.ToLower(s[1 + startIndex], CultureInfo.InvariantCulture)) == monthString[1]) &&
119 ((Char.ToLower(s[2 + startIndex], CultureInfo.InvariantCulture)) == monthString[2]) ) {
124 throw new FormatException(SR.GetString(SR.MakeMonthBadString, s, startIndex));
130 Converts a string representation of a GMT time (three different
131 varieties) to an NT representation of a file time.
133 We handle the following variations:
135 Sun, 06 Nov 1994 08:49:37 GMT (RFC 822 updated by RFC 1123)
136 Sunday, 06-Nov-94 08:49:37 GMT (RFC 850)
137 Sun Nov 06 08:49:37 1994 (ANSI C's asctime() format
140 time String representation of time field
143 TRUE on success and FALSE on failure.
147 Johnl 24-Jan-1995 Modified from WWW library
150 static internal DateTime UtcParse(string time)
153 int year, month, day, hour, minute, second;
156 throw new ArgumentNullException("time");
159 if ((i = time.IndexOf(',')) != -1) {
162 // Thursday, 10-Jun-93 01:29:59 GMT
163 // or: Thu, 10 Jan 1993 01:29:59 GMT */
166 int length = time.Length - i;
167 while (--length > 0 && time[++i] == ' ') ;
169 if (time[i+2] == '-' ) { /* First format */
172 throw new FormatException(SR.GetString(SR.UtilParseDateTimeBad, time));
175 day = atoi2(time, i);
176 month = make_month(time, i + 3);
177 year = atoi2(time, i + 7);
184 hour = atoi2(time, i + 10);
185 minute = atoi2(time, i + 13);
186 second = atoi2(time, i +16);
188 } else { /* Second format */
191 throw new FormatException(SR.GetString(SR.UtilParseDateTimeBad, time));
194 day = atoi2(time, i);
195 month = make_month(time, i + 3);
196 year = atoi2(time, i + 7) * 100 + atoi2(time, i + 9);
197 hour = atoi2(time, i + 12);
198 minute = atoi2(time, i + 15);
199 second = atoi2(time, i + 18);
201 } else { /* Try the other format: Wed Jun 09 01:29:59 1993 GMT */
204 int length = time.Length + 1;
205 while (--length > 0 && time[++i] == ' ');
208 throw new FormatException(SR.GetString(SR.UtilParseDateTimeBad, time));
211 day = atoi2(time, i + 8);
212 month = make_month(time, i + 4);
213 year = atoi2(time, i + 20) * 100 + atoi2(time, i + 22);
214 hour = atoi2(time, i + 11);
215 minute = atoi2(time, i + 14);
216 second = atoi2(time, i + 17);
219 return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc);