date-casually 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|