Module: Zena::Use::Dates::Common

Included in:
ControllerMethods, ModelMethods, ViewMethods
Defined in:
lib/zena/use/dates.rb

Instance Method Summary collapse

Instance Method Details

#format_date(thedate, opts = {}) ⇒ Object

This is like strftime but with better support for i18n (translate day names, month abbreviations, etc)



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
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
# File 'lib/zena/use/dates.rb', line 12

def format_date(thedate, opts = {})
  return '' if thedate.blank?

  theformat, tz_name, lang = opts[:format], opts[:tz], opts[:lang]
  format = theformat || _('datetime')

  if tz_name
    if tz_name.kind_of?(TZInfo::Timezone)
      tz = tz_name
    else
      # display time local to event's timezone
      begin
        tz = TZInfo::Timezone.get(tz_name)
      rescue TZInfo::InvalidTimezoneIdentifier
        return "<span class='parser_error'>invalid timezone #{tz_name.inspect}.</span>"
      end
    end
  else
    tz = visitor.tz
  end

  if thedate.kind_of?(Time)
    utc_date = thedate
    adate = tz.utc_to_local(thedate)
  elsif thedate.kind_of?(String)
    begin
      adate    = Date.parse(thedate)
      utc_date = adate
    rescue
      return "<span class='parser_error'>invalid date #{thedate.inspect}</span>"
    end
  else
    adate    = thedate
    utc_date = adate
  end

  # TODO: REFACTOR TO something like:
  # with_locale(lang) do
  # ...
  # end
  if lang
    ::I18n.locale = lang
  end

  if format =~ /^age\/?(.*)$/
    format = $1.blank? ? _('long_date') : $1
    # how long ago/in how long is the date
    # FIXME: when using 'age', set expire_at (+1 minute, +1 hour, +1 day, never)
    age = (Time.now.utc - utc_date) / 60

    if age > 7 * 24 * 60
      # far in the past, use strftime
    elsif age >= 2 * 24 * 60
      # days
      return _("%{d} days ago") % {:d => (age/(24*60)).floor}
    elsif age >= 24 * 60
      # days
      return _("yesterday")
    elsif age >= 2 * 60
      # hours
      return _("%{h} hours ago") % {:h => (age/60).floor}
    elsif age >= 60
      return _("1 hour ago")
    elsif age > 2
      # minutes
      return _("%{m} minutes ago") % {:m => age.floor}
    elsif age > 0
      return _("1 minute ago")
    elsif age >= -1
      return _("in 1 minute")
    elsif age > -60
      return _("in %{m} minutes") % {:m => -age.ceil}
    elsif age > -2 * 60
      return _("in 1 hour")
    elsif age > -24 * 60
      return _("in %{h} hours") % {:h => -(age/60).ceil}
    elsif age > -2 * 24 * 60
      return _("tomorrow")
    elsif age > -7 * 24 * 60
      return _("in %{d} days") % {:d => -(age/(24*60)).ceil}
    else
      # too far in the future, use strftime
    end
  end

  # month name
  format = format.gsub("%b", _(adate.strftime("%b")) )
  format.gsub!("%B", _(adate.strftime("%B")) )

  # weekday name
  format.gsub!("%a", _(adate.strftime("%a")) )
  format.gsub!("%A", _(adate.strftime("%A")) )

  if lang
    # Restore
    ::I18n.locale = visitor.lang
  end

  adate.strftime(format)
end