Permalink
Browse files

add relative_time_helpers plugin

git-svn-id: http://ar-code.svn.engineyard.com/plugins/relative_time_helpers@14 d98f8484-0aa7-43af-80ea-302c351499d6
  • Loading branch information...
0 parents commit 1eb646b3a645b2ba55fa025f3c17a4d8b80dc2f4 rick committed May 17, 2007
Showing with 172 additions and 0 deletions.
  1. +55 −0 init.rb
  2. +49 −0 lib/active_reload/relative_time_helpers.rb
  3. +68 −0 test/relative_time_helpers_test.rb
@@ -0,0 +1,55 @@
+# Time.now.to_ordinalized_s :long
+# => "February 28th, 2006 21:10"
+module OrdinalizedFormatting
+ def to_ordinalized_s(format = :default)
+ format = ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[format]
+ return to_default_s if format.nil?
+ strftime_ordinalized(format)
+ end
+
+ def strftime_ordinalized(fmt)
+ strftime(fmt.gsub(/%d/, '_%d_')).gsub(/_(\d+)_/) { |s| s.to_i.ordinalize }
+ end
+end
+
+Time.send :include, OrdinalizedFormatting
+Date.send :include, OrdinalizedFormatting
+
+class Time
+ class << self
+ # Used for getting multifield attributes like those generated by a
+ # select_datetime into a new Time object. For example if you have
+ # following <tt>params={:meetup=>{:"time(1i)=>..."}}</tt> just do
+ # following:
+ #
+ # <tt>Time.parse_from_attributes(params[:meetup], :time)</tt>
+ def parse_from_attributes(attrs, field, method=:gm)
+ attrs = attrs.keys.sort.grep(/^#{field.to_s}\(.+\)$/).map { |k| attrs[k] }
+ attrs.any? ? Time.send(method, *attrs) : nil
+ end
+
+ def delta(year, month = nil, day = nil)
+ from = Time.local(year, month || 1, day || 1)
+
+ to =
+ if !day.blank?
+ from.advance :days => 1
+ elsif !month.blank?
+ from.advance :months => 1
+ else
+ from.advance :years => 1
+ end
+ return [from.midnight, to.midnight-1]
+ end
+ end
+
+ def to_delta(delta_type = :day)
+ case delta_type
+ when :year then self.class.delta(year)
+ when :month then self.class.delta(year, month)
+ else self.class.delta(year, month, day)
+ end
+ end
+end
+
+ActionView::Base.send :include, ActiveReload::RelativeTimeHelpers
@@ -0,0 +1,49 @@
+module ActiveReload
+ # see test cases for sample output
+ module RelativeTimeHelpers
+ mattr_accessor :time_class
+ mattr_accessor :time_output
+
+ self.time_class = Time
+ self.time_output = {
+ :today => 'today',
+ :yesterday => 'yesterday',
+ :tomorrow => 'tomorrow',
+ :initial_format => '%b %d',
+ :year_format => ', %Y'
+ }
+
+ def relative_time(time)
+ date = time.to_date
+ today = time_class.now.to_date
+ if date == today
+ time_output[:today]
+ elsif date == (today - 1)
+ time_output[:yesterday]
+ elsif date == (today + 1)
+ time_output[:tomorrow]
+ else
+ fmt = time_output[:initial_format].dup
+ fmt << time_output[:year_format] unless date.year == today.year
+ time.strftime_ordinalized(fmt)
+ end
+ end
+
+ def relative_time_span(times)
+ times = [times.first, times.last].collect!(&:to_date)
+ times.sort!
+ if times.first == times.last
+ relative_time(times.first)
+ else
+ first = times.first; last = times.last; now = time_class.now
+ [first.strftime_ordinalized('%b %d')].tap do |arr|
+ arr << ", #{first.year}" unless first.year == last.year
+ arr << ' - '
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
+ arr << last.day.ordinalize
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
+ end.to_s
+ end
+ end
+ end
+end
@@ -0,0 +1,68 @@
+require File.dirname(__FILE__) + '/../../../../test/test_helper'
+
+class RelativeTimeHelpersTest < Test::Unit::TestCase
+ include ActiveReload::RelativeTimeHelpers
+
+ def setup
+ @current_time_class = ActiveReload::RelativeTimeHelpers.time_class
+ ActiveReload::RelativeTimeHelpers.time_class = Time
+ end
+
+ def teardown
+ ActiveReload::RelativeTimeHelpers.time_class = @current_time_class
+ end
+
+ def test_should_show_today
+ assert_equal 'today', relative_time(Time.now.utc)
+ end
+
+ def test_should_show_yesterday
+ assert_equal 'yesterday', relative_time(1.day.ago.utc)
+ end
+
+ def test_should_show_tomorrow
+ assert_equal 'tomorrow', relative_time(1.day.from_now.utc)
+ end
+
+ def test_should_show_date_with_year
+ assert_equal 'Nov 15th, 2005', relative_time(Time.utc(2005, 11, 15))
+ end
+
+ def test_should_show_date
+ Time.stubs(:now).returns(Time.utc(2006, 6, 1, 11))
+ assert_equal 'Nov 15th', relative_time(Time.utc(2006, 11, 15))
+ end
+
+ def test_should_show_span_on_the_same_day
+ assert_equal 'Nov 15th', relative_time_span([Time.utc(2007, 11, 15), Time.utc(2007, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_same_day_on_different_year
+ assert_equal 'Nov 15th, 2006', relative_time_span([Time.utc(2006, 11, 15), Time.utc(2006, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_same_month
+ assert_equal 'Nov 15th - 16th', relative_time_span([Time.utc(2007, 11, 15), Time.utc(2007, 11, 16)])
+ assert_equal 'Nov 15th - 16th', relative_time_span([Time.utc(2007, 11, 16), Time.utc(2007, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_same_month_on_different_year
+ assert_equal 'Nov 15th - 16th, 2006', relative_time_span([Time.utc(2006, 11, 15), Time.utc(2006, 11, 16)])
+ assert_equal 'Nov 15th - 16th, 2006', relative_time_span([Time.utc(2006, 11, 16), Time.utc(2006, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_different_month
+ assert_equal 'Nov 15th - Dec 16th', relative_time_span([Time.utc(2007, 11, 15), Time.utc(2007, 12, 16)])
+ assert_equal 'Nov 15th - Dec 16th', relative_time_span([Time.utc(2007, 12, 16), Time.utc(2007, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_different_month_on_different_year
+ assert_equal 'Nov 15th - Dec 16th, 2006', relative_time_span([Time.utc(2006, 11, 15), Time.utc(2006, 12, 16)])
+ assert_equal 'Nov 15th - Dec 16th, 2006', relative_time_span([Time.utc(2006, 12, 16), Time.utc(2006, 11, 15)])
+ end
+
+ def test_should_show_span_on_the_different_year
+ assert_equal 'Nov 15th, 2006 - Dec 16th, 2007', relative_time_span([Time.utc(2006, 11, 15), Time.utc(2007, 12, 16)])
+ assert_equal 'Nov 15th, 2006 - Dec 16th, 2007', relative_time_span([Time.utc(2007, 12, 16), Time.utc(2006, 11, 15)])
+ end
+end

0 comments on commit 1eb646b

Please sign in to comment.