Class: XfOOrth::Duration

Inherits:
Object show all
Extended by:
FormatEngine::AttrFormatter
Defined in:
lib/fOOrth/library/duration/make.rb,
lib/fOOrth/library/duration_library.rb,
lib/fOOrth/library/duration/formatter.rb,
lib/fOOrth/library/duration/intervals.rb,
lib/fOOrth/library/duration/arithmetic.rb

Overview

  • library/duration/arithmetic.rb - Arithmetic operator support for durations.

Constant Summary collapse

A_SECOND =

Seconds in a second.

Duration.new(1.to_r)
A_MINUTE =

Seconds in a minute.

Duration.new(60 * A_SECOND.to_r)
AN_HOUR =

Seconds in an hour.

Duration.new(60 * A_MINUTE.to_r)
A_DAY =

Seconds in a day.

Duration.new(24 * AN_HOUR.to_r)
A_MONTH =

Seconds in a (average) month.

Duration.new(Rational(365_2425, 120000) * A_DAY.to_r)
A_YEAR =

Seconds in a (average) year.

Duration.new(12 * A_MONTH.to_r)
INTERVALS =

An array of interval values.

[A_YEAR, A_MONTH, A_DAY, AN_HOUR, A_MINUTE, A_SECOND]
LABELS =

An array of interval labels.

["years", "months", "days", "hours", "minutes", "seconds"]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(period) ⇒ Duration

Create a duration instance.
Parameters

  • period - The period of time of the duration.



14
15
16
# File 'lib/fOOrth/library/duration/make.rb', line 14

def initialize(period)
  @period = period.rationalize
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

Pass off all unknown methods to the period data.



37
38
39
# File 'lib/fOOrth/library/duration_library.rb', line 37

def method_missing(symbol, *args, &block)
  @period.send(symbol, *args, &block)
end

Instance Attribute Details

#periodObject

The length of time of the duration.



9
10
11
# File 'lib/fOOrth/library/duration/make.rb', line 9

def period
  @period
end

Class Method Details

.pick_label(index, qty = 1) ⇒ Object

Pick the appropriate label
Endemic Code Smells

  • :reek:ControlParameter



36
37
38
39
40
# File 'lib/fOOrth/library/duration/intervals.rb', line 36

def self.pick_label(index, qty=1)
  result = LABELS[index]
  result = result.chop if qty == 1
  " " + result
end

Instance Method Details

#as_daysObject

How many total days in this duration?



75
76
77
# File 'lib/fOOrth/library/duration/intervals.rb', line 75

def as_days
  (@period/A_DAY.to_r).to_f
end

#as_hoursObject

How many total hours in this duration?



86
87
88
# File 'lib/fOOrth/library/duration/intervals.rb', line 86

def as_hours
  (@period/AN_HOUR.to_r).to_f
end

#as_minutesObject

How many total minutes in this duration?



97
98
99
# File 'lib/fOOrth/library/duration/intervals.rb', line 97

def as_minutes
  (@period/A_MINUTE.to_r).to_f
end

#as_monthsObject

How many total months in this duration?



64
65
66
# File 'lib/fOOrth/library/duration/intervals.rb', line 64

def as_months
  (@period/A_MONTH.to_r).to_f
end

#as_secondsObject

How many total seconds in this duration?



108
109
110
# File 'lib/fOOrth/library/duration/intervals.rb', line 108

def as_seconds
  @period.to_f
end

#as_yearsObject

How many total years in this duration?



53
54
55
# File 'lib/fOOrth/library/duration/intervals.rb', line 53

def as_years
  (@period/A_YEAR.to_r).to_f
end

#daysObject

How many days into the month in this duration?



70
71
72
# File 'lib/fOOrth/library/duration/intervals.rb', line 70

def days
  ((@period % A_MONTH.to_r)/A_DAY.to_r).to_i
end

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

Define equality for durations.

Returns:

  • (Boolean)


26
27
28
# File 'lib/fOOrth/library/duration/arithmetic.rb', line 26

def eql?(other)
  @period.eql?(other.to_foorth_r)
end

#foorth_coerce(arg) ⇒ Object

Coerce the argument to match my type.



10
11
12
# File 'lib/fOOrth/library/duration/arithmetic.rb', line 10

def foorth_coerce(arg)
  @period.foorth_coerce(arg)
end

#hoursObject

How many hours into the day in this duration?



