quarter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []