From: daurnimator Date: Mon, 22 Jul 2013 21:48:55 +0000 (-0400) Subject: src/tzinfo: Add utctime function to convert local -> utc X-Git-Url: https://git.madduck.net/etc/awesome.git/commitdiff_plain/4cdcecedc224992d80f04f677e12bb79e9a91e55?ds=sidebyside;hp=fdc736b35e4525fffa01fc2f20403997f2626381 src/tzinfo: Add utctime function to convert local -> utc --- diff --git a/src/tzinfo.lua b/src/tzinfo.lua index d347e05..34b7048 100644 --- a/src/tzinfo.lua +++ b/src/tzinfo.lua @@ -17,6 +17,40 @@ local function _find_current ( tzinfo , target , i , j ) return _find_current ( tzinfo , target , i , half-1 ) end end + +local function find_current_local ( tzinfo , ts_local ) + -- Find two best possibilities by searching back and forward a day (assumes transition is never by more than 24 hours) + local tz_first = _find_current ( tzinfo , ts_local-86400 , 0 , #tzinfo ) + local tz_last = _find_current ( tzinfo , ts_local+86400 , 0 , #tzinfo ) + + local n_candidates = tz_last - tz_first + 1 + + if n_candidates == 1 then + return tz_first + elseif n_candidates == 2 then + local tz_first_ob = tzinfo [ tz_first ] + local tz_last_ob = tzinfo [ tz_last ] + + local first_gmtoffset = tz_first_ob.info.gmtoff + local last_gmtoffset = tz_last_ob .info.gmtoff + + local t_start = tz_last_ob.transition_time + first_gmtoffset + local t_end = tz_last_ob.transition_time + last_gmtoffset + + -- If timestamp is before start or after end + if ts_local < t_start then + return tz_first + elseif ts_local > t_end then + return tz_last + end + + -- If we get this far, the local time is ambiguous + return tz_first , tz_last + else + error ( "Too many transitions in a 2 day period" ) + end +end + function tz_info_methods:find_current ( current ) return self [ _find_current ( self , current , 0 , #self ) ].info end @@ -26,6 +60,18 @@ function tz_info_methods:localize ( utc_ts ) return utc_ts + self:find_current ( utc_ts ).gmtoff end +function tz_info_methods:utctime ( ts_local , is_dst ) + local tz1 , tz2 = find_current_local ( self , ts_local ) + tz1 = self [ tz1 ].info + if tz2 == nil then + return ts_local - tz1.gmtoff + else -- Local time is ambiguous + tz2 = self [ tz2 ].info + + return ts_local - tz2.gmtoff , ts_local - tz2.gmtoff + end +end + return { tz_info_mt = tz_info_mt ; }