123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- module Ago
- module VERSION
- MAJOR = 0
- MINOR = 1
- TINY = 5
- class << self
- def pretty
- "#{MAJOR}.#{MINOR}.#{TINY}"
- end
- alias_method :print, :pretty
- end
- end
- Ago::Order = [:year, :month, :week, :day, :hour, :minute, :second]
- Ago::Units = {
- :year => {
- :basic => 60 * 60 * 24 * 365,
- :gregorian => 86400 * 365.2425,
- },
- :month => {
- :basic => 60 * 60 * 24 * 30,
- :gregorian => 86400 * 30.436875,
- },
- :week => {
- :basic => 60 * 60 * 24 * 7,
- :gregorian => 86400 * 7.02389423076923,
- },
- :day => {
- :basic => 60 * 60 * 24
- },
- :hour => {
- :basic => 60 * 60
- },
- :minute => {
- :basic => 60
- },
- :second => {
- :basic => 1
- }
- }
- def Ago.calendar_check(calendar)
- error = ":calendar => value must be either :basic or :gregorian."
- unless calendar == :basic || calendar == :gregorian
- raise ArgumentError, error
- end
- end
- module Ago::TimeAgo
- # Generate List of valid unit :symbols
- valids = ""
- Ago::Order.each do |u|
- unless u == :second
- valids += ":#{u.to_s}, "
- else
- valids += "and :#{u.to_s}."
- end
- end
- Valids = valids
- def ago_in_words(opts={})
- # Process options {hash}
- focus = opts[:focus] ? opts[:focus] : 0
- start_at = opts[:start_at] ? opts[:start_at] : :year
- now = opts[:now] ? opts[:now] : Time.now
- in_time = opts[:in_time] ? opts[:in_time] : :past
- calendar = opts[:calendar] ? opts[:calendar] : :basic
- # Filter out invalid arguments for :in_time
- in_time_error = ":in_time => value must be either :past or :future, " \
- + "depending on whether the Time object is before or after Time.now."
- unless in_time == :past || in_time == :future
- raise ArgumentError, in_time_error
- end
- # Filter out invalid arguments for :calendar
- Ago.calendar_check(calendar)
- # Filter out invalid arguments for :start_at and :focus
- base_error = " => value must either be a number " +
- "between 0 and 6 (inclusive),\nor one of the following " +
- "symbols: " + Valids
- {:focus => focus, :start_at => start_at}.each do |key, opt|
- opt_error = ":" + key.to_s + base_error
- if opt.class == Integer
- raise ArgumentError, opt_error unless opt >= 0 && opt <= 6
- elsif opt.class == Symbol
- raise ArgumentError, opt_error unless Ago::Units[opt]
- else
- raise ArgumentError, opt_error
- end
- end
- # Create Variables necessary for processing.
- frags = []
- output = ""
- count = 0
- now = calendar == :basic ? now.to_i : now.to_f
- my_time = calendar == :basic ? self.to_i : self.to_f
- if now > my_time
- diff = now - my_time
- tail = " ago"
- elsif my_time > now
- diff = my_time - now
- tail = " from now"
- else
- diff = 0
- tail = "just now"
- end
- # Begin Ago.ago processing
- Ago::Order.each do |u|
- if calendar == :gregorian && Ago::Units[u][:gregorian]
- value = Ago::Units[u][:gregorian]
- else
- value = Ago::Units[u][:basic]
- end
- count += 1
- # Move further ahead in the Ago::Units array if start_at is farther back than
- # the current point in the array.
- if start_at.class == Integer
- next if count <= start_at
- elsif start_at.class == Symbol
- next if Ago::Order.index(u) < Ago::Order.index(start_at)
- end
- n = (diff/value).floor
- if n > 0
- plural = n > 1 ? "s" : ""
- frags << "#{n} #{u.to_s + plural}"
- # If the argument passed into ago() is a symbol, focus the ago statement
- # down to the level specified in the symbol
- if focus.class == Symbol
- break if u == focus || u == :second
- elsif focus.class == Integer
- if focus == 0 || u == :second
- break
- else
- focus -= 1
- end
- end
- diff -= n * value
- end
- end
- # Der Kommissar
- frags.size.times do |n|
- output += frags[n]
- output += ", " unless n == frags.size - 1
- end
- return output + "#{tail}"
- end
- def from_now_in_words(opts={})
- ago_in_words(opts)
- end
- end
- end
- class Time
- include Ago::TimeAgo
- end
|