81
82
83
# File 'lib/fOOrth/library/duration/intervals.rb', line 81

def hours
  (((@period % A_MONTH.to_r) % A_DAY.to_r)/AN_HOUR.to_r).to_i
end

#largest_intervalObject

Find the largest interval for this duration



43
44
45
# File 'lib/fOOrth/library/duration/intervals.rb', line 43

def largest_interval
  (0..5).detect {|idx| INTERVALS[idx] <= period} || 5
end

#minutesObject

How many minutes into the hour in this duration?



92
93
94
# File 'lib/fOOrth/library/duration/intervals.rb', line 92

def minutes
  (((@period % A_MONTH.to_r) % AN_HOUR.to_r)/A_MINUTE.to_r).to_i
end

#monthsObject

How many months into the year in this duration?



59
60
61
# File 'lib/fOOrth/library/duration/intervals.rb', line 59

def months
  ((@period % A_YEAR.to_r)/A_MONTH.to_r).to_i
end

#secondsObject

How many seconds into the minute in this duration?



103
104
105
# File 'lib/fOOrth/library/duration/intervals.rb', line 103

def seconds
  ((@period % A_MONTH.to_r) % A_MINUTE.to_f)
end

#strfmtObject

The specification of the formatter method of the Duration class.
Year Formats:

  • %?$wy - Whole years.

  • %?$XfOOrth::Duration.w{w{.p}Y - Total (with fractional) years.


Month Formats:

  • %?$wo - Whole months in the year.

  • %?$XfOOrth::Duration.w{w{.p}O - Total (with fractional) months.


Day Formats:

  • %?$wd - Whole days in the month.

  • %?$XfOOrth::Duration.w{w{.p}D - Total (with fractional) days.


Hour Formats:

  • %?$wh - Whole hours in the day.

  • %?$XfOOrth::Duration.w{w{.p}H - Total (with fractional) hours.


Minute Formats:

  • %?$wm - Whole minutes in the hour.

  • %?$XfOOrth::Duration.w{w{.p}M - Total (with fractional) minutes.


Second Formats:

  • %?$XfOOrth::Duration.w{w{.p}s - Total (with fractional) seconds in the minute.

  • %?$XfOOrth::Duration.w{w{.p}S - Total (with fractional) seconds.


Brief Summary Formats:

  • %?$XfOOrth::Duration.w{w{.p}B - Total (with fractional) of the largest, non-zero time unit.


Raw Formats (in seconds and fractions):

  • %XfOOrth::Duration.w{w{.p}f - Total seconds in floating point format.

  • %wr - Total seconds in rational format.


Where:

  • ? is an optional flag indicating that the data should be suppressed if absent.

  • $ is an optional flag indication to retrieve the corresponding text label.

  • w is an optional field width parameter.

  • p is an optional precision parameter.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/fOOrth/library/duration/formatter.rb', line 43

attr_formatter :strfmt,
{
  :before => lambda do
    tmp[:all]   = arr = src.to_a
    tmp[:year]  = arr[0]; tmp[0] = src.as_years
    tmp[:month] = arr[1]; tmp[1] = src.as_months
    tmp[:day]   = arr[2]; tmp[2] = src.as_days
    tmp[:hour]  = arr[3]; tmp[3] = src.as_hours
    tmp[:min]   = arr[4]; tmp[4] = src.as_minutes
    tmp[:sec]   = arr[5]; tmp[5] = src.as_seconds
  end,

  "%y"  => lambda {cat "%#{fmt.parm_str}d" % tmp[:year]},
  "%?y" => lambda {cat "%#{fmt.parm_str}d" % tmp[:year] if tmp[:year] >= 1},
  "%Y"  => lambda {cat "%#{fmt.parm_str}f" % tmp[0]},
  "%?Y" => lambda {cat "%#{fmt.parm_str}f" % tmp[0] if tmp[0] > 0},

  "%$y" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[:year])},
  "%?$y"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[:year]) if tmp[:year] >= 1},
  "%$Y" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[0])},
  "%?$Y"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[0]) if tmp[0] > 0},

  "%o"  => lambda {cat "%#{fmt.parm_str}d" % tmp[:month]},
  "%?o" => lambda {cat "%#{fmt.parm_str}d" % tmp[:month] if tmp[:month] >= 1},
  "%O"  => lambda {cat "%#{fmt.parm_str}f" % tmp[1]},
  "%?O" => lambda {cat "%#{fmt.parm_str}f" % tmp[1] if tmp[1] > 0},

  "%$o" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[:month])},
  "%?$o"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[:month]) if tmp[:month] >= 1},
  "%$O" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[1])},
  "%?$O"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[1]) if tmp[1] > 0},

  "%d"  => lambda {cat "%#{fmt.parm_str}d" % tmp[:day]},
  "%?d" => lambda {cat "%#{fmt.parm_str}d" % tmp[:day] if tmp[:day] >= 1},
  "%D"  => lambda {cat "%#{fmt.parm_str}f" % tmp[2]},
  "%?D" => lambda {cat "%#{fmt.parm_str}f" % tmp[2] if tmp[2] > 0},

  "%$d" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[:day])},
  "%?$d"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[:day]) if tmp[:day] >= 1},
  "%$D" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[2])},
  "%?$D"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[2]) if tmp[2] > 0},

  "%h"  => lambda {cat "%#{fmt.parm_str}d" % tmp[:hour]},
  "%?h" => lambda {cat "%#{fmt.parm_str}d" % tmp[:hour] if tmp[:hour] >= 1},
  "%H"  => lambda {cat "%#{fmt.parm_str}f" % tmp[3]},
  "%?H" => lambda {cat "%#{fmt.parm_str}f" % tmp[3] if tmp[3] > 0},

  "%$h" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[:hour])},
  "%?$h"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[:hour]) if tmp[:hour] >= 1},
  "%$H" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[3])},
  "%?$H"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[3]) if tmp[3] > 0},

  "%m"  => lambda {cat "%#{fmt.parm_str}d" % tmp[:min]},
  "%?m" => lambda {cat "%#{fmt.parm_str}d" % tmp[:min] if tmp[:min] >= 1},
  "%M"  => lambda {cat "%#{fmt.parm_str}f" % tmp[4]},
  "%?M" => lambda {cat "%#{fmt.parm_str}f" % tmp[4] if tmp[4] > 0},

  "%$m" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[:min])},
  "%?$m"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[:min]) if tmp[:min] >= 1},
  "%$M" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[4])},
  "%?$M"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[4]) if tmp[4] > 0},

  "%s"  => lambda {cat "%#{fmt.parm_str}f" % tmp[:sec]},
  "%?s" => lambda {cat "%#{fmt.parm_str}f" % tmp[:sec] if tmp[:sec] >= 1},
  "%S"  => lambda {cat "%#{fmt.parm_str}f" % tmp[5]},
  "%?S" => lambda {cat "%#{fmt.parm_str}f" % tmp[5] if tmp[5] > 0},

  "%$s" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[:sec])},
  "%?$s"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[:sec]) if tmp[:sec] >= 1},
  "%$S" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[5])},
  "%?$S"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[5]) if tmp[5] > 0},

  "%B"  => lambda {cat "%#{fmt.parm_str}f" % tmp[src.largest_interval]},
  "%?B" => lambda {cat "%#{fmt.parm_str}f" % tmp[src.largest_interval] if src.period > 0},

  "%$B" => lambda do
    index = src.largest_interval
    cat "%#{fmt.parm_str}s" % Duration.pick_label(index, tmp[index])
  end,
  "%?$B" => lambda do
    if src.period > 0
      index = src.largest_interval
      cat "%#{fmt.parm_str}s" % Duration.pick_label(index, tmp[index])
    end
  end,


  "%f"  => lambda {cat "%#{fmt.parm_str}f" % src.period.to_f},
  "%r"  => lambda {cat "%#{fmt.parm_str}s" % src.period.to_s}
}

#to_aObject

Convert this duration to an array.
Endemic Code Smells

  • :reek:FeatureEnvy – false positive.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/fOOrth/library/duration_library.rb', line 19

def to_a
  balance = @period

  Duration::INTERVALS.map do |item|
    interval = item.to_r

    if interval > 1
      value = (balance / interval).to_i
      balance -= value * interval
      value
    else
      balance.to_f
    end
  end

end

#to_rObject Also known as: rationalize, to_foorth_r

Convert this duration to a rational number.



15
16
17
# File 'lib/fOOrth/library/duration/arithmetic.rb', line 15

def to_r
  @period
end

#yearsObject

How many whole years in this duration?



48
49
50
# File 'lib/fOOrth/library/duration/intervals.rb', line 48

def years
  (@period/A_YEAR.to_r).to_i
end