Here's my effort. I didn't get around to testing it, but the concept seems sound. I decided to interpret the goal a little more conservatively and instead of just making sure the displayed time never goes forward, I decided to make sure the offset never goes backwards. To do this, I made the max delta from the current offset no more than the amount of time that passed since the last offset update: class FuzzyTime MAX_OFFSET = 5*60 def initialize(*args) now = Time.new @internal_time = args[0] || now @time_offset = now - @internal_time @fuzzy_secs = 0 @last_calc = Time.new end def actual @internal_time end def update @internal_time = Time.new + @time_offset end def advance(amount) @time_offset += amount.to_i end def calc_offset # Choose a new offset that's between +/- 5 mins. If it has been # less than 5 mins since the last offset calc, choose that time as # a max delta (this makes sure time is always going forward) time_from_last_calc = (Time.new - @last_calc).to_i if time_from_last_calc > 0 begin max_delta = [MAX_OFFSET, time_from_last_calc].min delta = rand((2*max_delta) + 1) - max_delta end until (delta + @fuzzy_secs).abs < MAX_OFFSET @fuzzy_secs += delta puts "Fuzzy secs now: #{@fuzzy_secs}" @last_calc = Time.new end @fuzzy_secs end def get_time fuzzy_hour = @internal_time.hour fuzzy_min = @internal_time.min fuzzy_sec = @internal_time.sec + calc_offset if fuzzy_sec > 60 fuzzy_sec -= 60 fuzzy_min += 1 end if fuzzy_sec < 0 fuzzy_sec += 60 fuzzy_min -= 1 end if fuzzy_min > 60 fuzzy_min -= 60 fuzzy_hour = (fuzzy_hour + 1) % 24 end if fuzzy_min < 0 fuzzy_min += 60 fuzzy_hour = (fuzzy_hour + 23) % 24 end [fuzzy_hour, fuzzy_min, fuzzy_sec] end def to_s fuzzy_hour, fuzzy_min, fuzzy_sec = get_time "#{fuzzy_hour}:#{fuzzy_min / 10}~" # "#{fuzzy_hour}:#{fuzzy_min / 10}~ (#{fuzzy_hour}:#{"%02d" % fuzzy_min}:#{"%02d" % fuzzy_sec})" end end if $0 == __FILE__ t = FuzzyTime.new 10.times do puts t, Time.new sleep 10 t.update end end