Class: CATime::Resolution

Inherits:
Object
  • Object
show all
Defined in:
lib/carray/time.rb

Overview

A tick resolution: count ticks of a base unit. The human surface is a String ("3 hours" / "1 month"); a bare Symbol (:h) is the count-1 shorthand over the base-unit vocabulary. It names both a storage tick (= the grid a CATime is stored on) and a coarser bucket for the floor / timesteps family. Value object: frozen, value-equal, hashable.

Constant Summary collapse

WORDS =

Long / abbreviated unit words -> base unit symbol. Calendar words (ayear etc.) are intentionally dropped (standard calendar only).

{
  "year" => :Y, "years" => :Y, "yr" => :Y, "yrs" => :Y,
  "month" => :M, "months" => :M, "mon" => :M, "mons" => :M,
  "week" => :W, "weeks" => :W,
  "day" => :D, "days" => :D,
  "hour" => :h, "hours" => :h, "hr" => :h, "hrs" => :h,
  "minute" => :m, "minutes" => :m, "min" => :m, "mins" => :m,
  "second" => :s, "seconds" => :s, "sec" => :s, "secs" => :s,
  "millisecond" => :ms, "milliseconds" => :ms, "msec" => :ms, "msecs" => :ms,
  "microsecond" => :us, "microseconds" => :us, "usec" => :us, "usecs" => :us,
  "nanosecond" => :ns, "nanoseconds" => :ns,
  "picosecond" => :ps, "picoseconds" => :ps,
  "femtosecond" => :fs, "femtoseconds" => :fs,
  "attosecond" => :as, "attoseconds" => :as,
}.freeze
SYMBOLS =

Single-letter / short symbols accepted as the count-1 shorthand. These are the base-unit letters (case-sensitive: :m minute vs :M month).

%i[Y M W D h m s ms us ns ps fs as].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(count, base) ⇒ Resolution

Returns a new instance of Resolution.

Raises:

  • (ArgumentError)


1803
1804
1805
1806
1807
1808
1809
1810
1811
# File 'lib/carray/time.rb', line 1803

def initialize(count, base)
  raise ArgumentError, "unit count must be >= 1 (got #{count})" if count < 1
  # calendar (Y/M) bases are month-ordinal linear, so only integer
  # multiples are well-defined; a fractional multiple has no meaning.
  # (count is already Integer here; the guard documents the rule.)
  @count = count
  @base  = base
  freeze
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



1750
1751
1752
# File 'lib/carray/time.rb', line 1750

def base
  @base
end

#countObject (readonly)

Returns the value of attribute count.



1750
1751
1752
# File 'lib/carray/time.rb', line 1750

def count
  @count
end

Class Method Details

.parse(spec) ⇒ Resolution

Coerces spec into a CATime::Resolution: a Resolution passes through, a base unit Symbol becomes count 1, and a String such as "10 minutes" is parsed.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    when spec names no known unit.



1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
# File 'lib/carray/time.rb', line 1779

def self.parse(spec)
  case spec
  when Resolution then spec
  when Symbol
    unless SYMBOLS.include?(spec)
      raise ArgumentError, "invalid unit #{spec.inspect} " \
            "(one of #{SYMBOLS.map(&:inspect).join(', ')})"
    end
    new(1, spec)
  when String
    # Strict grammar: "<unit>" (count 1) or "<n> <unit>" (whitespace
    # required -- compact "3h" is rejected).
    m = spec.strip.match(/\A(?:(\d+)\s+)?([A-Za-z]+)\z/)
    unless m && WORDS.key?(m[2].downcase)
      raise ArgumentError, "invalid unit spec #{spec.inspect} " \
            "(use e.g. \"3 hours\" / \"1 month\", or a unit Symbol)"
    end
    new(m[1] ? Integer(m[1]) : 1, WORDS[m[2].downcase])
  else
    raise ArgumentError, "unit spec must be a String / Symbol / Resolution " \
          "(got #{spec.class})"
  end
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Returns whether other is the same count and base unit.

Returns:

  • (Boolean)

    whether other is the same count and base unit.



1819
# File 'lib/carray/time.rb', line 1819

def ==(other) = other.is_a?(Resolution) && other.count == count && other.base == base

#hashInteger

Returns a hash consistent with #==.

Returns:

  • (Integer)

    a hash consistent with #==.



1822
1823
# File 'lib/carray/time.rb', line 1822

def hash = [count, base].hash
# @return [String] e.g. `"h"` for a count of 1, `"10 minutes"` otherwise.

#inspectString

Returns:

  • (String)


1826
# File 'lib/carray/time.rb', line 1826

def inspect = "#<CATime::Resolution #{count} #{base}>"

#tick_ratioObject

seconds- (fixed base) or months- (calendar base) per tick (Rational).



1814
1815
1816
# File 'lib/carray/time.rb', line 1814

def tick_ratio
  count * CATimeUnitAlgebra.base_ratio(base)
end

#to_sString

Returns e.g. "h" for a count of 1, "10 minutes" otherwise.

Returns:

  • (String)

    e.g. "h" for a count of 1, "10 minutes" otherwise.



1824
1825
# File 'lib/carray/time.rb', line 1824

def to_s = count == 1 ? base.to_s : "#{count} #{base}"
# @return [String]