webmcp
diff libraries/atom/atom.lua @ 106:bbfbbddf13ad
Support for intervals
author | jbe |
---|---|
date | Sun Nov 04 04:55:22 2012 +0100 (2012-11-04) |
parents | bdebade717d3 |
children | 6b435d3c0b14 |
line diff
1.1 --- a/libraries/atom/atom.lua Sun Nov 04 04:54:54 2012 +0100 1.2 +++ b/libraries/atom/atom.lua Sun Nov 04 04:55:22 2012 +0100 1.3 @@ -1015,7 +1015,7 @@ 1.4 error("Left operand of '-' operator has wrong type.") 1.5 end 1.6 if getmetatable(value2) == date then 1.7 - return value1.jd - value2.jd -- TODO: transform to interval 1.8 + return value1.jd - value2.jd 1.9 elseif type(value2) == "number" then 1.10 return date(value1.jd - value2) 1.11 else 1.12 @@ -1299,7 +1299,7 @@ 1.13 error("Left operand of '-' operator has wrong type.") 1.14 end 1.15 if getmetatable(value2) == timestamp then 1.16 - return value1.tsec - value2.tsec -- TODO: transform to interval 1.17 + return value1.tsec - value2.tsec 1.18 elseif type(value2) == "number" then 1.19 return timestamp(value1.tsec - value2) 1.20 else 1.21 @@ -1508,7 +1508,7 @@ 1.22 error("Left operand of '-' operator has wrong type.") 1.23 end 1.24 if getmetatable(value2) == time then 1.25 - return value1.dsec - value2.dsec -- TODO: transform to interval 1.26 + return value1.dsec - value2.dsec 1.27 elseif type(value2) == "number" then 1.28 return time((value1.dsec - value2) % 86400) 1.29 else 1.30 @@ -1539,4 +1539,154 @@ 1.31 1.32 1.33 1.34 +-------------- 1.35 +-- interval -- 1.36 +-------------- 1.37 + 1.38 +interval = create_new_type("interval") 1.39 + 1.40 +--[[-- 1.41 +atom.interval.invalid 1.42 + 1.43 +Value representing an invalid interval. 1.44 + 1.45 +--]]-- 1.46 +interval.invalid = interval:_create{ 1.47 + years = not_a_number, months = not_a_number, days = not_a_number, 1.48 + hours = not_a_number, minutes = not_a_number, seconds = not_a_number, 1.49 + hms_seconds = not_a_number, 1.50 + invalid = true 1.51 +} 1.52 +--//-- 1.53 + 1.54 +--[[-- 1.55 +t = -- time based on given data 1.56 +atom.interval:new{ 1.57 + years = years, 1.58 + months = months, 1.59 + days = days, 1.60 + hours = hours, 1.61 + minutes = minutes, 1.62 + seconds = seconds 1.63 +} 1.64 + 1.65 +This method returns a new time value, based on given data. 1.66 + 1.67 +--]]-- 1.68 +function interval:new(args) 1.69 + local args = args 1.70 + if type(args) == "number" then args = { seconds = args } end 1.71 + if type(args) == "table" then 1.72 + if 1.73 + (type(args.years) == "number" or not args.years ) and 1.74 + (type(args.months) == "number" or not args.months ) and 1.75 + (type(args.days) == "number" or not args.days ) and 1.76 + (type(args.hours) == "number" or not args.hours ) and 1.77 + (type(args.minutes) == "number" or not args.minutes) and 1.78 + (type(args.seconds) == "number" or not args.seconds) 1.79 + then 1.80 + local years = args.years and tonumber(args.years) or 0 1.81 + local months = args.months and tonumber(args.months) or 0 1.82 + local days = args.days and tonumber(args.days) or 0 1.83 + local hours = args.hours and tonumber(args.hours) or 0 1.84 + local minutes = args.minutes and tonumber(args.minutes) or 0 1.85 + local seconds = args.seconds and tonumber(args.seconds) or 0 1.86 + if not ( 1.87 + is_integer(years) and is_integer(months) and is_integer(days) and 1.88 + is_integer(hours) and is_integer(minutes) and is_integer(seconds) 1.89 + ) then 1.90 + return interval.invalid 1.91 + end 1.92 + local hms_seconds = 3600 * hours + 60 * minutes + seconds 1.93 + if not is_integer(hms_seconds) then return interval.invalid end 1.94 + local hms_negative = false 1.95 + if hms_seconds < 0 then 1.96 + hms_negative = true 1.97 + hms_seconds = -hms_seconds 1.98 + if not is_integer(hms_seconds) then return interval.invalid end 1.99 + end 1.100 + hours = math.floor(hms_seconds / 3600) 1.101 + minutes = math.floor(hms_seconds / 60) % 60 1.102 + seconds = hms_seconds % 60 1.103 + if hms_negative then 1.104 + hours = -hours 1.105 + minutes = -minutes 1.106 + seconds = -seconds 1.107 + hms_seconds = -hms_seconds 1.108 + end 1.109 + return interval:_create{ 1.110 + years = years, months = months, days = days, 1.111 + hours = hours, minutes = minutes, seconds = seconds, 1.112 + hms_seconds = hms_seconds, 1.113 + } 1.114 + end 1.115 + end 1.116 + error("Invalid arguments passed to interval constructor.") 1.117 +end 1.118 +--//-- 1.119 + 1.120 +--[[-- 1.121 +t = -- interval represented by the string 1.122 +atom.interval:load( 1.123 + string -- string representing an interval 1.124 +) 1.125 + 1.126 +This method returns an interval represented by the given string. 1.127 + 1.128 +--]]-- 1.129 +function interval:load(str) 1.130 + if str == nil or str == "" then 1.131 + return nil 1.132 + elseif type(str) ~= "string" then 1.133 + error("String expected") 1.134 + else 1.135 + local years, months, days, hours, minutes, seconds = string.match( 1.136 + str, 1.137 + "^(%-?[0-9]+) years (%-?[0-9]+) months (%-?[0-9]+) days (%-?[0-9]+) hours (%-?[0-9]+) minutes (%-?[0-9]+) seconds$" 1.138 + ) 1.139 + return interval:new{ 1.140 + years = tonumber(years), 1.141 + months = tonumber(months), 1.142 + days = tonumber(days), 1.143 + hours = tonumber(hours), 1.144 + minutes = tonumber(minutes), 1.145 + seconds = tonumber(seconds) 1.146 + } 1.147 + end 1.148 +end 1.149 +--//-- 1.150 + 1.151 +function interval:__tostring() 1.152 + if self.invalid then 1.153 + return "invalid_interval" 1.154 + else 1.155 + return string.format( 1.156 + "%i years %i months %i days %i hours %i minutes %i seconds", 1.157 + self.years, self.months, self.days, self.hours, self.minutes, self.seconds 1.158 + ) 1.159 + end 1.160 +end 1.161 + 1.162 +function interval.__eq(value1, value2) 1.163 + if value1.invalid or value2.invalid then 1.164 + return false 1.165 + else 1.166 + return ( 1.167 + value1.years == value2.years and 1.168 + value1.months == value2.months and 1.169 + value1.days == value2.days and 1.170 + value1.hms_seconds == value2.hms_seconds 1.171 + ) 1.172 + end 1.173 +end 1.174 + 1.175 +function interval:__unm() 1.176 + return self.new{ 1.177 + years = -self.years, months = -self.months, days = -self.days, 1.178 + hours = -self.hours, minutes = -self.minutes, seconds = -self.seconds 1.179 + } 1.180 +end 1.181 + 1.182 + 1.183 + 1.184 return _M