Module: Humane
- Defined in:
- lib/humane.rb,
lib/humane/size.rb,
lib/humane/time.rb,
lib/humane/version.rb
Constant Summary collapse
- UNITS =
%w[KB MB GB TB PB EB].freeze
- VERSION =
"0.9.3"
Class Method Summary collapse
-
.distance_in_time(at, relative_to, approximate: true, include_seconds: false, when_nil: nil) ⇒ Object
Formats one time relative to another the way ActionView's distance_of_time_in_words does for wording, but direction-aware like RelativeDateTimeFormatter -- "X ago"/"in X", chosen automatically rather than requiring the caller to know which applies ahead of time.
-
.human_size(byte_count) ⇒ Object
Returns byte_count as a Finder-style human-readable string.
-
.time_ago(at, **opts) ⇒ Object
Returns at relative to the current time -- a convenience for the common "drop into a view" case, modeled on ActionView's time_ago_in_words wrapping distance_of_time_in_words with Time.now.
Class Method Details
.distance_in_time(at, relative_to, approximate: true, include_seconds: false, when_nil: nil) ⇒ Object
Formats one time relative to another the way ActionView's distance_of_time_in_words does for wording, but direction-aware like RelativeDateTimeFormatter -- "X ago"/"in X", chosen automatically rather than requiring the caller to know which applies ahead of time. This is the explicit, fully-tested core -- see .time_ago below for the one-argument convenience. See docs/COMMENTS.md.
Humane.distance_in_time(Time.now - 180, Time.now) #=> "3 minutes ago"
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/humane/time.rb', line 12 def self.distance_in_time(at, relative_to, approximate: true, include_seconds: false, when_nil: nil) return when_nil if at.nil? seconds = relative_to - at future = seconds.negative? seconds = seconds.abs if !include_seconds && seconds < 30 return future ? "in less than a minute" : "less than a minute ago" end if include_seconds && seconds < 60 return wrap(pluralize(seconds.to_i, "second"), future: future) end # Buckets come from distance_in_minutes, not raw seconds re-divided per unit -- see docs/COMMENTS.md. distance_in_minutes = (seconds / 60.0).round text, approximable = case distance_in_minutes when 1 then ["1 minute", false] when 2..44 then [pluralize(distance_in_minutes, "minute"), false] when 45..89 then ["1 hour", true] when 90..1439 then [pluralize((distance_in_minutes / 60.0).round, "hour"), true] when 1440..2519 then ["1 day", false] else [pluralize((distance_in_minutes / 1440.0).round, "day"), false] end text = "about #{text}" if approximate && approximable wrap(text, future: future) end |
.human_size(byte_count) ⇒ Object
Returns byte_count as a Finder-style human-readable string.
Humane.human_size(225_935) #=> "226 KB"
9 10 11 12 13 14 15 16 17 |
# File 'lib/humane/size.rb', line 9 def self.human_size(byte_count) return "Zero KB" if byte_count.zero? return (byte_count == 1) ? "1 byte" : "#{byte_count} bytes" if byte_count < 1000 exponent = [(Math.log(byte_count) / Math.log(1000)).to_i, UNITS.size].min value = byte_count / (1000.0**exponent) "#{format_significant(value, 3)} #{UNITS[exponent - 1]}" end |
.time_ago(at, **opts) ⇒ Object
Returns at relative to the current time -- a convenience for the common "drop into a view" case, modeled on ActionView's time_ago_in_words wrapping distance_of_time_in_words with Time.now. Use .distance_in_time directly when the reference time needs to be explicit (tests, a fixed point other than now).
Humane.time_ago(Time.now - 180) #=> "3 minutes ago"
51 52 53 |
# File 'lib/humane/time.rb', line 51 def self.time_ago(at, **opts) distance_in_time(at, Time.now, **opts) end |