* libs/http: added http mime helper lib
[project/luci.git] / libs / http / luasrc / http / protocol / date.lua
1 --[[
2
3 HTTP protocol implementation for LuCI - date handling
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13
14 ]]--
15
16 module("luci.http.protocol.date", package.seeall)
17
18 MONTHS = {
19         "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
20         "Sep", "Oct", "Nov", "Dec"
21 }
22
23 -- This list is stolen from Perl's Time::Timezone
24 TZ = {
25         -- DST zones
26         ["brst"]  =   -2*3600;   -- Brazil Summer Time (East Daylight)
27         ["adt"]   =   -3*3600;   -- Atlantic Daylight
28         ["edt"]   =   -4*3600;   -- Eastern Daylight
29         ["cdt"]   =   -5*3600;   -- Central Daylight
30         ["mdt"]   =   -6*3600;   -- Mountain Daylight
31         ["pdt"]   =   -7*3600;   -- Pacific Daylight
32         ["ydt"]   =   -8*3600;   -- Yukon Daylight
33         ["hdt"]   =   -9*3600;   -- Hawaii Daylight
34         ["bst"]   =    1*3600;   -- British Summer
35         ["mest"]  =    2*3600;   -- Middle European Summer
36         ["sst"]   =    2*3600;   -- Swedish Summer
37         ["fst"]   =    2*3600;   -- French Summer
38         ["eest"]  =    3*3600;   -- Eastern European Summer
39         ["cest"]  =    2*3600;   -- Central European Daylight
40         ["wadt"]  =    8*3600;   -- West Australian Daylight
41         ["kdt"]   =   10*3600;   -- Korean Daylight
42         ["eadt"]  =   11*3600;   -- Eastern Australian Daylight
43         ["nzdt"]  =   13*3600;   -- New Zealand Daylight
44
45         -- zones
46         ["gmt"]   =   0;                 -- Greenwich Mean
47         ["ut"]    =   0;                 -- Universal (Coordinated)
48         ["utc"]   =   0;
49         ["wet"]   =   0;                 -- Western European
50         ["wat"]   =  -1*3600;    -- West Africa
51         ["azost"] =  -1*3600;    -- Azores Standard Time
52         ["cvt"]   =  -1*3600;    -- Cape Verde Time
53         ["at"]    =  -2*3600;    -- Azores
54         ["fnt"]   =  -2*3600;    -- Brazil Time (Extreme East - Fernando Noronha)
55         ["ndt"]   =  -2*3600+1800;-- Newfoundland Daylight
56         ["art"]   =  -3*3600;    -- Argentina Time
57         ["nft"]   =  -3*3600+1800;-- Newfoundland
58         ["mnt"]   =  -4*3600;    -- Brazil Time (West Standard - Manaus)
59         ["ewt"]   =  -4*3600;    -- U.S. Eastern War Time
60         ["ast"]   =  -4*3600;    -- Atlantic Standard
61         ["bot"]   =  -4*3600;    -- Bolivia Time
62         ["vet"]   =  -4*3600;    -- Venezuela Time
63         ["est"]   =  -5*3600;    -- Eastern Standard
64         ["cot"]   =  -5*3600;    -- Colombia Time
65         ["act"]   =  -5*3600;    -- Brazil Time (Extreme West - Acre)
66         ["pet"]   =  -5*3600;    -- Peru Time
67         ["cst"]   =  -6*3600;    -- Central Standard
68         ["cest"]  =   2*3600;    -- Central European Summer
69         ["mst"]   =  -7*3600;    -- Mountain Standard
70         ["pst"]   =  -8*3600;    -- Pacific Standard
71         ["yst"]   =  -9*3600;    -- Yukon Standard
72         ["hst"]   = -10*3600;    -- Hawaii Standard
73         ["cat"]   = -10*3600;    -- Central Alaska
74         ["ahst"]  = -10*3600;    -- Alaska-Hawaii Standard
75         ["taht"]  = -10*3600;    -- Tahiti Time
76         ["nt"]    = -11*3600;    -- Nome
77         ["idlw"]  = -12*3600;    -- International Date Line West
78         ["cet"]   =   1*3600;    -- Central European
79         ["mez"]   =   1*3600;    -- Central European (German)
80         ["met"]   =   1*3600;    -- Middle European
81         ["mewt"]  =   1*3600;    -- Middle European Winter
82         ["swt"]   =   1*3600;    -- Swedish Winter
83         ["set"]   =   1*3600;    -- Seychelles
84         ["fwt"]   =   1*3600;    -- French Winter
85         ["west"]  =   1*3600;    -- Western Europe Summer Time
86         ["eet"]   =   2*3600;    -- Eastern Europe; USSR Zone 1
87         ["ukr"]   =   2*3600;    -- Ukraine
88         ["sast"]  =   2*3600;    -- South Africa Standard Time
89         ["bt"]    =   3*3600;    -- Baghdad; USSR Zone 2
90         ["eat"]   =   3*3600;    -- East Africa Time
91         ["irst"]  =   3*3600+1800;-- Iran Standard Time
92         ["zp4"]   =   4*3600;    -- USSR Zone 3
93         ["msd"]   =   4*3600;    -- Moscow Daylight Time
94         ["sct"]   =   4*3600;    -- Seychelles Time
95         ["zp5"]   =   5*3600;    -- USSR Zone 4
96         ["azst"]  =   5*3600;    -- Azerbaijan Summer Time
97         ["mvt"]   =   5*3600;    -- Maldives Time
98         ["uzt"]   =   5*3600;    -- Uzbekistan Time
99         ["ist"]   =   5*3600+1800;-- Indian Standard
100         ["zp6"]   =   6*3600;    -- USSR Zone 5
101         ["lkt"]   =   6*3600;    -- Sri Lanka Time
102         ["pkst"]  =   6*3600;    -- Pakistan Summer Time
103         ["yekst"] =   6*3600;    -- Yekaterinburg Summer Time
104         ["wast"]  =   7*3600;    -- West Australian Standard
105         ["ict"]   =   7*3600;    -- Indochina Time
106         ["wit"]   =   7*3600;    -- Western Indonesia Time
107         ["cct"]   =   8*3600;    -- China Coast; USSR Zone 7
108         ["wst"]   =   8*3600;    -- West Australian Standard
109         ["hkt"]   =   8*3600;    -- Hong Kong
110         ["bnt"]   =   8*3600;    -- Brunei Darussalam Time
111         ["cit"]   =   8*3600;    -- Central Indonesia Time
112         ["myt"]   =   8*3600;    -- Malaysia Time
113         ["pht"]   =   8*3600;    -- Philippines Time
114         ["sgt"]   =   8*3600;    -- Singapore Time
115         ["jst"]   =   9*3600;    -- Japan Standard; USSR Zone 8
116         ["kst"]   =   9*3600;    -- Korean Standard
117         ["east"]  =  10*3600;    -- Eastern Australian Standard
118         ["gst"]   =  10*3600;    -- Guam Standard; USSR Zone 9
119         ["nct"]   =  11*3600;    -- New Caledonia Time
120         ["nzt"]   =  12*3600;    -- New Zealand
121         ["nzst"]  =  12*3600;    -- New Zealand Standard
122         ["fjt"]   =  12*3600;    -- Fiji Time
123         ["idle"]  =  12*3600;    -- International Date Line East
124 }
125
126
127 -- Find corresponding timezone offset
128 function tz_offset(tz)
129
130         if type(tz) == "string" then
131
132                 -- check for a numeric identifier
133                 local s, v = tz:match("([%+%-])([0-9]+)")
134                 if s == '+' then s = 1 else s = -1 end
135                 if v then v = tonumber(v) end
136
137                 if s and v then
138                         return s * 60 * ( math.floor( v / 100 ) * 60 + ( v % 100 ) )
139
140                 -- lookup symbolic tz
141                 elseif TZ[tz:lower()] then
142                         return TZ[tz:lower()]
143                 end
144
145         end
146
147         -- bad luck
148         return 0
149 end
150
151 -- Convert a HTTP date to unixtime
152 function to_unix(date)
153
154         print("D: "..date)
155
156         local wd, day, mon, yr, hr, min, sec, tz = date:match(
157                 "([A-Z][a-z][a-z]), ([0-9]+) " ..
158                 "([A-Z][a-z][a-z]) ([0-9]+) " ..
159                 "([0-9]+):([0-9]+):([0-9]+) " ..
160                 "([A-Z0-9%+%-]+)"
161         )
162
163         print(day .. " | " .. mon .. " | " .. yr .. " | " .. tz)
164
165         if day and mon and yr and hr and min and sec then
166
167                 -- find month
168                 local month = 1
169                 for i = 1, 12 do
170                         if MONTHS[i] == mon then
171                                 month = i
172                                 break
173                         end
174                 end
175
176                 -- convert to epoch time
177                 return tz_offset(tz) + os.time( {
178                         year  = yr,
179                         month = month,
180                         day   = day,
181                         hour  = hr,
182                         min   = min,
183                         sec   = sec
184                 } )
185         end
186
187         return 0
188 end
189
190 -- Convert a unixtime to HTTP date
191 function to_http(time)
192         return os.date( "%a, %d %b %Y %H:%M:%S GMT", time )
193 end
194
195 -- Compare two dates
196 function compare(d1, d2)
197
198         if d1:match("[^0-9]") then d1 = to_unix(d1) end
199         if d2:match("[^0-9]") then d2 = to_unix(d2) end
200
201         if d1 == d2 then
202                 return 0
203         elseif d1 < d2 then
204                 return -1
205         else
206                 return 1
207         end
208 end