class Fugit::Duration
Constants
- KEYS
- NON_INFLA_KEYS
- SECOND_ROUND
Round float seconds to 9 decimals when deflating
Attributes
h[R]
options[R]
original[R]
Public Class Methods
common_rewrite_dur(t)
click to toggle source
# File lib/fugit/duration.rb, line 51 def common_rewrite_dur(t) t .subgather(nil) .inject({}) { |h, tt| v = tt.string; v = v.index('.') ? v.to_f : v.to_i # drops ending ("y", "m", ...) by itself h[tt.name] = (h[tt.name] || 0) + v h } end
do_parse(s, opts={})
click to toggle source
# File lib/fugit/duration.rb, line 41 def do_parse(s, opts={}) parse(s, opts) || fail(ArgumentError.new("not a duration #{s.inspect}")) end
new(s)
click to toggle source
# File lib/fugit/duration.rb, line 11 def new(s) parse(s) end
parse(s, opts={})
click to toggle source
# File lib/fugit/duration.rb, line 16 def parse(s, opts={}) return s if s.is_a?(self) original = s s = "#{s}s" if s.is_a?(Numeric) return nil unless s.is_a?(String) s = s.strip #p [ original, s ]; Raabro.pp(Parser.parse(s, debug: 3), colours: true) h = if opts[:iso] IsoParser.parse(opts[:stricter] ? s : s.upcase) elsif opts[:plain] Parser.parse(s) else Parser.parse(s) || IsoParser.parse(opts[:stricter] ? s : s.upcase) end h ? self.allocate.send(:init, original, opts, h) : nil end
to_iso_s(o)
click to toggle source
# File lib/fugit/duration.rb, line 48 def to_iso_s(o); do_parse(o).deflate.to_iso_s; end
to_long_s(o, opts={})
click to toggle source
# File lib/fugit/duration.rb, line 49 def to_long_s(o, opts={}); do_parse(o).deflate.to_long_s(opts); end
to_plain_s(o)
click to toggle source
# File lib/fugit/duration.rb, line 47 def to_plain_s(o); do_parse(o).deflate.to_plain_s; end
Public Instance Methods
==(o)
click to toggle source
# File lib/fugit/duration.rb, line 279 def ==(o) o.is_a?(Fugit::Duration) && o.h == @h end
Also aliased as: eql?
add(a)
click to toggle source
# File lib/fugit/duration.rb, line 253 def add(a) case a when Numeric then add_numeric(a) when Fugit::Duration then add_duration(a) when String then add_duration(self.class.parse(a)) when ::Time, EtOrbi::EoTime then add_to_time(a) else fail ArgumentError.new( "cannot add #{a.class} instance to a Fugit::Duration") end end
Also aliased as: +
add_duration(d)
click to toggle source
# File lib/fugit/duration.rb, line 214 def add_duration(d) params = d.h.inject(@h.dup) { |h, (k, v)| h[k] = (h[k] || 0) + v; h } self.class.allocate.init(nil, {}, params) end
add_numeric(n)
click to toggle source
# File lib/fugit/duration.rb, line 206 def add_numeric(n) h = @h.dup h[:sec] = (h[:sec] || 0) + n.to_i self.class.allocate.init(nil,{}, h) end
add_to_time(t)
click to toggle source
# File lib/fugit/duration.rb, line 221 def add_to_time(t) t = ::EtOrbi.make_time(t) INFLA_KEYS.each do |k, a| v = @h[k]; next unless v t = t + v * a[:s] end NON_INFLA_KEYS.each do |k, a| v = @h[k]; next unless v at = [ t.year, t.month, t.day, t.hour, t.min, t.sec ] at[a[:x]] += v if at[1] > 12 n, m = at[1] / 12, at[1] % 12 at[0], at[1] = at[0] + n, m elsif at[1] < 1 n, m = -at[1] / 12, -at[1] % 12 at[0], at[1] = at[0] - n, m end t = ::EtOrbi.make_time(at, t.zone) end t end
deflate(options={})
click to toggle source
# File lib/fugit/duration.rb, line 161 def deflate(options={}) id = inflate h = id.h.dup s = h.delete(:sec) || 0 keys = INFLA_KEYS mon = options[:month] yea = options[:year] keys = keys.dup if mon || yea if mon mon = 30 if mon == true mon = "#{mon}d" if mon.is_a?(Integer) keys.unshift([ :mon, { s: Fugit::Duration.parse(mon).to_sec } ]) end if yea yea = 365 if yea == true yea = "#{yea}d" if yea.is_a?(Integer) keys.unshift([ :yea, { s: Fugit::Duration.parse(yea).to_sec } ]) end keys[0..-2].each do |k, v| vs = v[:s]; next if s < vs h[k] = (h[k] || 0) + s.to_i / vs s = s % vs end h[:sec] = s.is_a?(Integer) ? s : s.round(SECOND_ROUND) self.class.allocate.init(@original, {}, h) end
drop_seconds()
click to toggle source
Returns a copy of this duration, omitting its seconds.
# File lib/fugit/duration.rb, line 297 def drop_seconds h = @h.dup h.delete(:sec) h[:min] = 0 if h.empty? self.class.allocate.init(nil, { literal: true }, h) end
hash()
click to toggle source
# File lib/fugit/duration.rb, line 285 def hash @h.hash end
inflate()
click to toggle source
# File lib/fugit/duration.rb, line 141 def inflate params = @h.inject({ sec: 0 }) { |h, (k, v)| a = KEYS[k] if a[:I] h[:sec] += (v * a[:s]) else h[k] = v end h } self.class.allocate.init(@original, {}, params) end
next_time(from=::EtOrbi::EoTime.now)
click to toggle source
# File lib/fugit/duration.rb, line 290 def next_time(from=::EtOrbi::EoTime.now) add(from) end
opposite()
click to toggle source
# File lib/fugit/duration.rb, line 197 def opposite params = @h.inject({}) { |h, (k, v)| h[k] = -v; h } self.class.allocate.init(nil, {}, params) end
Also aliased as: -@
subtract(a)
click to toggle source
# File lib/fugit/duration.rb, line 266 def subtract(a) case a when Numeric then add_numeric(-a) when Fugit::Duration then add_duration(-a) when String then add_duration(-self.class.parse(a)) when ::Time, ::EtOrbi::EoTime then add_to_time(a) else fail ArgumentError.new( "cannot subtract #{a.class} instance to a Fugit::Duration") end end
Also aliased as: -
to_h()
click to toggle source
For now, let's alias to h
# File lib/fugit/duration.rb, line 126 def to_h; h; end
to_iso_s()
click to toggle source
# File lib/fugit/duration.rb, line 88 def to_iso_s t = false s = StringIO.new s << 'P' KEYS.each_with_index do |(k, a), i| v = @h[k]; next unless v if i > 3 && t == false t = true s << 'T' end s << v.to_s; s << a[:i] end s.string end
to_long_s(opts={})
click to toggle source
# File lib/fugit/duration.rb, line 107 def to_long_s(opts={}) s = StringIO.new adn = [ false, 'no' ].include?(opts[:oxford]) ? ' and ' : ', and ' a = @h.to_a while kv = a.shift k, v = kv aa = KEYS[k] s << v.to_i s << ' '; s << aa[:l]; s << 's' if v > 1 s << (a.size == 1 ? adn : ', ') if a.size > 0 end s.string end
to_plain_s()
click to toggle source
# File lib/fugit/duration.rb, line 85 def to_plain_s; _to_s(:a); end
to_rufus_h()
click to toggle source
# File lib/fugit/duration.rb, line 128 def to_rufus_h KEYS.inject({}) { |h, (ks, kh)| v = @h[ks]; h[kh[:r].to_sym] = v if v; h } end
to_rufus_s()
click to toggle source
# File lib/fugit/duration.rb, line 86 def to_rufus_s; _to_s(:r); end
to_sec()
click to toggle source
Warning: this is an “approximation”, months are 30 days and years are 365 days, …
# File lib/fugit/duration.rb, line 136 def to_sec KEYS.inject(0) { |s, (k, a)| v = @h[k]; next s unless v; s += v * a[:s] } end
Protected Instance Methods
_to_s(key)
click to toggle source
# File lib/fugit/duration.rb, line 74 def _to_s(key) KEYS.inject([ StringIO.new, '+' ]) { |(s, sign), (k, a)| v = @h[k] next [ s, sign ] unless v sign1 = v < 0 ? '-' : '+' s << (sign1 != sign ? sign1 : '') << v.abs.to_s << a[key] [ s, sign1 ] }[0].string end
init(original, options, h)
click to toggle source
# File lib/fugit/duration.rb, line 308 def init(original, options, h) @original = original @options = options if options[:literal] @h = h else @h = h.reject { |k, v| v == 0 } @h[:sec] = 0 if @h.empty? end self end