X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/abb29b0b113102a7dea3e4691a853ee20e30f614..6db06b57e851ec08d5355f015d6df1ebe58b4982:/src/timetable.lua?ds=inline diff --git a/src/timetable.lua b/src/timetable.lua index b58ad0f..d1cd534 100644 --- a/src/timetable.lua +++ b/src/timetable.lua @@ -1,3 +1,4 @@ +local strformat = string.format local floor = math.floor local function idiv ( n , d ) return floor ( n / d ) @@ -20,6 +21,7 @@ local function year_length ( y ) end local function month_length ( m , y ) + m = ( m - 1 ) % 12 + 1 if m == 2 then return is_leap ( y ) and 29 or 28 else @@ -73,7 +75,9 @@ local function unpack_tm ( tm ) assert ( tm.day , "day required" ) , tm.hour or 12 , tm.min or 0 , - tm.sec or 0 + tm.sec or 0 , + tm.yday , + tm.wday end -- Modify parameters so they all fit within the "normal" range @@ -102,12 +106,16 @@ local function normalise ( year , month , day , hour , min , sec ) return year , month , day , hour , min , sec end +local leap_years_since_1970 = leap_years_since ( 1970 ) local function timestamp ( year , month , day , hour , min , sec ) - return 60*60*24*( - year * year_length ( year ) - + month * month_length ( month , year ) - + day - ) + year , month , day , hour , min , sec = normalise ( year , month , day , hour , min , sec ) + + local days_since_epoch = day_of_year ( day , month , year ) + + 365 * ( year - 1970 ) + -- Each leap year adds one day + + ( leap_years_since ( year - 1 ) - leap_years_since_1970 ) - 1 + + return days_since_epoch * (60*60*24) + hour * (60*60) + min * 60 + sec @@ -143,11 +151,23 @@ function timetable_methods:rfc_3339 ( ) return strformat ( "%04u-%02u-%02uT%02u:%02u:%06.4g" , unpack_tm ( self ) ) end -local timetable_mt = { +local timetable_mt + +local function coerce_arg ( t ) + if getmetatable ( t ) == timetable_mt then + return t:timestamp ( ) + end + return t +end + +timetable_mt = { __index = timetable_methods ; __tostring = timetable_methods.rfc_3339 ; __eq = function ( a , b ) - return a:timestamp() < b:timestamp() + return coerce_arg ( a ) == coerce_arg ( b ) + end ; + __lt = function ( a , b ) + return coerce_arg ( a ) < coerce_arg ( b ) end ; } @@ -155,7 +175,7 @@ local function cast_timetable ( tm ) return setmetatable ( tm , timetable_mt ) end -local function new_timetable ( year , month , day , hour , min , sec ) +local function new_timetable ( year , month , day , hour , min , sec , yday , wday ) return cast_timetable { year = year ; month = month ; @@ -163,15 +183,26 @@ local function new_timetable ( year , month , day , hour , min , sec ) hour = hour ; min = min ; sec = sec ; + yday = yday ; + wday = wday ; } end +function timetable_methods:clone ( ) + return new_timetable ( unpack_tm ( self ) ) +end + +local function new_from_timestamp ( ts ) + return new_timetable ( 1970 , 1 , 1 , 0 , 0 , ts ) +end + return { doomsday = doomsday ; normalise = normalise ; timestamp = timestamp ; new = new_timetable ; + new_from_timestamp = new_from_timestamp ; cast = cast_timetable ; timetable_mt = timetable_mt ; }