b3b993866426efbb79aa2715b22d1fca5a862eca
[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 to 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