date-casually 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +54 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/date-casually.gemspec +88 -0
- data/lib/date-casually/calculator.rb +48 -0
- data/lib/date-casually/config.rb +14 -0
- data/lib/date-casually/translator.rb +59 -0
- data/lib/date-casually/translators/day_of_week.rb +30 -0
- data/lib/date-casually/translators/days.rb +26 -0
- data/lib/date-casually/translators/months.rb +32 -0
- data/lib/date-casually/translators/weeks.rb +32 -0
- data/lib/date-casually/translators/years.rb +35 -0
- data/lib/date-casually.rb +17 -0
- data/lib/extensions/date.rb +5 -0
- data/lib/locale/en.yml +93 -0
- data/lib/locale/en.yml.sorted +85 -0
- data/lib/util/alphabetize_yaml.rb +38 -0
- data/test/helper.rb +27 -0
- data/test/test_calculator.rb +59 -0
- data/test/test_date-casually.rb +2 -0
- data/test/test_day_of_week.rb +37 -0
- data/test/test_days.rb +40 -0
- data/test/test_months.rb +59 -0
- data/test/test_translator.rb +4 -0
- data/test/test_weeks.rb +40 -0
- data/test/test_years.rb +60 -0
- data/test/timeline.rb +11 -0
- metadata +153 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 twmills LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= DateCasually
|
2
|
+
|
3
|
+
If you've always expected the Rails date helpers to say "Today", "Yesterday" or "10 days ago" when asked about a specific date, then it's time to date casually.
|
4
|
+
|
5
|
+
I've never liked (and always seem to forget) the name of the Rails distance_of_time_in_words_to_now helper method. Additionally it doesn't handle obvious translations such as "today", "tomorrow" or "yesterday" and doesn't determine if a date is in the future ("10 days from now") or the past ("10 days ago").
|
6
|
+
|
7
|
+
== Quick Examples
|
8
|
+
|
9
|
+
Date.today.casual
|
10
|
+
#=> 'today'
|
11
|
+
|
12
|
+
(Date.today + 1).casual
|
13
|
+
#=> 'tomorrow'
|
14
|
+
|
15
|
+
(Date.today - 1).casual
|
16
|
+
#=> 'yesterday'
|
17
|
+
|
18
|
+
== The :as option
|
19
|
+
|
20
|
+
If you'd like to change what increments of time DateCasually returns you can use the :as option.
|
21
|
+
|
22
|
+
(Date.today + 1).casual(:as => :months)
|
23
|
+
#=> 'less than a month from now'
|
24
|
+
|
25
|
+
You can also pass in multiple options:
|
26
|
+
|
27
|
+
(Date.today + 1).casual(:as => :days, :months, :years)
|
28
|
+
#=> 'less than a month from now'
|
29
|
+
|
30
|
+
The default :as options for DatCasually are:
|
31
|
+
|
32
|
+
(Date.today + 1).casual(:as => :days, :weeks, :months, :years)
|
33
|
+
|
34
|
+
If you'd change DateCasually globally, do this:
|
35
|
+
|
36
|
+
DateCasually::Config.as = :months, :years
|
37
|
+
|
38
|
+
== i18n
|
39
|
+
|
40
|
+
Date-casually hooks into the i18n gem, but currently only supports English.
|
41
|
+
|
42
|
+
== Dependencies
|
43
|
+
|
44
|
+
* i18n
|
45
|
+
* chronic (_only used in the test suite_)
|
46
|
+
* timecop (_only used in the test suite_)
|
47
|
+
|
48
|
+
== Roadmap
|
49
|
+
|
50
|
+
* timezone support
|
51
|
+
* configurable start of week
|
52
|
+
* set up config class to handle global options (such as :include)
|
53
|
+
* spanish translations (and others if people provide them)
|
54
|
+
* configurable ranges (maybe...)
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "date-casually"
|
8
|
+
gem.summary = %Q{Easy on the eyes alternative to the Rails distance_of_time_in_words_to_now helper method.}
|
9
|
+
gem.description = %Q{If you've never liked (and always seem to forget) the name of the Rails distance_of_time_in_words_to_now helper method, then it's time to date casually.}
|
10
|
+
gem.email = "twmills@twmills.com"
|
11
|
+
gem.homepage = "http://github.com/twmills/date-casually"
|
12
|
+
gem.authors = ["Theo Mills"]
|
13
|
+
gem.add_dependency 'i18n', ">= 0.4.1"
|
14
|
+
gem.add_development_dependency "timecop", ">= 0.3.5"
|
15
|
+
gem.add_development_dependency "chronic", ">= 0.2.3"
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/test_*.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
task :test => :check_dependencies
|
30
|
+
|
31
|
+
task :default => :test
|
32
|
+
|
33
|
+
require 'rake/rdoctask'
|
34
|
+
Rake::RDocTask.new do |rdoc|
|
35
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
36
|
+
|
37
|
+
rdoc.rdoc_dir = 'rdoc'
|
38
|
+
rdoc.title = "date-casually #{version}"
|
39
|
+
rdoc.rdoc_files.include('README*')
|
40
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{date-casually}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Theo Mills"]
|
12
|
+
s.date = %q{2010-08-26}
|
13
|
+
s.description = %q{If you've never liked (and always seem to forget) the name of the Rails distance_of_time_in_words_to_now helper method, then it's time to date casually.}
|
14
|
+
s.email = %q{twmills@twmills.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"date-casually.gemspec",
|
27
|
+
"lib/date-casually.rb",
|
28
|
+
"lib/date-casually/calculator.rb",
|
29
|
+
"lib/date-casually/config.rb",
|
30
|
+
"lib/date-casually/translator.rb",
|
31
|
+
"lib/date-casually/translators/day_of_week.rb",
|
32
|
+
"lib/date-casually/translators/days.rb",
|
33
|
+
"lib/date-casually/translators/months.rb",
|
34
|
+
"lib/date-casually/translators/weeks.rb",
|
35
|
+
"lib/date-casually/translators/years.rb",
|
36
|
+
"lib/extensions/date.rb",
|
37
|
+
"lib/locale/en.yml",
|
38
|
+
"lib/locale/en.yml.sorted",
|
39
|
+
"lib/util/alphabetize_yaml.rb",
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/test_calculator.rb",
|
42
|
+
"test/test_date-casually.rb",
|
43
|
+
"test/test_day_of_week.rb",
|
44
|
+
"test/test_days.rb",
|
45
|
+
"test/test_months.rb",
|
46
|
+
"test/test_translator.rb",
|
47
|
+
"test/test_weeks.rb",
|
48
|
+
"test/test_years.rb",
|
49
|
+
"test/timeline.rb"
|
50
|
+
]
|
51
|
+
s.homepage = %q{http://github.com/twmills/date-casually}
|
52
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
53
|
+
s.require_paths = ["lib"]
|
54
|
+
s.rubygems_version = %q{1.3.7}
|
55
|
+
s.summary = %q{Easy on the eyes alternative to the Rails distance_of_time_in_words_to_now helper method.}
|
56
|
+
s.test_files = [
|
57
|
+
"test/helper.rb",
|
58
|
+
"test/test_calculator.rb",
|
59
|
+
"test/test_date-casually.rb",
|
60
|
+
"test/test_day_of_week.rb",
|
61
|
+
"test/test_days.rb",
|
62
|
+
"test/test_months.rb",
|
63
|
+
"test/test_translator.rb",
|
64
|
+
"test/test_weeks.rb",
|
65
|
+
"test/test_years.rb",
|
66
|
+
"test/timeline.rb"
|
67
|
+
]
|
68
|
+
|
69
|
+
if s.respond_to? :specification_version then
|
70
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
71
|
+
s.specification_version = 3
|
72
|
+
|
73
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
74
|
+
s.add_runtime_dependency(%q<i18n>, [">= 0.4.1"])
|
75
|
+
s.add_development_dependency(%q<timecop>, [">= 0.3.5"])
|
76
|
+
s.add_development_dependency(%q<chronic>, [">= 0.2.3"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<i18n>, [">= 0.4.1"])
|
79
|
+
s.add_dependency(%q<timecop>, [">= 0.3.5"])
|
80
|
+
s.add_dependency(%q<chronic>, [">= 0.2.3"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<i18n>, [">= 0.4.1"])
|
84
|
+
s.add_dependency(%q<timecop>, [">= 0.3.5"])
|
85
|
+
s.add_dependency(%q<chronic>, [">= 0.2.3"])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module DateCasually
|
2
|
+
|
3
|
+
# Contains short-cut calculations for determing the distance between
|
4
|
+
# today and a supplied date.
|
5
|
+
class Calculator
|
6
|
+
|
7
|
+
def self.number_of_weeks_from_today(date)
|
8
|
+
((Date.today - date) / 7).to_i.abs
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.number_of_months_from_today(date)
|
12
|
+
((Date.today.month - date.month) + 12 * (Date.today.year - date.year)).abs
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.number_of_years_from_today(date)
|
16
|
+
years_diff = (Date.today.year - date.year).abs
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.this_week_range
|
20
|
+
self.this_past_sunday..(self.this_past_sunday + 6)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.next_week_range
|
24
|
+
self.next_sunday..(self.next_sunday + 6)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.last_week_range
|
28
|
+
self.last_sunday..(self.last_sunday + 6)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.next_sunday
|
32
|
+
date = Date.today
|
33
|
+
(date.wday == 0) ? (date += 7) : (date += 1 until (date.wday == 0))
|
34
|
+
date
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.last_sunday
|
38
|
+
self.this_past_sunday - 7
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.this_past_sunday
|
42
|
+
date = Date.today
|
43
|
+
(date.wday == 0) ? date : (date -= 1 until (date.wday == 0))
|
44
|
+
date
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module DateCasually
|
2
|
+
|
3
|
+
# The Translator class is the core of the date-casually functionality,
|
4
|
+
# translating the supplied date to its casual equivalent.
|
5
|
+
class Translator
|
6
|
+
|
7
|
+
# The possible options and order of the :as toggle
|
8
|
+
AS_OPTIONS = [:days, :day_of_week, :weeks, :months, :years]
|
9
|
+
|
10
|
+
#
|
11
|
+
# This method takes the supplied date and determines how it should be translated
|
12
|
+
# into its casual equivalent. If the :as option is passed with a valid value,
|
13
|
+
# then the date is evaluated against that scope, e.g. :as=>:day_of_week.
|
14
|
+
# Otherwise, the Translator iterates through all the available scopes until a
|
15
|
+
# match on the supplied date is made.
|
16
|
+
#
|
17
|
+
# Though it's easier to use date-casually date extension and monkey-patch
|
18
|
+
# this function into the Date class, it's also possible to call the casual
|
19
|
+
# function directly.
|
20
|
+
#
|
21
|
+
def self.casual(date, options = {})
|
22
|
+
|
23
|
+
# Process in order until we hit a condition that matches
|
24
|
+
# the supplied date.
|
25
|
+
translator = nil
|
26
|
+
self.as_options(options).each do |option|
|
27
|
+
translator = self.get_translator(option)
|
28
|
+
translation = translator.translate(date)
|
29
|
+
return translation unless translation.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
# If no conditions are caught, use our last :as option to create
|
33
|
+
# explicit counts. I.e. 470 days ago, 46 months from now, 4 years from now, etc.
|
34
|
+
unless translator.nil?
|
35
|
+
translation = translator.translate_count(date)
|
36
|
+
return translation unless translation.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
raise "[date-casually] No ruleset defined for this date: #{date}"
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Process :as option if passed, otherwise use global config
|
44
|
+
def self.as_options(options)
|
45
|
+
as = []
|
46
|
+
as << (!options.nil? && options.has_key?(:as) ? options[:as] : DateCasually::Config.as)
|
47
|
+
self::AS_OPTIONS & as.flatten
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.get_translator(sym)
|
51
|
+
DateCasually::Translators.const_get(self.camelcase(sym.to_s))
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.camelcase(string)
|
55
|
+
string.downcase.gsub(/\b[a-z]|_+[a-z]/) { |a| a.upcase }.gsub(/\s|_/,'')
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DateCasually
|
2
|
+
module Translators
|
3
|
+
class DayOfWeek
|
4
|
+
|
5
|
+
# Scopes for translation into day of week
|
6
|
+
def self.translate(date)
|
7
|
+
today = Date.today
|
8
|
+
case
|
9
|
+
when date == today then I18n.t('date.casual.today')
|
10
|
+
when (date - today).abs <= 3
|
11
|
+
key = today < date ? "date.casual.this_wday_#{date.wday}" : "date.casual.this_past_wday_#{date.wday}"
|
12
|
+
I18n.t(key)
|
13
|
+
when DateCasually::Calculator.last_week_range.include?(date)
|
14
|
+
I18n.t("date.casual.last_wday_#{date.wday}")
|
15
|
+
when DateCasually::Calculator.next_week_range.include?(date)
|
16
|
+
I18n.t("date.casual.next_wday_#{date.wday}")
|
17
|
+
else
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Translates into number of days of weeks away, e.g. "6 Mondays ago"
|
23
|
+
def self.translate_count(date)
|
24
|
+
key = Date.today < date ? "date.casual.wdays_from_now_#{date.wday}" : "date.casual.wdays_ago_#{date.wday}"
|
25
|
+
I18n.t(key, :number => DateCasually::Calculator.number_of_weeks_from_today(date))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DateCasually
|
2
|
+
module Translators
|
3
|
+
class Days
|
4
|
+
|
5
|
+
# Scopes for translation into days
|
6
|
+
def self.translate(date)
|
7
|
+
today = Date.today
|
8
|
+
case
|
9
|
+
when date == today then I18n.t('date.casual.today')
|
10
|
+
when date == today + 1 then I18n.t('date.casual.tomorrow')
|
11
|
+
when date == (today - 1) then I18n.t('date.casual.yesterday')
|
12
|
+
when date == (today + 2) then I18n.t('date.casual.couple_of_days_from_now')
|
13
|
+
when date == (today - 2) then I18n.t('date.casual.couple_of_days_ago')
|
14
|
+
else nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Translates into number of days away, e.g. "6 days ago"
|
19
|
+
def self.translate_count(date)
|
20
|
+
i18n_key = (date < Date.today) ? 'ago' : 'from_now'
|
21
|
+
I18n.t("date.casual.days_#{i18n_key}", :number => (date - Date.today).abs)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module DateCasually
|
2
|
+
module Translators
|
3
|
+
|
4
|
+
class Months
|
5
|
+
|
6
|
+
# Scopes for translation into months
|
7
|
+
def self.translate(date)
|
8
|
+
today = Date.today
|
9
|
+
case
|
10
|
+
when (today - date).abs <= 29
|
11
|
+
key = today < date ? 'date.casual.less_than_a_month_from_now' : 'date.casual.less_than_a_month_ago'
|
12
|
+
I18n.t(key)
|
13
|
+
when (30..60).include?((today - date).abs)
|
14
|
+
key = today < date ? 'date.casual.next_month' : 'date.casual.last_month'
|
15
|
+
I18n.t(key)
|
16
|
+
when DateCasually::Calculator.number_of_months_from_today(date) == 2
|
17
|
+
key = today < date ? 'date.casual.couple_of_months_from_now' : 'date.casual.couple_of_months_ago'
|
18
|
+
I18n.t(key)
|
19
|
+
else
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Translates into number of months away, e.g. "6 months ago"
|
25
|
+
def self.translate_count(date)
|
26
|
+
key = Date.today < date ? 'date.casual.months_from_now' : 'date.casual.months_ago'
|
27
|
+
date = I18n.t(key, :number => DateCasually::Calculator.number_of_months_from_today(date))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module DateCasually
|
2
|
+
module Translators
|
3
|
+
class Weeks
|
4
|
+
|
5
|
+
# Scopes for translation into weeks
|
6
|
+
def self.translate(date)
|
7
|
+
today = Date.today
|
8
|
+
case
|
9
|
+
when DateCasually::Calculator.this_week_range.include?(date)
|
10
|
+
key = today < date ? 'date.casual.less_than_a_week_from_now' : 'date.casual.less_than_a_week_ago'
|
11
|
+
I18n.t(key)
|
12
|
+
when DateCasually::Calculator.last_week_range.include?(date)
|
13
|
+
I18n.t('date.casual.last_week')
|
14
|
+
when DateCasually::Calculator.next_week_range.include?(date)
|
15
|
+
I18n.t('date.casual.next_week')
|
16
|
+
when (today - date).abs < 21
|
17
|
+
key = today < date ? 'date.casual.couple_of_weeks_from_now' : 'date.casual.couple_of_weeks_ago'
|
18
|
+
I18n.t(key)
|
19
|
+
else
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Translates into number of weeks away, e.g. "6 weeks ago"
|
25
|
+
def self.translate_count(date)
|
26
|
+
key = Date.today < date ? 'date.casual.weeks_from_now' : 'date.casual.weeks_ago'
|
27
|
+
I18n.t(key, :number => DateCasually::Calculator.number_of_weeks_from_today(date))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DateCasually
|
2
|
+
module Translators
|
3
|
+
class Years
|
4
|
+
|
5
|
+
# Scopes for translation into years
|
6
|
+
def self.translate(date)
|
7
|
+
today = Date.today
|
8
|
+
case
|
9
|
+
when DateCasually::Calculator.number_of_months_from_today(date) < 12
|
10
|
+
if (date.year - today.year).abs == 1
|
11
|
+
key = today < date ? 'date.casual.next_year' : 'date.casual.last_year'
|
12
|
+
else
|
13
|
+
key = today < date ? 'date.casual.less_than_a_year_from_now' : 'date.casual.less_than_a_year_ago'
|
14
|
+
end
|
15
|
+
I18n.t(key)
|
16
|
+
when (date.year - today.year).abs == 1
|
17
|
+
key = today < date ? 'date.casual.next_year' : 'date.casual.last_year'
|
18
|
+
I18n.t(key)
|
19
|
+
when DateCasually::Calculator.number_of_months_from_today(date) <= 30
|
20
|
+
key = today < date ? 'date.casual.couple_of_years_from_now' : 'date.casual.couple_of_years_ago'
|
21
|
+
I18n.t(key)
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Translates into number of weeks away, e.g. "6 years ago"
|
28
|
+
def self.translate_count(date)
|
29
|
+
key = Date.today < date ? 'date.casual.years_from_now' : 'date.casual.years_ago'
|
30
|
+
I18n.t(key, :number => DateCasually::Calculator.number_of_years_from_today(date))
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'date'
|
5
|
+
require 'i18n'
|
6
|
+
require "date-casually/config"
|
7
|
+
require "date-casually/calculator"
|
8
|
+
require "date-casually/translator"
|
9
|
+
require "date-casually/translators/days"
|
10
|
+
require "date-casually/translators/weeks"
|
11
|
+
require "date-casually/translators/months"
|
12
|
+
require "date-casually/translators/day_of_week"
|
13
|
+
require "date-casually/translators/years"
|
14
|
+
require "extensions/date"
|
15
|
+
|
16
|
+
# load up translations
|
17
|
+
I18n.load_path << Dir[File.join(File.dirname(__FILE__), 'locale', '*.{rb,yml}')]
|
data/lib/locale/en.yml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
en:
|
2
|
+
date:
|
3
|
+
casual:
|
4
|
+
today: "today"
|
5
|
+
tomorrow: "tomorrow"
|
6
|
+
yesterday: "yesterday"
|
7
|
+
next_week: "next week"
|
8
|
+
last_week: "last week"
|
9
|
+
this_wday_0: "this Sunday"
|
10
|
+
this_wday_1: "this Monday"
|
11
|
+
this_wday_2: "this Tuesday"
|
12
|
+
this_wday_3: "this Wednesday"
|
13
|
+
this_wday_4: "this Thursday"
|
14
|
+
this_wday_5: "this Friday"
|
15
|
+
this_wday_6: "this Saturday"
|
16
|
+
this_past_wday_0: "this past Sunday"
|
17
|
+
this_past_wday_1: "this past Monday"
|
18
|
+
this_past_wday_2: "this past Tuesday"
|
19
|
+
this_past_wday_3: "this past Wednesday"
|
20
|
+
this_past_wday_4: "this past Thursday"
|
21
|
+
this_past_wday_5: "this past Friday"
|
22
|
+
this_past_wday_6: "this past Saturday"
|
23
|
+
next_wday_0: "next Sunday"
|
24
|
+
next_wday_1: "next Monday"
|
25
|
+
next_wday_2: "next Tuesday"
|
26
|
+
next_wday_3: "next Wednesday"
|
27
|
+
next_wday_4: "next Thursday"
|
28
|
+
next_wday_5: "next Friday"
|
29
|
+
next_wday_6: "next Saturday"
|
30
|
+
last_wday_0: "last Sunday"
|
31
|
+
last_wday_1: "last Monday"
|
32
|
+
last_wday_2: "last Tuesday"
|
33
|
+
last_wday_3: "last Wednesday"
|
34
|
+
last_wday_4: "last Thursday"
|
35
|
+
last_wday_5: "last Friday"
|
36
|
+
last_wday_6: "last Saturday"
|
37
|
+
wdays_from_now_0: "%{number} Sundays from now"
|
38
|
+
wdays_from_now_1: "%{number} Mondays from now"
|
39
|
+
wdays_from_now_2: "%{number} Tuesdays from now"
|
40
|
+
wdays_from_now_3: "%{number} Wednesdays from now"
|
41
|
+
wdays_from_now_4: "%{number} Thursdays from now"
|
42
|
+
wdays_from_now_5: "%{number} Fridays from now"
|
43
|
+
wdays_from_now_6: "%{number} Saturdays from now"
|
44
|
+
wdays_ago_0: "%{number} Sundays ago"
|
45
|
+
wdays_ago_1: "%{number} Mondays ago"
|
46
|
+
wdays_ago_2: "%{number} Tuesdays ago"
|
47
|
+
wdays_ago_3: "%{number} Wednesdays ago"
|
48
|
+
wdays_ago_4: "%{number} Thursdays ago"
|
49
|
+
wdays_ago_5: "%{number} Fridays ago"
|
50
|
+
wdays_ago_6: "%{number} Saturdays ago"
|
51
|
+
one_day_ago: "one day ago"
|
52
|
+
days_ago: "%{number} days ago"
|
53
|
+
a_week_ago: "a week ago"
|
54
|
+
more_than_a_week_ago: "more than a week ago"
|
55
|
+
weeks_ago: "%{number} weeks ago"
|
56
|
+
exactly_one_month_ago: "exactly one month ago"
|
57
|
+
exactly_one_month_from_now: "exactly one month from now"
|
58
|
+
more_than_a_month_ago: "more than a month ago"
|
59
|
+
less_than_a_month_ago: "less than a month ago"
|
60
|
+
more_than_a_month_from_now: "more than a month from now"
|
61
|
+
less_than_a_month_from_now: "less than a month from now"
|
62
|
+
more_than_a_week_ago: "more than a week ago"
|
63
|
+
less_than_a_week_ago: "less than a week ago"
|
64
|
+
more_than_a_week_from_now: "more than a week from now"
|
65
|
+
less_than_a_week_from_now: "less than a week from now"
|
66
|
+
about_a_week_from_now: "about a week from now"
|
67
|
+
about_a_week_ago: "about a week ago"
|
68
|
+
more_than_a_year_ago: "more than a year ago"
|
69
|
+
less_than_a_year_ago: "less than a year ago"
|
70
|
+
more_than_a_year_from_now: "more than a year from now"
|
71
|
+
less_than_a_year_from_now: "less than a year from now"
|
72
|
+
months_ago: "%{number} months ago"
|
73
|
+
next_month: "next month"
|
74
|
+
last_month: "last month"
|
75
|
+
a_year_ago: "a year ago"
|
76
|
+
a_year_from_now: "a year from now"
|
77
|
+
years_ago: "%{number} years ago"
|
78
|
+
next_year: "next year"
|
79
|
+
last_year: "last year"
|
80
|
+
days_from_now: "%{number} days from now"
|
81
|
+
weeks_from_now: "%{number} weeks from now"
|
82
|
+
months_from_now: "%{number} months from now"
|
83
|
+
years_from_now: "%{number} years from now"
|
84
|
+
in_a_couple_of_days: "in a couple of days"
|
85
|
+
in_a_couple_of_weeks: "in a couple of weeks"
|
86
|
+
couple_of_months_ago: "a couple of months ago"
|
87
|
+
couple_of_months_from_now: "a couple of months from now"
|
88
|
+
couple_of_days_from_now: "a couple of days from now"
|
89
|
+
couple_of_days_ago: "a couple of days ago"
|
90
|
+
couple_of_weeks_ago: "a couple of weeks ago"
|
91
|
+
couple_of_weeks_from_now: "a couple of weeks from now"
|
92
|
+
couple_of_years_ago: "a couple of years ago"
|
93
|
+
couple_of_years_from_now: "a couple of years from now"
|
@@ -0,0 +1,85 @@
|
|
1
|
+
en:
|
2
|
+
date:
|
3
|
+
casual:
|
4
|
+
a_week_ago: a week ago
|
5
|
+
a_year_ago: a year ago
|
6
|
+
a_year_from_now: a year from now
|
7
|
+
about_a_week_ago: about a week ago
|
8
|
+
about_a_week_from_now: about a week from now
|
9
|
+
couple_of_days_ago: a couple of days ago
|
10
|
+
couple_of_days_from_now: a couple of days from now
|
11
|
+
couple_of_months_ago: a couple of months ago
|
12
|
+
couple_of_months_from_now: a couple of months from now
|
13
|
+
couple_of_weeks_ago: a couple of weeks ago
|
14
|
+
couple_of_weeks_from_now: a couple of weeks from now
|
15
|
+
couple_of_years_ago: a couple of years ago
|
16
|
+
couple_of_years_from_now: a couple of years from now
|
17
|
+
days_ago: {{number}} days ago
|
18
|
+
days_from_now: {{number}} days from now
|
19
|
+
exactly_one_month_ago: exactly one month ago
|
20
|
+
exactly_one_month_from_now: exactly one month from now
|
21
|
+
in_a_couple_of_days: in a couple of days
|
22
|
+
in_a_couple_of_weeks: in a couple of weeks
|
23
|
+
last_month: last month
|
24
|
+
last_wday_0: last Sunday
|
25
|
+
last_wday_1: last Monday
|
26
|
+
last_wday_2: last Tuesday
|
27
|
+
last_wday_3: last Wednesday
|
28
|
+
last_wday_4: last Thursday
|
29
|
+
last_wday_5: last Friday
|
30
|
+
last_wday_6: last Saturday
|
31
|
+
last_week: last week
|
32
|
+
last_year: last year
|
33
|
+
less_than_a_month_ago: less than a month ago
|
34
|
+
less_than_a_month_from_now: less than a month from now
|
35
|
+
less_than_a_week_ago: less than a week ago
|
36
|
+
less_than_a_week_from_now: less than a week from now
|
37
|
+
less_than_a_year_ago: less than a year ago
|
38
|
+
less_than_a_year_from_now: less than a year from now
|
39
|
+
months_ago: {{number}} months ago
|
40
|
+
months_from_now: {{number}} months from now
|
41
|
+
more_than_a_month_ago: more than a month ago
|
42
|
+
more_than_a_month_from_now: more than a month from now
|
43
|
+
more_than_a_week_ago: more than a week ago
|
44
|
+
more_than_a_week_from_now: more than a week from now
|
45
|
+
more_than_a_year_ago: more than a year ago
|
46
|
+
more_than_a_year_from_now: more than a year from now
|
47
|
+
next_month: next month
|
48
|
+
next_wday_0: next Sunday
|
49
|
+
next_wday_1: next Monday
|
50
|
+
next_wday_2: next Tuesday
|
51
|
+
next_wday_3: next Wednesday
|
52
|
+
next_wday_4: next Thursday
|
53
|
+
next_wday_5: next Friday
|
54
|
+
next_wday_6: next Saturday
|
55
|
+
next_week: next week
|
56
|
+
next_year: next year
|
57
|
+
one_day_ago: one day ago
|
58
|
+
this_past_wday_0: this past Sunday
|
59
|
+
this_past_wday_1: this past Monday
|
60
|
+
this_past_wday_2: this past Tuesday
|
61
|
+
this_past_wday_3: this past Wednesday
|
62
|
+
this_past_wday_4: this past Thursday
|
63
|
+
this_past_wday_5: this past Friday
|
64
|
+
this_past_wday_6: this past Saturday
|
65
|
+
this_wday_0: this Sunday
|
66
|
+
this_wday_1: this Monday
|
67
|
+
this_wday_2: this Tuesday
|
68
|
+
this_wday_3: this Wednesday
|
69
|
+
this_wday_4: this Thursday
|
70
|
+
this_wday_5: this Friday
|
71
|
+
this_wday_6: this Saturday
|
72
|
+
today: today
|
73
|
+
tomorrow: tomorrow
|
74
|
+
wdays_ago_0: {{number}} Sundays ago
|
75
|
+
wdays_ago_1: {{number}} Mondays ago
|
76
|
+
wdays_ago_2: {{number}} Tuesdays ago
|
77
|
+
wdays_ago_3: {{number}} Wednesdays ago
|
78
|
+
wdays_ago_4: {{number}} Thursdays ago
|
79
|
+
wdays_ago_5: {{number}} Fridays ago
|
80
|
+
wdays_ago_6: {{number}} Saturdays ago
|
81
|
+
weeks_ago: {{number}} weeks ago
|
82
|
+
weeks_from_now: {{number}} weeks from now
|
83
|
+
years_ago: {{number}} years ago
|
84
|
+
years_from_now: {{number}} years from now
|
85
|
+
yesterday: yesterday
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class Hash
|
3
|
+
def to_sorted_yaml( opts = {} )
|
4
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
5
|
+
out.map( taguri, to_yaml_style ) do |map|
|
6
|
+
sort.each do |k, v|
|
7
|
+
map.add(k,v)
|
8
|
+
if v.is_a? Hash
|
9
|
+
v.sort.each do |x,y|
|
10
|
+
if y.is_a? Hash
|
11
|
+
y.sort.each do |u,t|
|
12
|
+
map.add(u,t)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
files = Dir.glob(File.join(File.dirname(__FILE__),"*.yml"))
|
25
|
+
|
26
|
+
files.each do |file|
|
27
|
+
hash = YAML::load(File.read(file))
|
28
|
+
def alphabetize(hash, tabs = 0)
|
29
|
+
string=""
|
30
|
+
hash.keys.sort.each do |key|
|
31
|
+
tabs.times { string << " " }
|
32
|
+
string << (hash[key].is_a?(Hash) ? ("#{key}: \n" + alphabetize(hash[key], tabs + 2)) : "#{key}: #{hash[key]}\n")
|
33
|
+
end
|
34
|
+
string
|
35
|
+
end
|
36
|
+
File.open(file + '.sorted', 'w') { |f| f.write(alphabetize(hash)) }
|
37
|
+
end
|
38
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'chronic'
|
4
|
+
require 'timecop'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'date-casually'
|
9
|
+
|
10
|
+
# freeze time for test consistency
|
11
|
+
t = Time.local(2008, 9, 1, 10, 5, 0)
|
12
|
+
Timecop.travel(t)
|
13
|
+
|
14
|
+
class Test::Unit::TestCase
|
15
|
+
def parse(string)
|
16
|
+
Date.parse(Chronic.parse(string).strftime('%b %d, %Y'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.method_name(name, options)
|
20
|
+
if (options != nil) && options.has_key?(:as)
|
21
|
+
"test_#{name}_as_#{options[:as]}"
|
22
|
+
else
|
23
|
+
"test_#{name}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCalculator < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_last_week_range
|
6
|
+
sunday = Date.today.wday == 0 ? Date.today : parse('last Sunday')
|
7
|
+
sunday -= 7
|
8
|
+
saturday = sunday + 6
|
9
|
+
assert_equal sunday..saturday, DateCasually::Calculator.last_week_range
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_last_sunday
|
13
|
+
sunday = Date.today.wday == 0 ? Date.today : parse('last Sunday')
|
14
|
+
sunday -= 7
|
15
|
+
assert_equal sunday, DateCasually::Calculator.last_sunday
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_this_past_sunday
|
19
|
+
sunday = Date.today.wday == 0 ? Date.today : parse('last Sunday')
|
20
|
+
assert_equal sunday, DateCasually::Calculator.this_past_sunday
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_next_week_range
|
24
|
+
sunday = parse('next Sunday')
|
25
|
+
assert_equal sunday..sunday + 6, DateCasually::Calculator.next_week_range
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_this_week_range
|
29
|
+
sunday = Date.today.wday == 0 ? Date.today : parse('last Sunday')
|
30
|
+
saturday = sunday + 6
|
31
|
+
assert_equal sunday..saturday, DateCasually::Calculator.this_week_range
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_next_sunday
|
35
|
+
assert_equal parse('next Sunday'), DateCasually::Calculator.next_sunday
|
36
|
+
end
|
37
|
+
|
38
|
+
(1..100).each do |x|
|
39
|
+
define_method("test_#{x}_weeks_from_today".to_sym) do
|
40
|
+
assert_equal x, DateCasually::Calculator.number_of_weeks_from_today(parse("in #{x} weeks"))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
(1..200).each do |x|
|
45
|
+
define_method("test_#{x}_months_from_today".to_sym) do
|
46
|
+
assert_equal x, DateCasually::Calculator.number_of_months_from_today(parse("in #{x} months"))
|
47
|
+
end
|
48
|
+
define_method("test_#{x}_months_ago".to_sym) do
|
49
|
+
assert_equal x, DateCasually::Calculator.number_of_months_from_today(parse("#{x} months ago"))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
(1..400).each do |x|
|
54
|
+
define_method("test_#{x}_years_from_today".to_sym) do
|
55
|
+
assert_equal x, DateCasually::Calculator.number_of_years_from_today(parse("in #{x} years"))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDayOfWeek < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_next_wday
|
6
|
+
date = parse('7 days from now')
|
7
|
+
assert_equal I18n.t("date.casual.next_wday_#{date.wday}"), date.casual(:as => :day_of_week)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_this_wday
|
11
|
+
date = parse('3 days from now')
|
12
|
+
assert_equal I18n.t("date.casual.this_wday_#{date.wday}"), date.casual(:as => :day_of_week)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_last_wday
|
16
|
+
date = parse('7 days ago')
|
17
|
+
assert_equal I18n.t("date.casual.last_wday_#{date.wday}"), date.casual(:as => :day_of_week)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_this_past_wday
|
21
|
+
date = parse('3 days ago')
|
22
|
+
assert_equal I18n.t("date.casual.this_past_wday_#{date.wday}"), date.casual(:as => :day_of_week)
|
23
|
+
end
|
24
|
+
|
25
|
+
(14..366).each do |x|
|
26
|
+
weeks = x / 7
|
27
|
+
define_method "test_#{x}_wdays_ago" do
|
28
|
+
date = parse("#{x} days ago")
|
29
|
+
assert_equal I18n.t("date.casual.wdays_ago_#{date.wday}", :number => weeks), date.casual(:as => :day_of_week)
|
30
|
+
end
|
31
|
+
define_method "test_#{x}_wdays_from_now" do
|
32
|
+
date = parse("in #{x} days")
|
33
|
+
assert_equal I18n.t("date.casual.wdays_from_now_#{date.wday}", :number => weeks), date.casual(:as => :day_of_week)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/test/test_days.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDays < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Test day ranges both with and without the :as => :days option
|
6
|
+
[nil, {:as => :days}].each do |options|
|
7
|
+
define_method method_name('yesterday', options) do
|
8
|
+
date = parse('yesterday')
|
9
|
+
assert_equal I18n.t('date.casual.yesterday'), date.casual(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
define_method method_name('tomorrow', options) do
|
13
|
+
date = parse('tomorrow')
|
14
|
+
assert_equal I18n.t('date.casual.tomorrow'), date.casual(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method method_name('couple_of_days_ago', options) do
|
18
|
+
date = parse('today') - 2
|
19
|
+
assert_equal I18n.t('date.casual.couple_of_days_ago'), date.casual(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
define_method method_name('couple_of_days_from_now', options) do
|
23
|
+
date = parse('today') + 2
|
24
|
+
assert_equal I18n.t('date.casual.couple_of_days_from_now'), date.casual(options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
(3..366).each do |x|
|
29
|
+
define_method "test_#{x}_days_ago_as_days" do
|
30
|
+
date = parse("#{x} days ago")
|
31
|
+
assert_equal I18n.t('date.casual.days_ago', :number => x), date.casual(:as => :days)
|
32
|
+
end
|
33
|
+
define_method "test_#{x}_days_from_now_as_days" do
|
34
|
+
date = parse("in #{x} days")
|
35
|
+
assert_equal I18n.t('date.casual.days_from_now', :number => x), date.casual(:as => :days)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
data/test/test_months.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestMonths < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Test month ranges both with and without the :as => :months option
|
6
|
+
[nil, {:as => :months}].each do |options|
|
7
|
+
define_method method_name('less_than_a_month_ago', options) do
|
8
|
+
date = parse('3 weeks ago')
|
9
|
+
assert_equal I18n.t('date.casual.less_than_a_month_ago'), date.casual(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
define_method method_name('less_than_a_month_from_now', options) do
|
13
|
+
date = parse('in 3 weeks')
|
14
|
+
assert_equal I18n.t('date.casual.less_than_a_month_from_now'), date.casual(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method method_name('exactly_one_month_from_now', options) do
|
18
|
+
date = parse('1 month from now')
|
19
|
+
assert_equal I18n.t('date.casual.next_month'), date.casual(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
define_method method_name('exactly_one_month_ago', options) do
|
23
|
+
date = parse('1 month ago')
|
24
|
+
assert_equal I18n.t('date.casual.last_month'), date.casual(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method method_name('next_month', options) do
|
28
|
+
date = parse('in 1 month') + 1
|
29
|
+
assert_equal I18n.t('date.casual.next_month'), date.casual(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method method_name('last_month', options) do
|
33
|
+
date = parse('1 month ago') - 1
|
34
|
+
assert_equal I18n.t('date.casual.last_month'), date.casual(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
define_method method_name('couple_of_months_from_now', options) do
|
38
|
+
date = parse('in 2 months')
|
39
|
+
assert_equal I18n.t('date.casual.couple_of_months_from_now'), date.casual(options)
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method method_name('couple_of_months_ago', options) do
|
43
|
+
date = parse('2 months ago')
|
44
|
+
assert_equal I18n.t('date.casual.couple_of_months_ago'), date.casual(options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
(3..24).each do |x|
|
49
|
+
define_method "test_#{x}_months_ago_as_months" do
|
50
|
+
date = parse("#{x} months ago")
|
51
|
+
assert_equal I18n.t('date.casual.months_ago', :number => x), date.casual(:as => :months)
|
52
|
+
end
|
53
|
+
define_method "test_#{x}_months_from_now_as_months" do
|
54
|
+
date = parse("in #{x} months")
|
55
|
+
assert_equal I18n.t('date.casual.months_from_now', :number => x), date.casual(:as => :months)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/test/test_weeks.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestWeeks < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Test week ranges both with and without the :as => :weeks option
|
6
|
+
[nil, {:as => :weeks}].each do |options|
|
7
|
+
|
8
|
+
define_method method_name('next_week', options) do
|
9
|
+
date = DateCasually::Calculator.this_week_range.last + 3
|
10
|
+
assert_equal I18n.t('date.casual.next_week'), date.casual(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
define_method method_name('last_week', options) do
|
14
|
+
date = DateCasually::Calculator.last_sunday + 1
|
15
|
+
assert_equal I18n.t('date.casual.last_week'), date.casual(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
define_method method_name('couple_of_weeks_from_now', options) do
|
19
|
+
date = parse('in 2 weeks')
|
20
|
+
assert_equal I18n.t('date.casual.couple_of_weeks_from_now'), date.casual(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
define_method method_name('couple_of_weeks_ago', options) do
|
24
|
+
date = parse('2 weeks ago')
|
25
|
+
assert_equal I18n.t('date.casual.couple_of_weeks_ago'), date.casual(options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
(3..53).each do |x|
|
30
|
+
define_method "test_#{x}_weeks_ago_as_weeks" do
|
31
|
+
date = parse("#{x} weeks ago")
|
32
|
+
assert_equal I18n.t('date.casual.weeks_ago', :number => x), date.casual(:as => :weeks)
|
33
|
+
end
|
34
|
+
define_method "test_#{x}_weeks_from_now_as_weeks" do
|
35
|
+
date = parse("in #{x} weeks")
|
36
|
+
assert_equal I18n.t('date.casual.weeks_from_now', :number => x), date.casual(:as => :weeks)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/test/test_years.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestYears < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Test year ranges both with and without the :as => :years option
|
6
|
+
[nil, {:as => :years}].each do |options|
|
7
|
+
define_method method_name('less_than_a_year_ago', options) do
|
8
|
+
date = parse('3 months ago')
|
9
|
+
assert_equal I18n.t('date.casual.less_than_a_year_ago'), date.casual(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
define_method method_name('less_than_a_year_from_now', options) do
|
13
|
+
date = parse('in 3 months')
|
14
|
+
assert_equal I18n.t('date.casual.less_than_a_year_from_now'), date.casual(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method method_name('exactly_one_year_from_now', options) do
|
18
|
+
date = parse('in 1 year')
|
19
|
+
assert_equal I18n.t('date.casual.next_year'), date.casual(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
define_method method_name('exactly_one_year_ago', options) do
|
23
|
+
date = parse('1 year ago')
|
24
|
+
assert_equal I18n.t('date.casual.last_year'), date.casual(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method method_name('next_year', options) do
|
28
|
+
date = parse('in 1 year') + 2
|
29
|
+
assert_equal I18n.t('date.casual.next_year'), date.casual(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method method_name('last_year', options) do
|
33
|
+
date = parse('1 year ago') - 2
|
34
|
+
assert_equal I18n.t('date.casual.last_year'), date.casual(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
define_method method_name('couple_of_years_from_now', options) do
|
38
|
+
date = parse('in 2 years')
|
39
|
+
assert_equal I18n.t('date.casual.couple_of_years_from_now'), date.casual(options)
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method method_name('couple_of_years_ago', options) do
|
43
|
+
date = parse('2 years ago')
|
44
|
+
assert_equal I18n.t('date.casual.couple_of_years_ago'), date.casual(options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Since years is our highest unit of time (as opposed to decades, etc),
|
48
|
+
# we'll also test year counts both with and without the :as => :years option.
|
49
|
+
(3..10).each do |x|
|
50
|
+
define_method method_name("#{x}_years_ago", options) do
|
51
|
+
date = parse("#{x} years ago")
|
52
|
+
assert_equal I18n.t('date.casual.years_ago', :number => x), date.casual(options)
|
53
|
+
end
|
54
|
+
define_method method_name("#{x}_years_from_now", options) do
|
55
|
+
date = parse("in #{x} years")
|
56
|
+
assert_equal I18n.t('date.casual.years_from_now', :number => x), date.casual(options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/test/timeline.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'helper'
|
2
|
+
# max = 400
|
3
|
+
# as = :week
|
4
|
+
# max.downto(1).each do |x|
|
5
|
+
# puts "+#{(Date.today + x).to_s} = #{(Date.today + x).casual(:as => as)}"
|
6
|
+
# end
|
7
|
+
# 1.upto(max).each do |x|
|
8
|
+
# puts "-#{(Date.today - x).to_s} = #{(Date.today - x).casual(:as => as)}"
|
9
|
+
# end
|
10
|
+
DateCasually::Config.as = :months
|
11
|
+
puts (Date.today + 1).casual
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: date-casually
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 0.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Theo Mills
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-26 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: i18n
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 4
|
33
|
+
- 1
|
34
|
+
version: 0.4.1
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: timecop
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 25
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 3
|
49
|
+
- 5
|
50
|
+
version: 0.3.5
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: chronic
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 17
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 2
|
65
|
+
- 3
|
66
|
+
version: 0.2.3
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
description: If you've never liked (and always seem to forget) the name of the Rails distance_of_time_in_words_to_now helper method, then it's time to date casually.
|
70
|
+
email: twmills@twmills.com
|
71
|
+
executables: []
|
72
|
+
|
73
|
+
extensions: []
|
74
|
+
|
75
|
+
extra_rdoc_files:
|
76
|
+
- LICENSE
|
77
|
+
- README.rdoc
|
78
|
+
files:
|
79
|
+
- .document
|
80
|
+
- .gitignore
|
81
|
+
- LICENSE
|
82
|
+
- README.rdoc
|
83
|
+
- Rakefile
|
84
|
+
- VERSION
|
85
|
+
- date-casually.gemspec
|
86
|
+
- lib/date-casually.rb
|
87
|
+
- lib/date-casually/calculator.rb
|
88
|
+
- lib/date-casually/config.rb
|
89
|
+
- lib/date-casually/translator.rb
|
90
|
+
- lib/date-casually/translators/day_of_week.rb
|
91
|
+
- lib/date-casually/translators/days.rb
|
92
|
+
- lib/date-casually/translators/months.rb
|
93
|
+
- lib/date-casually/translators/weeks.rb
|
94
|
+
- lib/date-casually/translators/years.rb
|
95
|
+
- lib/extensions/date.rb
|
96
|
+
- lib/locale/en.yml
|
97
|
+
- lib/locale/en.yml.sorted
|
98
|
+
- lib/util/alphabetize_yaml.rb
|
99
|
+
- test/helper.rb
|
100
|
+
- test/test_calculator.rb
|
101
|
+
- test/test_date-casually.rb
|
102
|
+
- test/test_day_of_week.rb
|
103
|
+
- test/test_days.rb
|
104
|
+
- test/test_months.rb
|
105
|
+
- test/test_translator.rb
|
106
|
+
- test/test_weeks.rb
|
107
|
+
- test/test_years.rb
|
108
|
+
- test/timeline.rb
|
109
|
+
has_rdoc: true
|
110
|
+
homepage: http://github.com/twmills/date-casually
|
111
|
+
licenses: []
|
112
|
+
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options:
|
115
|
+
- --charset=UTF-8
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
hash: 3
|
124
|
+
segments:
|
125
|
+
- 0
|
126
|
+
version: "0"
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
version: "0"
|
136
|
+
requirements: []
|
137
|
+
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.3.7
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: Easy on the eyes alternative to the Rails distance_of_time_in_words_to_now helper method.
|
143
|
+
test_files:
|
144
|
+
- test/helper.rb
|
145
|
+
- test/test_calculator.rb
|
146
|
+
- test/test_date-casually.rb
|
147
|
+
- test/test_day_of_week.rb
|
148
|
+
- test/test_days.rb
|
149
|
+
- test/test_months.rb
|
150
|
+
- test/test_translator.rb
|
151
|
+
- test/test_weeks.rb
|
152
|
+
- test/test_years.rb
|
153
|
+
- test/timeline.rb
|