161107ce0835f3ee37d103141e3f555ced350920
[project/luci.git] / modules / luci-base / luasrc / http / protocol / date.lua
1 -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
2 -- Licensed to the public under the Apache License 2.0.
3
4 --- LuCI http protocol implementation - date helper class.
5 -- This class contains functions to parse, compare and format http dates.
6 module("luci.http.protocol.date", package.seeall)
7
8 require("luci.sys.zoneinfo")
9
10
11 MONTHS = {
12         "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
13         "Sep", "Oct", "Nov", "Dec"
14 }
15
16 --- Return the time offset in seconds between the UTC and given time zone.
17 -- @param tz    Symbolic or numeric timezone specifier
18 -- @return              Time offset to UTC in seconds
19 function tz_offset(tz)
20
21         if type(tz) == "string" then
22
23                 -- check for a numeric identifier
24                 local s, v = tz:match("([%+%-])([0-9]+)")
25                 if s == '+' then s = 1 else s = -1 end
26                 if v then v = tonumber(v) end
27
28                 if s and v then
29                         return s * 60 * ( math.floor( v / 100 ) * 60 + ( v % 100 ) )
30
31                 -- lookup symbolic tz
32                 elseif luci.sys.zoneinfo.OFFSET[tz:lower()] then
33                         return luci.sys.zoneinfo.OFFSET[tz:lower()]
34                 end
35
36         end
37
38         -- bad luck
39         return 0
40 end
41
42 --- Parse given HTTP date string and convert it to unix epoch time.
43 -- @param data  String containing the date
44 -- @return              Unix epoch time
45 function to_unix(date)
46
47         local wd, day, mon, yr, hr, min, sec, tz = date:match(
48                 "([A-Z][a-z][a-z]), ([0-9]+) " ..
49                 "([A-Z][a-z][a-z]) ([0-9]+) " ..
50                 "([0-9]+):([0-9]+):([0-9]+) " ..
51                 "([A-Z0-9%+%-]+)"
52         )
53
54         if day and mon and yr and hr and min and sec then
55                 -- find month
56                 local month = 1
57                 for i = 1, 12 do
58                         if MONTHS[i] == mon then
59                                 month = i
60                                 break
61                         end
62                 end
63
64                 -- convert to epoch time
65                 return tz_offset(tz) + os.time( {
66                         year  = yr,
67                         month = month,
68                         day   = day,
69                         hour  = hr,
70                         min   = min,
71                         sec   = sec
72                 } )
73         end
74
75         return 0
76 end
77
78 --- Convert the given unix epoch time to valid HTTP date string.
79 -- @param time  Unix epoch time
80 -- @return              String containing the formatted date
81 function to_http(time)
82         return os.date( "%a, %d %b %Y %H:%M:%S GMT", time )
83 end
84
85 --- Compare two dates which can either be unix epoch times or HTTP date strings.
86 -- @param d1    The first date or epoch time to compare
87 -- @param d2    The first date or epoch time to compare
88 -- @return              -1  -  if d1 is lower then d2
89 -- @return              0   -  if both dates are equal
90 -- @return              1   -  if d1 is higher then d2
91 function compare(d1, d2)
92
93         if d1:match("[^0-9]") then d1 = to_unix(d1) end
94         if d2:match("[^0-9]") then d2 = to_unix(d2) end
95
96         if d1 == d2 then
97                 return 0
98         elseif d1 < d2 then
99                 return -1
100         else
101                 return 1
102         end
103 end