[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: os.time() and timezones
- From: Rena <hyperhacker@...>
- Date: Sat, 14 Apr 2012 03:22:19 -0600
On Fri, Apr 13, 2012 at 14:26, Sean Conner <sean@conman.org> wrote:
> It was thus said that the Great steve donovan once stated:
>> On Fri, Apr 13, 2012 at 10:16 AM, Rena <hyperhacker@gmail.com> wrote:
>> > Ouch.) Does Lua provide a way to turn a table into a Unix timestamp
>> > under the assumption that the table specifies GMT, not the local
>> > timezone?
>
> Even operating systems have trouble with timezones:
>
> http://www.chronos-st.org/Discovering%20the%20Local%20Time%20Zone--Why%20It%27s%20a%20Hard%20Problem.html
>
>> I use this kind of logic to find the timezone offset in pl.Date:
>>
>> local t = os.time()
>> local ut = os.date('!*t',t)
>> local lt = os.date('*t',t)
>> thour = lt.hour - ut.hour
>> tmin = lt.min - ut.min
>>
>> If this is misguided I would certainly like to know!
>
> It is. Try this:
>
> gmt = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 ,
> 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 }
> loc = { 19 , 20 , 21 , 22 , 23 , 0 , 1 , 2 , 3 , 4 , 5 , 6 ,
> 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 }
>
> for i = 1 , 24 do
> print(i,loc[i] - gmt[i])
> end
>
> And even when it does work, it still doesn't take into account DST. I found
> this works:
>
> now = os.time()
> lmt = os.date("*t",now)
> gmt = os.date("!*t",now)
> timel = os.time(lmt)
> timeg = os.time(gmt)
> zone = os.difftime(timel,timeg)
>
> if lmt.isdst then
> if zone < 0 then
> zone = zone + 3600
> else
> zone = zone - 3600
> end
> end
>
> -spc (Time is hard! I wonder how The Doctor does it?)
>
>
Hmm, are you sure about that DST correction? Perhaps I'm not parsing
HTTP dates properly:
function rena_http.parse_date(date)
local month_names = { jan=1, feb=2, mar=3, apr=4, may=5, jun=6, jul=7,
aug=8, sep=9, oct=10, nov=11, dec=12}
local day, mon, year, hour, min, sec = date:match(
'...,? (%d-) (...) (%d-) (%d-):(%d-):(%d-)')
month = month_names[mon and mon:lower()]
if not (year and month and day and hour and min and sec) then return nil end
local ok, res = pcall(os.time,
{year=year, month=month, day=day, hour=hour, min=min, sec=sec})
return ok and res or nil
end
I send a last-modified date of: Wed, 12 Jan 2011 08:22:15 GMT
which I get from os.date('!%a, %d %b %Y %H:%M:%S GMT', 1294820535)
Firefox subsequently sends the same date in an If-Modified-Since
header, but the above code parses it to a timestamp 7 hours behind the
current time, which I assume must be because of os.time() assuming the
table is local time. The local timezone is actually -0600 but I guess
DST accounts for the extra hour. But Sean's code only gives the
correct offset if I remove the "if lmt.isdst" check...
(man, whose idea was it to use local, human-readable dates for HTTP? I
at least send out X-Unix-Time and X-Lastmodified-Unix headers, just a
shame the browsers don't do the same...)
--
Sent from my toaster.