#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