#TimeRange ruby class developed by Alvise Susmel (alvise@gecosoftware.com) #GecoSoftware.com # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 3 of the License, or #(at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program. If not, see . require 'time' require 'date' class TimeRangeArray @ranges #inizializza controllando che il valore passato sia un array #di TimeRange def initialize(ranges=nil) @ranges = [] if ranges.class == Array ranges.each do |r| if r.class==TimeRange @ranges << r end end end #gli oggetti vengono ordinati per "ftime" crescenti @ranges.sort!{|a,b| a.ftime <=> b.ftime} return self end ########## Metodi per ricevere i valori ################## def ranges return @ranges end def to_s final= "" ranges.each do |r| final += "#{r}\n#{r.object.class}\n--------\n" end final += "#{@ranges.size} ranges\n" return final end #true o false #dice se il range passato e` in fullin con #almeno un range del TimeRangeArray def fullin?(range) @ranges.each do |r| if r.fullin?(range) return true end end return false end #dice se il range passato e` in intersection (comprende anche fullin) con #almeno un range del TimeRangeArray def intersection?(range) @ranges.each do |r| if r.intersection?(range) return true end end return false end def order_by_ftime! @ranges.sort!{|a,b| a.ftime <=> b.ftime} return self end def order_by_ttime! @ranges.sort!{|a,b| a.ttime <=> b.ttime} return self end def flatten! @ranges.flatten! return self end def add(value) if value.class == TimeRange @ranges << value elsif value.class == TimeRangeArray value.ranges.each do |r| self.add(r) end end end #aggiunge e poi ordina def add!(value) if value.class == TimeRange @ranges << value elsif value.class == TimeRangeArray value.ranges.each do |r| self.add(r) end end order_by_ftime! end #toglie i range puntiformi cioe` ftime=ttime def purge final = [] @ranges.each do |r| if r.ftime < r.ttime final << r end end return TimeRangeArray.new(final) end #toglie i range puntiformi e aggiorna l'oggetto def purge! final = [] @ranges.each do |r| if r.ftime < r.ttime final <= b.ftime and a.ftime <= b.ttime and a.ttime >= b.ttime) end def intersection_bottom?(b) a=self return (b.ftime <= a.ttime and b.ftime >= a.ftime and b.ttime >= a.ttime) end ############################################################## ############ Metodi per impostare i valori ################ def set_ftime(ftime) @ftime = ftime end def set_ttime(ttime) @ttime = ttime end def set_ftime_local(fyear,fmonth,fday,fhour,fminute,fsecond=0) @ftime = Time.local(fyear,fmonth,fday,fhour,fminute,fsecond) end def set_ttime_local(tyear,tmonth,tday,thour,tminute,tsecond) @ttime = Time.local(tyear,tmonth,tday,thour,tminute,tsecond) end def set_object(object) @object = object end ############################################################ ############## Operazioni ################## #permette unire due oggetti TimeRange ottenendo un oggetto TimeRangeArray #Se i due range sono staccati allora si avranno un oggetto TimeRangeArray con due oggetti TimeRange #Se i due range sono vicini allora si otterra` un unico oggetto TimeRange. #Nell'oggetto TimeRange, nel caso di bottom o top intersection come object ci sara` un array di oggetti #si sa che ftime <= ttime per definizione def +(range) a = self b = range #caso Bottom intersection if a.intersection_bottom?(b) return TimeRangeArray.new([TimeRange.new(@ftime,range.ttime,[@object,range.object])]) #caso Top instersection elsif a.intersection_top?(b) return TimeRangeArray.new([TimeRange.new(b.ftime,a.ttime,[a.object,b.object])]) #caso Full-in master elsif a.fullin_master?(b) return TimeRangeArray.new([a]) #caso Full-in slave elsif a.fullin_slave?(b) return TimeRangeArray.new([b]) #caso Equal elsif a == b return TimeRangeArray.new([TimeRange.new(a.ftime,a.ttime,[a.object,b.object])]) #caso Full-out elsif a.fullout?(b) return TimeRangeArray.new([a,b]) else return TimeRangeArray.new([]) end end #Permette di andare a togliere dei range all' interno di un range #Se il minuendo ed il sottraendo sono range diversi allora ritorna un oggetto TimeRangeArray con un elemento TimeRange #corrispondente al minuendo. #Se il minuendo ingloba il sottraendo allora si formeranno due TimeRange all' interno di un oggetto TimeRangeArray def -(b) a=self if a.intersection_bottom?(b) return TimeRangeArray.new([TimeRange.new(a.ftime,b.ftime,[a,b])]) elsif a.intersection_top?(b) return TimeRangeArray.new([TimeRange.new(b.ttime,a.ttime,[a,b])]) elsif a.fullin_master?(b) return TimeRangeArray.new([TimeRange.new(a.ftime,b.ftime,[a,b]),TimeRange.new(b.ttime,a.ttime,[a,b])]) elsif a.fullin_slave?(b) or a==b return TimeRangeArray.new elsif a.fullout?(b) return TimeRangeArray.new([TimeRange.new(a.ftime,a.ttime,[a,b])]) end end #Permette ottenere i range che vengono tolti dalla differenza a-b def comp(b) a=self if a.intersection_bottom?(b) return TimeRangeArray.new([TimeRange.new(b.ftime,a.ttime,[a,b])]) elsif a.intersection_top?(b) return TimeRangeArray.new([TimeRange.new(a.ftime,b.ttime,[a,b])]) elsif a.fullin_master?(b) return TimeRangeArray.new([TimeRange.new(b.ftime,b.ttime,[a,b])]) elsif a.fullin_slave?(b) or a==b return TimeRangeArray.new([TimeRange.new(a.ftime,a.ttime,[a,b])]) elsif a.fullout?(b) return TimeRangeArray.new end end def ==(range) a = self b = range return (a.ftime==b.ftime and a.ttime==b.ttime) end #Ritorna true se a.ftime < b.ftime def <(b) a=self return (a.ftime < b.ftime) end #Ritorna true se a.ftime <= b.ftime def <=(b) a=self return (a.ftime <= b.ftime) end #Ritorna true se a.ftime > b.ftime def >(b) a=self return (a.ttime > b.ttime) end #Ritorna true se a.ftime >= b.ftime def >=(b) a=self return (a.ftime >= b.ftime) end end