month 1.2.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 99d3a1f9ba6751770d9a06df16bd73ee776a8726
4
- data.tar.gz: 2939e754f6952365f4874ecf4cd6ae262975a723
2
+ SHA256:
3
+ metadata.gz: dc374de89e555a551ec3e4f67ca198a4fd0103d9bc256068b892f2405a049a6a
4
+ data.tar.gz: 8cc382ea4e97c8bbd0f234fcdb8808db495ad4ed487fbe8acb1ce7585c03d4d6
5
5
  SHA512:
6
- metadata.gz: c2e439bbb93bc6b10b0a7a0f0ead067c366660ecaa884c3a2eda73681f1ffa2032600b1964e6cc6fdb75b266f05d2065b7ab6f5a1e723de4179af7a4c82b8f11
7
- data.tar.gz: 38a4336b1e7c8ad7c258241379a174e4b9538dd76b826e0c1399efbf8e0db7fb00acf9080875f12383e9445b6665f30c3edc07d4fec4b2fb5837981e21a1e70e
6
+ metadata.gz: 11816342dee7af3574b80824283675823d703232fe39d3170e3f3ad424073584a0f4a95bae6b2ee1218b164a9d845245c2f8fe2ab63043554d2093c00abc7279
7
+ data.tar.gz: 0327fe3d9a9df8ea2957b13e28e1670585241187510a6f047883c2d0e02caea0cbb7ecb05b19f118f333ae46fd3b55d4774e654f72c785fe6cf5493142108fd1
@@ -1,4 +1,4 @@
1
- Copyright the authors and contributors. All rights reserved.
1
+ Copyright (c) 2014-2020 TIMCRAFT
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README.md CHANGED
@@ -1,18 +1,24 @@
1
- month
2
- =====
1
+ # month
3
2
 
