quarter 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.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +4 -0
  3. data/README.md +32 -0
  4. data/lib/quarter.rb +174 -0
  5. data/quarter.gemspec +18 -0
  6. metadata +50 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ee89de1f0184f1a1c816f6da0f81544b04c1700325dbdfe018cedb709a73eb68
4
+ data.tar.gz: f5728f54665347af3b15b6396121f8667ba01488af85bccbedc62c707f67fa41
5
+ SHA512:
6
+ metadata.gz: 30c126a64d3ae114d3d244722f1f32453a96782f4d6ebf4ee264087818c7b5bca5b4619bf8b7775a9fc9b12158a0d5ec4b8a1382bdf192a0f15a80b67027a23c
7
+ data.tar.gz: 1bc3ff80ba433d9a21982d1a5b1da2183505363bb4dc98a48c3940ef5a9edb0510e9aa4ede503e94a4989688de3a742055280ab5d4056a832d84bc0b28eab2e6
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2020 TIMCRAFT
2
+
3
+ This is an Open Source project licensed under the terms of the LGPLv3 license.
4
+ Please see <http://www.gnu.org/licenses/lgpl-3.0.html> for license text.
@@ -0,0 +1,32 @@
1
+ # percentage
2
+
3
+ Ruby gem for working with standard calendar quarters.
4
+
5
+
6
+ ## Install
7
+
8
+ Using Bundler:
9
+
10
+ $ bundle add quarter
11
+
12
+ Using RubyGems:
13
+
14
+ $ gem install quarter
15
+
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ require 'quarter'
21
+
22
+ date = Date.today
23
+
24
+ quarter = Quarter(date)
25
+
26
+ p quarter.start_date
27
+ p quarter.include?(date)
28
+ p quarter.next
29
+ p quarter.name
30
+ p quarter.to_s
31
+ p quarter.iso8601
32
+ ```
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+ require 'date'
3
+
4
+ class Quarter
5
+ def initialize(year, number)
6
+ unless number.between?(1, 4)
7
+ raise ArgumentError, 'invalid quarter number'
8
+ end
9
+
10
+ @year = year
11
+
12
+ @number = number
13
+
14
+ freeze
15
+ end
16
+
17
+ attr_reader :year
18
+
19
+ attr_reader :number
20
+
21
+ def name
22
+ "Q#{@number}"
23
+ end
24
+
25
+ def to_s
26
+ "Q#{@number} #{@year}"
27
+ end
28
+
29
+ def iso8601
30
+ "#{@year}-Q#{@number}"
31
+ end
32
+
33
+ def hash
34
+ iso8601.hash
35
+ end
36
+
37
+ def eql?(other)
38
+ other.class == self.class && other.hash == self.hash
39
+ end
40
+
41
+ def <=>(other)
42
+ return unless other.class == self.class
43
+
44
+ if @year == other.year
45
+ @number <=> other.number
46
+ else
47
+ @year <=> other.year
48
+ end
49
+ end
50
+
51
+ include Comparable
52
+
53
+ def next
54
+ self + 1
55
+ end
56
+
57
+ alias_method :succ, :next
58
+
59
+ alias_method :next_quarter, :next
60
+
61
+ def prev
62
+ self - 1
63
+ end
64
+
65
+ alias_method :prev_quarter, :prev
66
+
67
+ def step(limit, step = 1)
68
+ raise ArgumentError if step.zero?
69
+
70
+ return enum_for(:step, limit, step) unless block_given?
71
+
72
+ quarter = self
73
+
74
+ operator = step > 0 ? :> : :<
75
+
76
+ until quarter.public_send(operator, limit)
77
+ yield quarter
78
+
79
+ quarter += step
80
+ end
81
+ end
82
+
83
+ def upto(max, &block)
84
+ step(max, 1, &block)
85
+ end
86
+
87
+ def downto(min, &block)
88
+ step(min, -1, &block)
89
+ end
90
+
91
+ def +(other)
92
+ years, remainder = (@number - 1 + other.to_i).divmod(4)
93
+
94
+ self.class.new(@year + years, 1 + remainder)
95
+ end
96
+
97
+ def -(other)
98
+ if other.class == self.class
99
+ (@year * 4 + @number) - (other.year * 4 + other.number)
100
+ else
101
+ self + (-other)
102
+ end
103
+ end
104
+
105
+ def include?(date)
106
+ @year == date.year && @number == Quarter(date.month)
107
+ end
108
+
109
+ alias_method :===, :include?
110
+
111
+ def start_date
112
+ Date.new(@year, @number * 3 - 2, 1)
113
+ end
114
+
115
+ def end_date
116
+ Date.new(@year, @number * 3, -1)
117
+ end
118
+
119
+ def dates
120
+ start_date .. end_date
121
+ end
122
+
123
+ def length
124
+ case @number
125
+ when 1 then Date.gregorian_leap?(@year) ? 91 : 90
126
+ when 2 then 91
127
+ when 3, 4 then 92
128
+ end
129
+ end
130
+
131
+ def months
132
+ Month.new(@year, @number) .. Month.new(@year, @number + 2)
133
+ end
134
+ end
135
+
136
+ def Quarter(object)
137
+ case object
138
+ when Quarter
139
+ object
140
+ when Integer
141
+ (object / 3.0).ceil
142
+ else
143
+ Quarter.new(object.year, Quarter(object.month))
144
+ end
145
+ end
146
+
147
+ class Quarter
148
+ REGEXP = /\AQ(1|2|3|4) (\d{4})\z/i
149
+
150
+ private_constant :REGEXP
151
+
152
+ ISO8601_REGEXP = /\A(\d{4})\-Q(1|2|3|4)\z/i
153
+
154
+ private_constant :ISO8601_REGEXP
155
+
156
+ def self.parse(string)
157
+ case string
158
+ when REGEXP
159
+ Quarter.new($2.to_i, $1.to_i)
160
+ when ISO8601_REGEXP
161
+ Quarter.new($1.to_i, $2.to_i)
162
+ else
163
+ raise ArgumentError, 'invalid quarter string'
164
+ end
165
+ end
166
+ end
167
+
168
+ def Quarter.today
169
+ Quarter(Date.today)
170
+ end
171
+
172
+ def Quarter.now
173
+ Quarter(Time.now)
174
+ end
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'quarter'
3
+ s.version = '1.0.0'
4
+ s.license = 'LGPL-3.0'
5
+ s.platform = Gem::Platform::RUBY
6
+ s.authors = ['Tim Craft']
7
+ s.email = ['mail@timcraft.com']
8
+ s.homepage = 'https://github.com/readysteady/quarter'
9
+ s.description = 'Ruby gem for working with standard calendar quarters'
10
+ s.summary = 'See description'
11
+ s.files = Dir.glob('lib/**/*.rb') + %w[LICENSE.txt README.md quarter.gemspec]
12
+ s.require_path = 'lib'
13
+ s.metadata = {
14
+ 'homepage' => 'https://github.com/readysteady/quarter',
15
+ 'source_code_uri' => 'https://github.com/readysteady/quarter',
16
+ 'bug_tracker_uri' => 'https://github.com/readysteady/quarter/issues'
17
+ }
18
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quarter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Craft
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby gem for working with standard calendar quarters
14
+ email:
15
+ - mail@timcraft.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE.txt
21
+ - README.md
22
+ - lib/quarter.rb
23
+ - quarter.gemspec
24
+ homepage: https://github.com/readysteady/quarter
25
+ licenses:
26
+ - LGPL-3.0
27
+ metadata:
28
+ homepage: https://github.com/readysteady/quarter
29
+ source_code_uri: https://github.com/readysteady/quarter
30
+ bug_tracker_uri: https://github.com/readysteady/quarter/issues
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.1.2
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: See description
50
+ test_files: []