month 0.1.2 → 1.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.
- checksums.yaml +7 -0
- data/README.md +130 -0
- data/lib/month.rb +158 -96
- data/month.gemspec +14 -0
- data/spec/month_spec.rb +238 -0
- metadata +69 -57
- data/Manifest.txt +0 -7
- data/README.txt +0 -7
- data/changelog.txt +0 -9
- data/install.rb +0 -164
- data/rakefile +0 -44
- data/test/ts_month.rb +0 -68
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7a5b582cedcab3ae50a07ede99a2036cdf836d6
|
4
|
+
data.tar.gz: 74a2c8bfc2bf430a86cf9b1edadb26d20f047db8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2a262762f6b7699fc8031a4d4d304b85751682d7d5efa3e769961c379cf306b6ffeaeb1518067100befe4c3a7998bb1846f005a992a5b1ff22918377fdb55462
|
7
|
+
data.tar.gz: d069fd96c3e81f3e4b19d9e851103db1199d42ca100733b323b0ea680cf948bf985a412356d7f03a150f8b0d3da752e24dffae611525e1dff481ff5d9a19e970
|
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
month
|
2
|
+
=====
|
3
|
+
|
4
|
+
|
5
|
+
A little library for working with months.
|
6
|
+
|
7
|
+
|
8
|
+
Feature tour
|
9
|
+
------------
|
10
|
+
|
11
|
+
You can create a new Month object by passing the year and the month number
|
12
|
+
as arguments to the constructor:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
Month.new(2014, 1) # January 2014
|
16
|
+
```
|
17
|
+
|
18
|
+
Alternatively you can use the Month method to cast various date/time
|
19
|
+
objects to Month objects:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
Month(Date.new(2014, 1, 31)) # January 2014
|
23
|
+
|
24
|
+
Month(Time.at(1234567890)) # February 2009
|
25
|
+
```
|
26
|
+
|
27
|
+
The method will idempotently return Month objects as-is:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Month(Month.new(2014, 1)) # January 2014, same object
|
31
|
+
```
|
32
|
+
|
33
|
+
Use the Month.parse method to parse a YYYY-MM formatted string:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Month.parse('2014-01') # January 2014
|
37
|
+
```
|
38
|
+
|
39
|
+
The #year attribute will return the year of the month:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Month.new(2014, 1).year # 2014
|
43
|
+
```
|
44
|
+
|
45
|
+
The #number attribute will return the number of the month:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
Month.new(2014, 1).number # 1
|
49
|
+
```
|
50
|
+
|
51
|
+
The #name method will return the name of the month as a symbol:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Month.new(2014, 1).name # :January
|
55
|
+
```
|
56
|
+
|
57
|
+
Alternatively you can use predicate methods to test for a given month:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
Month.new(2014, 1).january? # true
|
61
|
+
|
62
|
+
Month.new(2014, 2).january? # false
|
63
|
+
```
|
64
|
+
|
65
|
+
The #to_s method will return a YYYY-MM formatted string representation
|
66
|
+
of the month:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Month.new(2014, 1).to_s # "2014-01"
|
70
|
+
```
|
71
|
+
|
72
|
+
You can add/subtract an integer number of months:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Month.new(2014, 1) + 1 # February 2014
|
76
|
+
|
77
|
+
Month.new(2014, 1) - 1 # December 2013
|
78
|
+
```
|
79
|
+
|
80
|
+
The #step method iterates between 2 months, similar to Date#step:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
Month.new(2014, 1).step(Month.new(2014, 12)) do |month|
|
84
|
+
...
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
The #include? method can be used to test if the month includes a date:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Month.new(2014, 1).include?(Date.new(2014, 1, 31)) # true
|
92
|
+
```
|
93
|
+
|
94
|
+
The #dates method returns a range containing the dates in the month:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Month.new(2014, 1).dates # Range containing 31 Date objects
|
98
|
+
```
|
99
|
+
|
100
|
+
The #length method returns the number of days in the month:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
Month.new(2014, 1).length # 31
|
104
|
+
```
|
105
|
+
|
106
|
+
Month objects can be used in case expressions.
|
107
|
+
|
108
|
+
Month objects can be used as hash keys.
|
109
|
+
|
110
|
+
Month objects can be used in ranges.
|
111
|
+
|
112
|
+
Month objects are comparable.
|
113
|
+
|
114
|
+
|
115
|
+
Bonus Extras
|
116
|
+
------------
|
117
|
+
|
118
|
+
The Month::Methods module provides methods for constructing Month objects
|
119
|
+
and Date objects in a manner that closely resembles written english:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
include Month::Methods
|
123
|
+
|
124
|
+
month = January 2014
|
125
|
+
|
126
|
+
date = January 15, 2014
|
127
|
+
```
|
128
|
+
|
129
|
+
It is not included by default, you can either include it within your
|
130
|
+
own modules/classes or globally within your application/script.
|
data/lib/month.rb
CHANGED
@@ -1,98 +1,160 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Month
|
4
|
+
NAMES = {
|
5
|
+
1 => :January,
|
6
|
+
2 => :February,
|
7
|
+
3 => :March,
|
8
|
+
4 => :April,
|
9
|
+
5 => :May,
|
10
|
+
6 => :June,
|
11
|
+
7 => :July,
|
12
|
+
8 => :August,
|
13
|
+
9 => :September,
|
14
|
+
10 => :October,
|
15
|
+
11 => :November,
|
16
|
+
12 => :December
|
17
|
+
}
|
18
|
+
|
19
|
+
def initialize(year, number)
|
20
|
+
unless NAMES.has_key?(number)
|
21
|
+
raise ArgumentError, 'invalid month number'
|
22
|
+
end
|
23
|
+
|
24
|
+
@year, @number = year, number
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :year, :number
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"#@year-#{@number.to_s.rjust(2, '0')}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def name
|
34
|
+
NAMES.fetch(@number)
|
35
|
+
end
|
36
|
+
|
37
|
+
NAMES.each do |number, name|
|
38
|
+
define_method(:"#{name.downcase}?") do
|
39
|
+
@number == number
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def hash
|
44
|
+
[@year, @number].hash
|
45
|
+
end
|
46
|
+
|
47
|
+
def eql?(object)
|
48
|
+
object.class == self.class && object.hash == self.hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def <=>(month)
|
52
|
+
if @year == month.year
|
53
|
+
@number <=> month.number
|
54
|
+
else
|
55
|
+
@year <=> month.year
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
include Comparable
|
60
|
+
|
61
|
+
def next
|
62
|
+
if @number == 12
|
63
|
+
self.class.new(@year + 1, 1)
|
64
|
+
else
|
65
|
+
self.class.new(@year, @number + 1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :succ, :next
|
70
|
+
|
71
|
+
def step(limit)
|
72
|
+
unless block_given?
|
73
|
+
return enum_for(:step, limit)
|
74
|
+
end
|
75
|
+
|
76
|
+
month = self
|
77
|
+
|
78
|
+
until month > limit
|
79
|
+
yield month
|
80
|
+
|
81
|
+
month = month.succ
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def +(number)
|
86
|
+
a, b = (@number + number).divmod(12)
|
87
|
+
|
88
|
+
self.class.new(@year + a, b)
|
89
|
+
end
|
90
|
+
|
91
|
+
def -(number)
|
92
|
+
if @number > number
|
93
|
+
self.class.new(@year, @number - number)
|
94
|
+
elsif @number < number
|
95
|
+
a, b = (@number - number).divmod(12)
|
96
|
+
|
97
|
+
self.class.new(@year + a, b)
|
98
|
+
else
|
99
|
+
self.class.new(@year - 1, 12)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def include?(date)
|
104
|
+
@year == date.year && @number == date.month
|
105
|
+
end
|
106
|
+
|
107
|
+
alias_method :===, :include?
|
108
|
+
|
109
|
+
def start_date
|
110
|
+
Date.new(@year, @number, 1)
|
111
|
+
end
|
112
|
+
|
113
|
+
def end_date
|
114
|
+
Date.new(@year, @number, -1)
|
115
|
+
end
|
116
|
+
|
117
|
+
def dates
|
118
|
+
start_date .. end_date
|
119
|
+
end
|
120
|
+
|
121
|
+
def length
|
122
|
+
end_date.mday
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def Month.parse(string)
|
127
|
+
if string =~ /\A(\d{4})-(\d{2})\z/
|
128
|
+
Month.new($1.to_i, $2.to_i)
|
129
|
+
else
|
130
|
+
raise ArgumentError, 'invalid month'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def Month(object)
|
135
|
+
case object
|
136
|
+
when Month
|
137
|
+
object
|
138
|
+
when Integer
|
139
|
+
Month(Time.at(object))
|
140
|
+
else
|
141
|
+
Month.new(object.year, object.month)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
7
145
|
class Month
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
# Month.new with no arguments to receive the current month.
|
23
|
-
def initialize( year = nil, month = nil )
|
24
|
-
require 'date'
|
25
|
-
if month.nil? || year.nil?
|
26
|
-
date = Date.today
|
27
|
-
month = date.mon unless month
|
28
|
-
year = date.year unless year
|
29
|
-
end
|
30
|
-
fail "invalid month" if month < 1 || month > 12
|
31
|
-
@month = month
|
32
|
-
@year = year
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns a new Month that is +amountToAdd+ months later.
|
36
|
-
def +( amountToAdd )
|
37
|
-
( fullYears, remainingMonths ) = amountToAdd.divmod( 12 )
|
38
|
-
resultYear = @year + fullYears
|
39
|
-
resultMonth = @month + remainingMonths
|
40
|
-
if resultMonth > 12
|
41
|
-
resultMonth -= 12
|
42
|
-
resultYear += 1
|
43
|
-
end
|
44
|
-
Month.new( resultYear, resultMonth )
|
45
|
-
end
|
46
|
-
|
47
|
-
# Returns a new Month that is +amountToSubtract+ months earlier.
|
48
|
-
def -(amountToSubtract)
|
49
|
-
self + (-amountToSubtract)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Compare this Month to another Month.
|
53
|
-
def <=>(anOther)
|
54
|
-
if @year == anOther.year
|
55
|
-
@month <=> anOther.month
|
56
|
-
else
|
57
|
-
@year <=> anOther.year
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns the last Date of the month.
|
62
|
-
def end_date
|
63
|
-
self.next.start_date - 1
|
64
|
-
end
|
65
|
-
|
66
|
-
# Is this Month equal to +anOther+? +anOther+ must be another Month of the
|
67
|
-
# same value.
|
68
|
-
def eql?(anOther)
|
69
|
-
self == anOther
|
70
|
-
end
|
71
|
-
|
72
|
-
# Calculate a hash value for this Month.
|
73
|
-
def hash
|
74
|
-
"#{@year}#{@month}".to_i
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns the next Month.
|
78
|
-
def next
|
79
|
-
self + 1
|
80
|
-
end
|
81
|
-
|
82
|
-
alias_method :succ, :next
|
83
|
-
|
84
|
-
# Returns the previous Month.
|
85
|
-
def prev
|
86
|
-
self - 1
|
87
|
-
end
|
88
|
-
|
89
|
-
# Returns the first Date of the month.
|
90
|
-
def start_date
|
91
|
-
Date.new( @year, @month, 1 )
|
92
|
-
end
|
93
|
-
|
94
|
-
# Returns a string of the format "January 2001".
|
95
|
-
def to_s
|
96
|
-
Month.month_names[@month-1][0..2] + " " + @year.to_s
|
97
|
-
end
|
146
|
+
module Methods
|
147
|
+
NAMES.each do |number, name|
|
148
|
+
define_method(name) do |*args|
|
149
|
+
case args.length
|
150
|
+
when 1
|
151
|
+
Month.new(args.first, number)
|
152
|
+
when 2
|
153
|
+
Date.new(args[1], number, args[0])
|
154
|
+
else
|
155
|
+
raise ArgumentError, 'too many arguments'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
98
160
|
end
|
data/month.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'month'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.authors = ['Tim Craft']
|
6
|
+
s.email = ['mail@timcraft.com']
|
7
|
+
s.homepage = 'http://github.com/timcraft/month'
|
8
|
+
s.description = 'A little library for working with months'
|
9
|
+
s.summary = 'See description'
|
10
|
+
s.files = Dir.glob('{lib,spec}/**/*') + %w(README.md month.gemspec)
|
11
|
+
s.add_development_dependency('rake', '~> 10.0')
|
12
|
+
s.add_development_dependency('minitest', '~> 5.0')
|
13
|
+
s.require_path = 'lib'
|
14
|
+
end
|
data/spec/month_spec.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require_relative '../lib/month'
|
4
|
+
|
5
|
+
describe 'Month' do
|
6
|
+
it 'raises an exception when initialized with an invalid number' do
|
7
|
+
proc { Month.new(2014, 0) }.must_raise(ArgumentError)
|
8
|
+
proc { Month.new(2014, 100) }.must_raise(ArgumentError)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'year method' do
|
12
|
+
it 'returns the integer year of the month' do
|
13
|
+
Month.new(2014, 1).year.must_equal(2014)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'number method' do
|
18
|
+
it 'returns the integer number of the month' do
|
19
|
+
Month.new(2014, 1).number.must_equal(1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'to_s method' do
|
24
|
+
it 'returns a string containing the year and zero padded number of the month' do
|
25
|
+
Month.new(2014, 1).to_s.must_equal('2014-01')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'name method' do
|
30
|
+
it 'returns the name of the month' do
|
31
|
+
Month.new(2014, 1).name.must_equal(:January)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'january predicate method' do
|
36
|
+
it 'returns true if the month is january' do
|
37
|
+
Month.new(2014, 1).january?.must_equal(true)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns false otherwise' do
|
41
|
+
Month.new(2014, 2).january?.must_equal(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'february predicate method' do
|
46
|
+
it 'returns true if the month is february' do
|
47
|
+
Month.new(2014, 2).february?.must_equal(true)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns false otherwise' do
|
51
|
+
Month.new(2014, 1).february?.must_equal(false)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'supports being used as a hash key' do
|
56
|
+
hash, n = Hash.new(0), 10
|
57
|
+
|
58
|
+
n.times { hash[Month.new(2014, 1)] += 1 }
|
59
|
+
|
60
|
+
hash.count.must_equal(1)
|
61
|
+
hash[Month.new(2014, 1)].must_equal(n)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'supports comparison between month objects' do
|
65
|
+
Month.new(2014, 1).must_be_kind_of(Comparable)
|
66
|
+
|
67
|
+
(Month.new(2014, 1) == Month.new(2014, 1)).must_equal(true)
|
68
|
+
(Month.new(2014, 1) == Month.new(2014, 2)).must_equal(false)
|
69
|
+
|
70
|
+
(Month.new(2014, 1) < Month.new(2014, 2)).must_equal(true)
|
71
|
+
(Month.new(2014, 2) > Month.new(2014, 1)).must_equal(true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'supports being used in a range' do
|
75
|
+
range = Month.new(2014, 1) .. Month.new(2014, 4)
|
76
|
+
|
77
|
+
range.map(&:number).must_equal([1, 2, 3, 4])
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'next method' do
|
81
|
+
it 'returns a month object denoting the next month' do
|
82
|
+
Month.new(2014, 1).next.must_equal(Month.new(2014, 2))
|
83
|
+
Month.new(2014, 12).next.must_equal(Month.new(2015, 1))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'succ method' do
|
88
|
+
it 'returns a month object denoting the next month' do
|
89
|
+
Month.new(2014, 1).succ.must_equal(Month.new(2014, 2))
|
90
|
+
Month.new(2014, 12).succ.must_equal(Month.new(2015, 1))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'step method' do
|
95
|
+
it 'calls the block for every month until the given limit' do
|
96
|
+
months = []
|
97
|
+
|
98
|
+
Month.new(2014, 1).step(Month.new(2014, 3)) { |month| months << month }
|
99
|
+
|
100
|
+
months.must_equal([Month.new(2014, 1), Month.new(2014, 2), Month.new(2014, 3)])
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns an enumerator if no block was given' do
|
104
|
+
months = Month.new(2014, 1).step(Month.new(2014, 3))
|
105
|
+
|
106
|
+
months.must_be_instance_of(Enumerator)
|
107
|
+
|
108
|
+
months.next.must_equal(Month.new(2014, 1))
|
109
|
+
months.next.must_equal(Month.new(2014, 2))
|
110
|
+
months.next.must_equal(Month.new(2014, 3))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe 'addition' do
|
115
|
+
it 'returns a month object denoting the given number of months after self' do
|
116
|
+
(Month.new(2014, 1) + 1).must_equal(Month.new(2014, 2))
|
117
|
+
(Month.new(2014, 1) + 12).must_equal(Month.new(2015, 1))
|
118
|
+
(Month.new(2014, 1) + 18).must_equal(Month.new(2015, 7))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe 'subtraction' do
|
123
|
+
it 'returns a month object denoting the given number of months before self' do
|
124
|
+
(Month.new(2014, 2) - 1).must_equal(Month.new(2014, 1))
|
125
|
+
(Month.new(2014, 1) - 1).must_equal(Month.new(2013, 12))
|
126
|
+
(Month.new(2014, 1) - 12).must_equal(Month.new(2013, 1))
|
127
|
+
(Month.new(2014, 1) - 18).must_equal(Month.new(2012, 7))
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'include predicate method' do
|
132
|
+
it 'returns true if the month includes the given date' do
|
133
|
+
Month.new(2014, 1).include?(Date.new(2014, 1, 1)).must_equal(true)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'returns false otherwise' do
|
137
|
+
Month.new(2014, 1).include?(Date.new(2014, 2, 1)).must_equal(false)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'case equals method' do
|
142
|
+
it 'returns true if the month includes the given date' do
|
143
|
+
(Month.new(2014, 1) === Date.new(2014, 1, 1)).must_equal(true)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'returns false otherwise' do
|
147
|
+
(Month.new(2014, 1) === Date.new(2014, 2, 1)).must_equal(false)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'start_date method' do
|
152
|
+
it 'returns a date object denoting the first day of the month' do
|
153
|
+
Month.new(2014, 1).start_date.must_equal(Date.new(2014, 1, 1))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'end_date method' do
|
158
|
+
it 'returns a date object denoting the last day of the month' do
|
159
|
+
Month.new(2014, 1).end_date.must_equal(Date.new(2014, 1, 31))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe 'dates method' do
|
164
|
+
it 'returns the range of dates in the month' do
|
165
|
+
dates = Month.new(2014, 1).dates
|
166
|
+
dates.must_be_instance_of(Range)
|
167
|
+
dates.count.must_equal(31)
|
168
|
+
dates.all? { |date| Date === date }.must_equal(true)
|
169
|
+
dates.first.must_equal(Date.new(2014, 1, 1))
|
170
|
+
dates.last.must_equal(Date.new(2014, 1, 31))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe 'length method' do
|
175
|
+
it 'returns the integer number of days in the month' do
|
176
|
+
Month.new(2014, 1).length.must_equal(31)
|
177
|
+
Month.new(2014, 2).length.must_equal(28)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'Month parse method' do
|
183
|
+
it 'returns the month corresponding to the given string representation' do
|
184
|
+
Month.parse('2014-01').must_equal(Month.new(2014, 1))
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'raises an exception if the format of the string is not as expected' do
|
188
|
+
proc { Month.parse('January 2014') }.must_raise(ArgumentError)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe 'Month method' do
|
193
|
+
it 'returns the month of the given date object' do
|
194
|
+
Month(Date.new(2014, 1, 1)).must_equal(Month.new(2014, 1))
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'returns the month of the given time object' do
|
198
|
+
Month(Time.at(1234567890)).must_equal(Month.new(2009, 2))
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'returns the month of the given datetime object' do
|
202
|
+
Month(DateTime.parse('2001-02-03T04:05:06+07:00')).must_equal(Month.new(2001, 2))
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'returns the month of the given integer unix timestamp' do
|
206
|
+
Month(1234567890).must_equal(Month.new(2009, 2))
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'idempotently returns the given month' do
|
210
|
+
month = Month.new(2014, 1)
|
211
|
+
|
212
|
+
Month(month).object_id.must_equal(month.object_id)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe 'A method defined in Month::Methods' do
|
217
|
+
include Month::Methods
|
218
|
+
|
219
|
+
it 'returns a month object denoting that month in the given year' do
|
220
|
+
month = January 2014
|
221
|
+
month.must_equal(Month.new(2014, 1))
|
222
|
+
|
223
|
+
month = February 2014
|
224
|
+
month.must_equal(Month.new(2014, 2))
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns a date object when given two arguments' do
|
228
|
+
date = January 31, 2014
|
229
|
+
date.must_equal(Date.new(2014, 1, 31))
|
230
|
+
|
231
|
+
date = February 28, 2014
|
232
|
+
date.must_equal(Date.new(2014, 2, 28))
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'raises an exception if given too many arguments' do
|
236
|
+
proc { January 1, 2, 3 }.must_raise(ArgumentError)
|
237
|
+
end
|
238
|
+
end
|
metadata
CHANGED
@@ -1,63 +1,75 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.2
|
3
|
-
specification_version: 1
|
1
|
+
--- !ruby/object:Gem::Specification
|
4
2
|
name: month
|
5
|
-
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
- lib
|
11
|
-
email: sera@fhwang.net
|
12
|
-
homepage: http://month.rubyforge.org/
|
13
|
-
rubyforge_project: month
|
14
|
-
description: Ruby Month is a utility class for representing months in Ruby. It handles addition, previous and next months, end and start dates, month names (in English), and a few other handy things.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Craft
|
15
8
|
autorequire:
|
16
|
-
default_executable:
|
17
9
|
bindir: bin
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
|
35
|
-
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
-
|
47
|
-
-
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
description: A little library for working with months
|
42
|
+
email:
|
43
|
+
- mail@timcraft.com
|
48
44
|
executables: []
|
49
|
-
|
50
45
|
extensions: []
|
51
|
-
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- lib/month.rb
|
50
|
+
- month.gemspec
|
51
|
+
- spec/month_spec.rb
|
52
|
+
homepage: http://github.com/timcraft/month
|
53
|
+
licenses: []
|
54
|
+
metadata: {}
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
52
69
|
requirements: []
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
requirements:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 1.3.0
|
63
|
-
version:
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 2.2.2
|
72
|
+
signing_key:
|
73
|
+
specification_version: 4
|
74
|
+
summary: See description
|
75
|
+
test_files: []
|
data/Manifest.txt
DELETED
data/README.txt
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
Ruby Month is a utility class for representing months in Ruby. It handles addition, previous and next months, end and start dates, month names (in English), and a few other handy things.
|
2
|
-
|
3
|
-
http://rubyforge.org/projects/month/
|
4
|
-
|
5
|
-
INSTALLATION:
|
6
|
-
As root, run "./install.rb", which will copy the Ruby files into the right
|
7
|
-
subdirectory. You can run "./install.rb --help" for information.
|
data/changelog.txt
DELETED
data/install.rb
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
################################################################################
|
3
|
-
# #
|
4
|
-
# Name: install.rb #
|
5
|
-
# Author: Sean E Russell <ser@germane-software.com> #
|
6
|
-
# Version: $Id: install.rb,v 1.1 2007/01/08 01:46:57 francis Exp $
|
7
|
-
# Date: *2002-174 #
|
8
|
-
# Description: #
|
9
|
-
# This is a generic installation script for pure ruby sources. Features #
|
10
|
-
# include: #
|
11
|
-
# * Clean uninstall #
|
12
|
-
# * Installation into an absolute path #
|
13
|
-
# * Installation into a temp path (useful for systems like Portage) #
|
14
|
-
# * Noop mode, for testing #
|
15
|
-
# To set for a different system, change the SRC directory to point to the #
|
16
|
-
# package name / source directory for the project. #
|
17
|
-
# #
|
18
|
-
################################################################################
|
19
|
-
|
20
|
-
# CHANGE THIS
|
21
|
-
SRC = 'lib'
|
22
|
-
MODULE_NAME = 'month'
|
23
|
-
BIN = 'bin'
|
24
|
-
# CHANGE NOTHING BELOW THIS LINE
|
25
|
-
|
26
|
-
if $0 == __FILE__
|
27
|
-
Dir.chdir ".." if Dir.pwd =~ /bin.?$/
|
28
|
-
|
29
|
-
require 'getoptlong'
|
30
|
-
require 'rbconfig'
|
31
|
-
require 'ftools'
|
32
|
-
require 'find'
|
33
|
-
|
34
|
-
opts = GetoptLong.new( [ '--uninstall', '-u', GetoptLong::NO_ARGUMENT],
|
35
|
-
[ '--destdir', '-d', GetoptLong::REQUIRED_ARGUMENT ],
|
36
|
-
[ '--target', '-t', GetoptLong::REQUIRED_ARGUMENT ],
|
37
|
-
[ '--help', '-h', GetoptLong::NO_ARGUMENT],
|
38
|
-
[ '--noop', '-n', GetoptLong::NO_ARGUMENT])
|
39
|
-
|
40
|
-
|
41
|
-
destdir = File.join Config::CONFIG['sitedir'],
|
42
|
-
"#{Config::CONFIG['MAJOR']}.#{Config::CONFIG['MINOR']}"
|
43
|
-
bindir = '/usr/local/bin'
|
44
|
-
|
45
|
-
uninstall = false
|
46
|
-
append = nil
|
47
|
-
opts.each do |opt,arg|
|
48
|
-
case opt
|
49
|
-
when '--destdir'
|
50
|
-
append = arg
|
51
|
-
when '--uninstall'
|
52
|
-
uninstall = true
|
53
|
-
when '--target'
|
54
|
-
destdir = arg
|
55
|
-
when '--help'
|
56
|
-
puts "Installs #{SRC}.\nUsage:\n\t#$0 [[-u] [-n] [-t <dir>|-d <dir>]|-h]"
|
57
|
-
puts "\t-u --uninstall\tUninstalls the package"
|
58
|
-
puts "\t-t --target\tInstalls the software at an absolute location, EG:"
|
59
|
-
puts "\t #$0 -t /usr/local/lib/ruby"
|
60
|
-
puts "\t will put the software directly underneath /usr/local/lib/ruby;"
|
61
|
-
puts "\t IE, /usr/local/lib/ruby/#{SRC}"
|
62
|
-
puts "\t-d --destdir\tInstalls the software at a relative location, EG:"
|
63
|
-
puts "\t #$0 -d /tmp"
|
64
|
-
puts "\t will put the software under tmp, using your ruby environment."
|
65
|
-
puts "\t IE, /tmp/#{destdir}/#{SRC}"
|
66
|
-
puts "\t-n --noop\tDon't actually do anything; just print out what it"
|
67
|
-
puts "\t would do."
|
68
|
-
exit 0
|
69
|
-
when '--noop'
|
70
|
-
NOOP = true
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
destdir = File.join append, destdir if append
|
75
|
-
|
76
|
-
def get_install_base( file )
|
77
|
-
file_parts = file.split( File::SEPARATOR )
|
78
|
-
file_parts.shift
|
79
|
-
file_parts.join( File::SEPARATOR )
|
80
|
-
end
|
81
|
-
|
82
|
-
def install destdir, bindir
|
83
|
-
puts "Installing in #{destdir}"
|
84
|
-
begin
|
85
|
-
Find.find(SRC) { |file|
|
86
|
-
next if file =~ /CVS|\.svn/
|
87
|
-
install_base = get_install_base( file )
|
88
|
-
dst = File.join( destdir, install_base )
|
89
|
-
if defined? NOOP
|
90
|
-
puts ">> #{dst}" if file =~ /\.rb$/
|
91
|
-
else
|
92
|
-
File.makedirs( File.dirname(dst) )
|
93
|
-
File.install(file, dst, 0644, true) if file =~ /\.rb$/
|
94
|
-
end
|
95
|
-
}
|
96
|
-
rescue
|
97
|
-
puts $!
|
98
|
-
end
|
99
|
-
puts "Installing binaries in #{ bindir }"
|
100
|
-
begin
|
101
|
-
Dir.entries( BIN ).each { |entry|
|
102
|
-
src = File.join( BIN, entry )
|
103
|
-
next unless FileTest.executable?( src ) && !FileTest.directory?( src )
|
104
|
-
dst = File.join( bindir, entry )
|
105
|
-
if defined? NOOP
|
106
|
-
puts ">> #{ dst }"
|
107
|
-
else
|
108
|
-
File.install( src, dst, 0755, true )
|
109
|
-
end
|
110
|
-
}
|
111
|
-
rescue
|
112
|
-
puts $!
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def uninstall destdir, bindir
|
117
|
-
puts "Uninstalling in #{destdir}"
|
118
|
-
begin
|
119
|
-
puts "Deleting:"
|
120
|
-
dirs = []
|
121
|
-
Find.find( destdir ) do |file|
|
122
|
-
if file =~ /^#{ destdir }#{ File::SEPARATOR }#{ MODULE_NAME }/
|
123
|
-
if defined? NOOP
|
124
|
-
puts "-- #{file}" if File.file? file
|
125
|
-
else
|
126
|
-
File.rm_f file,true if File.file? file
|
127
|
-
end
|
128
|
-
dirs << file if File.directory? file
|
129
|
-
end
|
130
|
-
end
|
131
|
-
dirs.sort { |x,y|
|
132
|
-
y.length <=> x.length
|
133
|
-
}.each { |d|
|
134
|
-
if defined? NOOP
|
135
|
-
puts "-- #{d}"
|
136
|
-
else
|
137
|
-
puts d
|
138
|
-
Dir.delete d
|
139
|
-
end
|
140
|
-
}
|
141
|
-
rescue
|
142
|
-
end
|
143
|
-
puts "Uninstalling binaries in #{ bindir }"
|
144
|
-
begin
|
145
|
-
Dir.entries( BIN ).each { |entry|
|
146
|
-
orig = File.join( BIN, entry )
|
147
|
-
next unless FileTest.executable?( orig ) && !FileTest.directory?( orig )
|
148
|
-
to_uninstall = File.join( bindir, entry )
|
149
|
-
if defined? NOOP
|
150
|
-
puts "-- #{to_uninstall}" if File.file? to_uninstall
|
151
|
-
else
|
152
|
-
File.rm_f to_uninstall,true if File.file? to_uninstall
|
153
|
-
end
|
154
|
-
}
|
155
|
-
rescue
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
if uninstall
|
160
|
-
uninstall destdir, bindir
|
161
|
-
else
|
162
|
-
install destdir, bindir
|
163
|
-
end
|
164
|
-
end
|
data/rakefile
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
$: << 'lib'
|
3
|
-
require 'month'
|
4
|
-
|
5
|
-
@@version_str = Month::Version
|
6
|
-
|
7
|
-
def release_tag
|
8
|
-
( uber, major, minor ) = @@version_str.split( '.' ).collect! { |str|
|
9
|
-
str.to_i
|
10
|
-
}
|
11
|
-
"rel-#{ uber }-#{ major }-#{ minor }"
|
12
|
-
end
|
13
|
-
|
14
|
-
def release_dir_name
|
15
|
-
"month-#{ @@version_str }"
|
16
|
-
end
|
17
|
-
|
18
|
-
task :export_release do
|
19
|
-
Dir.chdir('../releases')
|
20
|
-
ext = "-d:ext:francis@rubyforge.org:/var/cvs/month"
|
21
|
-
`cvs #{ ext } export -r #{ release_tag } -d #{ release_dir_name } month`
|
22
|
-
`tar zcvf month-#{ @@version_str }.tar.gz #{ release_dir_name }`
|
23
|
-
end
|
24
|
-
|
25
|
-
task :update_docs do
|
26
|
-
Dir.chdir( 'lib' )
|
27
|
-
`rdoc --op ../docs/`
|
28
|
-
end
|
29
|
-
=end
|
30
|
-
|
31
|
-
require 'hoe'
|
32
|
-
$:.unshift 'lib'
|
33
|
-
require 'month'
|
34
|
-
|
35
|
-
Hoe.new("month", Month::Version) do |p|
|
36
|
-
p.rubyforge_name = "month"
|
37
|
-
p.author = 'Francis Hwang'
|
38
|
-
p.description = p.paragraphs_of( 'README.txt', 0 ).first
|
39
|
-
p.summary = p.paragraphs_of( 'README.txt', 0 ).first
|
40
|
-
p.email = 'sera@fhwang.net'
|
41
|
-
p.url = 'http://month.rubyforge.org/'
|
42
|
-
p.changes = p.paragraphs_of( 'changelog.txt', 0 ).first
|
43
|
-
end
|
44
|
-
|
data/test/ts_month.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
$: << 'lib'
|
2
|
-
require 'month'
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
class TestMonth < Test::Unit::TestCase
|
6
|
-
def setup
|
7
|
-
@jan2000 = Month.new 2000, 1
|
8
|
-
@dec2000 = Month.new 2000, 12
|
9
|
-
@jan2001 = Month.new 2001, 1
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_arithmetic
|
13
|
-
assert_equal( Month.new( 2000, 2 ), @jan2000 + 1 )
|
14
|
-
assert_equal( Month.new( 2001, 1 ), @jan2000 + 12 )
|
15
|
-
assert_equal( Month.new( 1999, 10 ), @jan2000 - 3 )
|
16
|
-
assert_equal( Month.new( 1999, 10 ), @jan2000 + -3 )
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_checks_month
|
20
|
-
caught = false
|
21
|
-
begin
|
22
|
-
Month.new 1, 2000
|
23
|
-
rescue
|
24
|
-
caught = true
|
25
|
-
end
|
26
|
-
assert caught
|
27
|
-
Month.new 2000, 1
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_compare
|
31
|
-
assert @jan2000 < @jan2001
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_default_init_to_current_month
|
35
|
-
month = Month.new
|
36
|
-
date = Date.today
|
37
|
-
assert_equal( date.mon, month.month )
|
38
|
-
assert_equal( date.year, month.year )
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_hashable
|
42
|
-
newJan2000 = Month.new( 2000, 1 )
|
43
|
-
assert_equal @jan2000, newJan2000
|
44
|
-
assert_equal @jan2000.hash, newJan2000.hash
|
45
|
-
assert( @jan2000.eql?( newJan2000 ) )
|
46
|
-
normalHash = {}
|
47
|
-
normalHash[@jan2000] = 'q'
|
48
|
-
assert_equal 'q', normalHash[newJan2000]
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_prev_next_succ
|
52
|
-
assert_equal( @dec2000, @jan2001.prev )
|
53
|
-
assert_equal( @jan2001, @dec2000.next )
|
54
|
-
assert_equal( @jan2001, @dec2000.succ )
|
55
|
-
assert_equal( @jan2000, @jan2000.prev.next )
|
56
|
-
assert_equal( @jan2000, @jan2000.prev.succ )
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_start_date_and_end_date
|
60
|
-
assert_equal( Date.new( 2000, 12, 1 ), @dec2000.start_date )
|
61
|
-
assert_equal( Date.new( 2000, 12, 31 ), @dec2000.end_date )
|
62
|
-
assert_equal( Date.new( 1999, 2, 28 ), Month.new( 1999, 2 ).end_date )
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_to_s
|
66
|
-
assert_equal 'Jan 2000', @jan2000.to_s
|
67
|
-
end
|
68
|
-
end
|