3
+ ![Gem Version](https://badge.fury.io/rb/month.svg)
4
+ ![Build Status](https://github.com/readysteady/month/workflows/Test/badge.svg)
4
5
 
5
- A little Ruby library for working with months.
6
6
 
7
+ Ruby gem for working with months.
7
8
 
8
- Installation
9
- ------------
9
+
10
+ ## Install
11
+
12
+ Using Bundler:
13
+
14
+ $ bundle add month
15
+
16
+ Using RubyGems:
10
17
 
11
18
  $ gem install month
12
19
 
13
20
 
14
- Feature tour
15
- ------------
21
+ ## Feature tour
16
22
 
17
23
  You can create a new Month object with a year and month number:
18
24
 
@@ -117,8 +123,7 @@ Month objects can be used in ranges.
117
123
  Month objects are comparable.
118
124
 
119
125
 
120
- Bonus Extras
121
- ------------
126
+ ## Bonus extras
122
127
 
123
128
  The Month::Methods module provides methods for constructing Month objects
124
129
  and Date objects in a manner that closely resembles written english:
@@ -135,8 +140,7 @@ It is not included globally by default; you can either include it within
135
140
  your own modules/classes or globally within your own application/script.
136
141
 
137
142
 
138
- History
139
- -------
143
+ ## Thanks
140
144
 
141
145
  This current implementation is an accidental rewrite of an older library/gem
142
146
  with the same name/purpose ([fhwang / month](https://github.com/fhwang/month)).
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'date'
2
3
 
3
4
  class Month
@@ -17,19 +18,25 @@ class Month
17
18
  }
18
19
 
19
20
  def initialize(year, number)
20
- unless NAMES.has_key?(number)
21
+ unless NAMES.key?(number)
21
22
  raise ArgumentError, 'invalid month number'
22
23
  end
23
24
 
24
25
  @year, @number = year, number
26
+
27
+ freeze
25
28
  end
26
29
 
27
30
  attr_reader :year, :number
28
31
 
32
+ alias_method :month, :number
33
+
29
34
  def to_s
30
35
  "#@year-#{@number.to_s.rjust(2, '0')}"
31
36
  end
32
37
 
38
+ alias_method :iso8601, :to_s
39
+
33
40
  def name
34
41
  NAMES.fetch(@number)
35
42
  end
@@ -49,6 +56,8 @@ class Month
49
56
  end
50
57
 
51
58
  def <=>(month)
59
+ return unless month.class == self.class
60
+
52
61
  if @year == month.year
53
62
  @number <=> month.number
54
63
  else
@@ -68,6 +77,18 @@ class Month
68
77
 
69
78
  alias_method :succ, :next
70
79
 
80
+ def >>(n)
81
+ self + n
82
+ end
83
+
84
+ alias_method :next_month, :>>
85
+
86
+ def <<(n)
87
+ self - n
88
+ end
89
+
90
+ alias_method :prev_month, :<<
91
+
71
92
  def step(limit, step = 1)
72
93
  raise ArgumentError if step.zero?
73
94
 
@@ -110,7 +131,7 @@ class Month
110
131
  if object.is_a?(Integer)
111
132
  self + (-object)
112
133
  else
113
- (year * 12 + @number) - (object.year * 12 + object.number)
134
+ 12 * (year - object.year) + (@number - object.number)
114
135
  end
115
136
  end
116
137
 
@@ -137,11 +158,17 @@ class Month
137
158
  end
138
159
  end
139
160
 
140
- def Month.parse(string)
141
- if string =~ /\A(\d{4})-(\d{2})\z/
142
- Month.new($1.to_i, $2.to_i)
143
- else
144
- raise ArgumentError, 'invalid month'
161
+ class Month
162
+ REGEXP = /\A(\d{4})-(\d{2})\z/
163
+
164
+ private_constant :REGEXP
165
+
166
+ def self.parse(string)
167
+ if string =~ REGEXP
168
+ Month.new($1.to_i, $2.to_i)
169
+ else
170
+ raise ArgumentError, 'invalid month'
171
+ end
145
172
  end
146
173
  end
147
174
 
@@ -156,6 +183,14 @@ def Month(object)
156
183
  end
157
184
  end
158
185
 
186
+ def Month.today
187
+ Month(Date.today)
188
+ end
189
+
190
+ def Month.now
191
+ Month(Time.now)
192
+ end
193
+
159
194
  class Month
160
195
  module Methods
161
196
  NAMES.each do |number, name|
@@ -0,0 +1,23 @@
1
+ require 'yaml'
2
+
3
+ class Month
4
+ def encode_with(coder)
5
+ coder.represent_scalar(nil, to_s)
6
+ end
7
+
8
+ module ScalarScannerPatch
9
+ REGEXP = /\A(\d{4})-(\d{2})\z/
10
+
11
+ def tokenize(string)
12
+ if !string.empty? && string.match(REGEXP)
13
+ return Month.new($1.to_i, $2.to_i)
14
+ end
15
+
16
+ super string
17
+ end
18
+
19
+ YAML::ScalarScanner.prepend(self)
20
+ end
21
+
22
+ private_constant :ScalarScannerPatch
23
+ end
@@ -1,16 +1,20 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'month'
3
- s.version = '1.2.0'
3
+ s.version = '1.7.0'
4
4
  s.license = 'MIT'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Tim Craft']
7
7
  s.email = ['mail@timcraft.com']
8
- s.homepage = 'http://github.com/timcraft/month'
9
- s.description = 'A little Ruby library for working with months'
8
+ s.homepage = 'https://github.com/readysteady/month'
9
+ s.description = 'Ruby gem for working with months'
10
10
  s.summary = 'See description'
11
- s.files = Dir.glob('{lib,spec}/**/*') + %w(LICENSE.txt README.md month.gemspec)
11
+ s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md month.gemspec)
12
12
  s.required_ruby_version = '>= 1.9.3'
13
- s.add_development_dependency('rake', '~> 10.0')
14
- s.add_development_dependency('minitest', '~> 5.0')
15
13
  s.require_path = 'lib'
14
+ s.metadata = {
15
+ 'homepage' => 'https://github.com/readysteady/month',
16
+ 'source_code_uri' => 'https://github.com/readysteady/month',
17
+ 'bug_tracker_uri' => 'https://github.com/readysteady/month/issues',
18
+ 'changelog_uri' => 'https://github.com/readysteady/month/blob/master/CHANGES.md'
19
+ }
16
20
  end
metadata CHANGED
@@ -1,44 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: month
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Craft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-25 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 Ruby library for working with months
11
+ date: 2020-06-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby gem for working with months
42
14
  email:
43
15
  - mail@timcraft.com
44
16
  executables: []
@@ -48,12 +20,16 @@ files:
48
20
  - LICENSE.txt
49
21
  - README.md
50
22
  - lib/month.rb
23
+ - lib/month/yaml.rb
51
24
  - month.gemspec
52
- - spec/month_spec.rb
53
- homepage: http://github.com/timcraft/month
25
+ homepage: https://github.com/readysteady/month
54
26
  licenses:
55
27
  - MIT
56
- metadata: {}
28
+ metadata:
29
+ homepage: https://github.com/readysteady/month
30
+ source_code_uri: https://github.com/readysteady/month
31
+ bug_tracker_uri: https://github.com/readysteady/month/issues
32
+ changelog_uri: https://github.com/readysteady/month/blob/master/CHANGES.md
57
33
  post_install_message:
58
34
  rdoc_options: []
59
35
  require_paths:
@@ -69,8 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
45
  - !ruby/object:Gem::Version
70
46
  version: '0'
71
47
  requirements: []
72
- rubyforge_project:
73
- rubygems_version: 2.2.2
48
+ rubygems_version: 3.1.2
74
49
  signing_key:
75
50
  specification_version: 4
76
51
  summary: See description
@@ -1,308 +0,0 @@
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
-
113
- it 'raises an exception when the given step argument is zero' do
114
- proc { Month.new(2014, 1).step(Month.new(2014, 3), 0) }.must_raise(ArgumentError)
115
- end
116
-
117
- it 'increases by the given number of months if the step argument is positive' do
118
- months = []
119
-
120
- Month.new(2014, 1).step(Month.new(2014, 3), 2) { |month| months << month }
121
-
122
- months.must_equal([Month.new(2014, 1), Month.new(2014, 3)])
123
- end
124
-
125
- it 'decreases by the given number of months if the step argument is negative' do
126
- months = []
127
-
128
- Month.new(2014, 3).step(Month.new(2014, 1), -1) { |month| months << month }
129
-
130
- months.must_equal([Month.new(2014, 3), Month.new(2014, 2), Month.new(2014, 1)])
131
- end
132
- end
133
-
134
- describe 'upto method' do
135
- it 'calls the block for every month until the given limit' do
136
- months = []
137
-
138
- Month.new(2014, 1).upto(Month.new(2014, 3)) { |month| months << month }
139
-
140
- months.must_equal([Month.new(2014, 1), Month.new(2014, 2), Month.new(2014, 3)])
141
- end
142
-
143
- it 'returns an enumerator if no block was given' do
144
- months = Month.new(2014, 1).upto(Month.new(2014, 3))
145
-
146
- months.must_be_instance_of(Enumerator)
147
-
148
- months.next.must_equal(Month.new(2014, 1))
149
- months.next.must_equal(Month.new(2014, 2))
150
- months.next.must_equal(Month.new(2014, 3))
151
- end
152
- end
153
-
154
- describe 'downto method' do
155
- it 'calls the block for every month until the given limit' do
156
- months = []
157
-
158
- Month.new(2014, 3).downto(Month.new(2014, 1)) { |month| months << month }
159
-
160
- months.must_equal([Month.new(2014, 3), Month.new(2014, 2), Month.new(2014, 1)])
161
- end
162
-
163
- it 'returns an enumerator if no block was given' do
164
- months = Month.new(2014, 3).downto(Month.new(2014, 1))
165
-
166
- months.must_be_instance_of(Enumerator)
167
-
168
- months.next.must_equal(Month.new(2014, 3))
169
- months.next.must_equal(Month.new(2014, 2))
170
- months.next.must_equal(Month.new(2014, 1))
171
- end
172
- end
173
-
174
- describe 'addition' do
175
- it 'returns a month object denoting the given number of months after self' do
176
- (Month.new(2014, 1) + 1).must_equal(Month.new(2014, 2))
177
- (Month.new(2014, 1) + 12).must_equal(Month.new(2015, 1))
178
- (Month.new(2014, 1) + 18).must_equal(Month.new(2015, 7))
179
- (Month.new(2013, 11) + 1).must_equal(Month.new(2013, 12))
180
- (Month.new(2013, 11) + 2).must_equal(Month.new(2014, 1))
181
- end
182
- end
183
-
184
- describe 'subtraction' do
185
- it 'returns a month object denoting the given number of months before self' do
186
- (Month.new(2014, 2) - 1).must_equal(Month.new(2014, 1))
187
- (Month.new(2014, 1) - 1).must_equal(Month.new(2013, 12))
188
- (Month.new(2014, 1) - 12).must_equal(Month.new(2013, 1))
189
- (Month.new(2014, 1) - 18).must_equal(Month.new(2012, 7))
190
- (Month.new(2013, 12) - 1).must_equal(Month.new(2013, 11))
191
- (Month.new(2014, 1) - 2).must_equal(Month.new(2013, 11))
192
- end
193
-
194
- it 'returns the number of months between the given month and self' do
195
- (Month.new(2014, 3) - Month.new(2014, 1)).must_equal(2)
196
- (Month.new(2015, 1) - Month.new(2014, 1)).must_equal(12)
197
- (Month.new(2077, 4) - Month.new(2070, 4)).must_equal(84)
198
- end
199
- end
200
-
201
- describe 'include predicate method' do
202
- it 'returns true if the month includes the given date' do
203
- Month.new(2014, 1).include?(Date.new(2014, 1, 1)).must_equal(true)
204
- end
205
-
206
- it 'returns false otherwise' do
207
- Month.new(2014, 1).include?(Date.new(2014, 2, 1)).must_equal(false)
208
- end
209
- end
210
-
211
- describe 'case equals method' do
212
- it 'returns true if the month includes the given date' do
213
- (Month.new(2014, 1) === Date.new(2014, 1, 1)).must_equal(true)
214
- end
215
-
216
- it 'returns false otherwise' do
217
- (Month.new(2014, 1) === Date.new(2014, 2, 1)).must_equal(false)
218
- end
219
- end
220
-
221
- describe 'start_date method' do
222
- it 'returns a date object denoting the first day of the month' do
223
- Month.new(2014, 1).start_date.must_equal(Date.new(2014, 1, 1))
224
- end
225
- end
226
-
227
- describe 'end_date method' do
228
- it 'returns a date object denoting the last day of the month' do
229
- Month.new(2014, 1).end_date.must_equal(Date.new(2014, 1, 31))
230
- end
231
- end
232
-
233
- describe 'dates method' do
234
- it 'returns the range of dates in the month' do
235
- dates = Month.new(2014, 1).dates
236
- dates.must_be_instance_of(Range)
237
- dates.count.must_equal(31)
238
- dates.all? { |date| Date === date }.must_equal(true)
239
- dates.first.must_equal(Date.new(2014, 1, 1))
240
- dates.last.must_equal(Date.new(2014, 1, 31))
241
- end
242
- end
243
-
244
- describe 'length method' do
245
- it 'returns the integer number of days in the month' do
246
- Month.new(2014, 1).length.must_equal(31)
247
- Month.new(2014, 2).length.must_equal(28)
248
- end
249
- end
250
- end
251
-
252
- describe 'Month parse method' do
253
- it 'returns the month corresponding to the given string representation' do
254
- Month.parse('2014-01').must_equal(Month.new(2014, 1))
255
- end
256
-
257
- it 'raises an exception if the format of the string is not as expected' do
258
- proc { Month.parse('January 2014') }.must_raise(ArgumentError)
259
- end
260
- end
261
-
262
- describe 'Month method' do
263
- it 'returns the month of the given date object' do
264
- Month(Date.new(2014, 1, 1)).must_equal(Month.new(2014, 1))
265
- end
266
-
267
- it 'returns the month of the given time object' do
268
- Month(Time.at(1234567890)).must_equal(Month.new(2009, 2))
269
- end
270
-
271
- it 'returns the month of the given datetime object' do
272
- Month(DateTime.parse('2001-02-03T04:05:06+07:00')).must_equal(Month.new(2001, 2))
273
- end
274
-
275
- it 'returns the month of the given integer unix timestamp' do
276
- Month(1234567890).must_equal(Month.new(2009, 2))
277
- end
278
-
279
- it 'idempotently returns the given month' do
280
- month = Month.new(2014, 1)
281
-
282
- Month(month).object_id.must_equal(month.object_id)
283
- end
284
- end
285
-
286
- describe 'A method defined in Month::Methods' do
287
- include Month::Methods
288
-
289
- it 'returns a month object denoting that month in the given year' do
290
- month = January 2014
291
- month.must_equal(Month.new(2014, 1))
292
-
293
- month = February 2014
294
- month.must_equal(Month.new(2014, 2))
295
- end
296
-
297
- it 'returns a date object when given two arguments' do
298
- date = January 31, 2014
299
- date.must_equal(Date.new(2014, 1, 31))
300
-
301
- date = February 28, 2014
302
- date.must_equal(Date.new(2014, 2, 28))
303
- end
304
-
305
- it 'raises an exception if given too many arguments' do
306
- proc { January 1, 2, 3 }.must_raise(ArgumentError)
307
- end
308
- end