periods 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +22 -0
  7. data/README.md +134 -0
  8. data/Rakefile +7 -0
  9. data/lib/january.rb +22 -0
  10. data/lib/periods/classes.rb +11 -0
  11. data/lib/periods/constants.rb +16 -0
  12. data/lib/periods/date_calculator.rb +25 -0
  13. data/lib/periods/halfyear.rb +9 -0
  14. data/lib/periods/halfyearly_period.rb +8 -0
  15. data/lib/periods/modules/halfyear.rb +52 -0
  16. data/lib/periods/modules/halfyearly_period.rb +52 -0
  17. data/lib/periods/modules/month.rb +61 -0
  18. data/lib/periods/modules/monthly_period.rb +43 -0
  19. data/lib/periods/modules/period.rb +58 -0
  20. data/lib/periods/modules/quarter.rb +59 -0
  21. data/lib/periods/modules/quarterly_period.rb +55 -0
  22. data/lib/periods/modules/year.rb +85 -0
  23. data/lib/periods/modules/yearly_period.rb +57 -0
  24. data/lib/periods/modules.rb +12 -0
  25. data/lib/periods/month.rb +12 -0
  26. data/lib/periods/monthly_period.rb +12 -0
  27. data/lib/periods/period.rb +9 -0
  28. data/lib/periods/quarter.rb +9 -0
  29. data/lib/periods/quarterly_period.rb +8 -0
  30. data/lib/periods/version.rb +3 -0
  31. data/lib/periods/year.rb +9 -0
  32. data/lib/periods/yearly_period.rb +9 -0
  33. data/lib/periods.rb +4 -0
  34. data/periods.gemspec +24 -0
  35. data/spec/lib/halfyear_spec.rb +41 -0
  36. data/spec/lib/halfyearly_period_spec.rb +74 -0
  37. data/spec/lib/january_spec.rb +44 -0
  38. data/spec/lib/month_spec.rb +58 -0
  39. data/spec/lib/monthly_period_spec.rb +35 -0
  40. data/spec/lib/period_spec.rb +75 -0
  41. data/spec/lib/periods/date_calculator_spec.rb +24 -0
  42. data/spec/lib/quarter_spec.rb +117 -0
  43. data/spec/lib/quarterly_period_spec.rb +80 -0
  44. data/spec/lib/year_spec.rb +51 -0
  45. data/spec/lib/yearly_period_spec.rb +74 -0
  46. data/spec/lint_check.rb +24 -0
  47. data/spec/spec_helper.rb +79 -0
  48. metadata +145 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e1b123692dc2c370b9fafe99dfd7c41e053c9c3
4
+ data.tar.gz: 23bde0ce3ee468d44228b68967806cdf2aca1b8a
5
+ SHA512:
6
+ metadata.gz: 01589f77ac31bfca9346442bcbeb81fb5c33af6e1fb9821e4de186ee56df645bd1c785ab820423e71bc42efadffc212578b14d8c737943c2e80301f668d3178b
7
+ data.tar.gz: 681447a4ab6ae3253593a05698b44a07804f3e000eebdda77adaeeec49909814d880500f113e2e319d22b6fedc1bf1327510a18789fe743fb01f6bf5e1de2b0c
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ /.idea
16
+ /coverage*
17
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9"
4
+ - "2.1"
5
+ - "2.2"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in periods.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Thomas Baustert
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+ [![Build Status](https://travis-ci.org/thomasbaustert/periods.svg?branch=master)](https://travis-ci.org/thomasbaustert/periods)
2
+
3
+ # Periods
4
+
5
+ **This is work in progress, no gem released!**
6
+
7
+ This gem provides period types like
8
+
9
+ * Period,
10
+ * WeeklyPeriod, Week,
11
+ * MonthlyPeriod, Month,
12
+ * QuarterlyPeriod, Quarter,
13
+ * HalfyearlyPeriod, Halfyear,
14
+ * YearlyPeriod, Year.
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'periods'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install periods
29
+
30
+ ## Usage
31
+
32
+ Require `periods` in your app:
33
+
34
+ require 'periods'
35
+
36
+ ### Period
37
+
38
+ A period is defined by a start and end date:
39
+
40
+ period = Period.for(Date.new(2015,6,25), Date.new(2015,8,19))
41
+ period.days # => 56
42
+ period.next # => 20.08.2015 - 14.10.2015
43
+ period.next.days # => 56
44
+
45
+ The start and end date can be a string too:
46
+
47
+ period = Period.for('25.06.2015', '19.08.2015')
48
+
49
+ All period models respond to the following interface:
50
+
51
+ * next
52
+ * previous
53
+ * days
54
+ * include?
55
+ * comparing (==, >=, >, <=, <)
56
+ * ...
57
+
58
+ Special period models may define additional methods (see below).
59
+
60
+ ### MonthlyPeriod
61
+
62
+ If you need a constant monthly range use `MonthlyPeriod`:
63
+
64
+ monthly = MonthPeriod.for('01.01.2015') # => 01.01.2015 - 31.01.2015
65
+ monthly.next # => 01.02.2015 - 28.02.2015
66
+
67
+ monthly = MonthPeriod.for('25.06.2015') # => 25.06.2015 - 24.07.2015
68
+ monthly.next # => 25.07.2015 - 24.08.2015
69
+ monthly.start_date # Date(25.06.2015)
70
+ monthly.end_date # Date(24.07.2015)
71
+
72
+ ### Month
73
+
74
+ If you need a calendar month starting at first day of month and ending at last day of month use `Month`:
75
+
76
+ january = Month.for('01.01.2015') # => 01.01.2015 - 31.01.2015
77
+ january.next # => 01.02.2015 - 28.02.2015
78
+
79
+ june = MonthPeriod.for('25.06.2015') # => 01.06.2015 - 30.06.2015
80
+ june.next # => 01.07.2015 - 31.07.2015
81
+ june.month # => 6
82
+ june.year # => 2015
83
+
84
+ ### QuarterlyPeriod
85
+
86
+ ### Quarter
87
+
88
+ ### HalfyearlyPeriod
89
+
90
+ ### Halfyear
91
+
92
+ ### Yearly
93
+
94
+ ### Year
95
+
96
+ ### If constants already exist
97
+
98
+ In case constants like `Month` already exist in your code stop requiring `periods` in your `Gemfile`:
99
+
100
+ gem 'periods', require: false
101
+
102
+ Require the namespaced classes only:
103
+
104
+ require 'periods/classes'
105
+
106
+ Use them like so:
107
+
108
+ month = Periods::Month.for('01.08.2015')
109
+
110
+ Alternatively require the modules only:
111
+
112
+ require 'periods/modules'
113
+
114
+ Write your own classes:
115
+
116
+ class MyMonth
117
+ include Periods::Modules::Month
118
+ end
119
+ month = MyMonth.for('01.08.2015')
120
+ ...
121
+
122
+ ## TODO
123
+
124
+ * Implement Week
125
+ * Use Time not Date
126
+ * Comment Code
127
+
128
+ ## Contributing
129
+
130
+ 1. Fork it
131
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
132
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
133
+ 4. Push to the branch (`git push origin my-new-feature`)
134
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # running spec as rake default tasks
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
7
+ require 'bundler/gem_tasks'
data/lib/january.rb ADDED
@@ -0,0 +1,22 @@
1
+ class January < Month
2
+
3
+ def self.of(year)
4
+ January.for("1.1.#{year}")
5
+ end
6
+
7
+ def next
8
+ January.for("1.1.#{year.to_i + 1}")
9
+ end
10
+
11
+ def previous
12
+ January.for("1.1.#{year.to_i - 1}")
13
+ end
14
+
15
+ def month
16
+ 1
17
+ end
18
+
19
+ def year
20
+ start_date.year
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ require 'periods/period'
2
+ require 'periods/month'
3
+ require 'periods/monthly_period'
4
+ require 'periods/quarter'
5
+ require 'periods/quarterly_period'
6
+ require 'periods/halfyear'
7
+ require 'periods/halfyearly_period'
8
+ require 'periods/year'
9
+ require 'periods/yearly_period'
10
+
11
+
@@ -0,0 +1,16 @@
1
+ require 'periods/classes'
2
+
3
+ Period = Periods::Period
4
+
5
+ Month = Periods::Month
6
+ MonthlyPeriod = Periods::MonthlyPeriod
7
+
8
+ Quarter = Periods::Quarter
9
+ QuarterlyPeriod = Periods::QuarterlyPeriod
10
+
11
+ Halfyear = Periods::Halfyear
12
+ HalfyearlyPeriod = Periods::HalfyearlyPeriod
13
+
14
+ Year = Periods::Year
15
+ YearlyPeriod = Periods::YearlyPeriod
16
+
@@ -0,0 +1,25 @@
1
+ module Periods
2
+ class DateCalculator
3
+
4
+ def initialize(date)
5
+ @date = to_date(date)
6
+ end
7
+
8
+ def beginning_of_month
9
+ _, m, y = split
10
+ to_date("#{1}.#{m}.#{y}")
11
+ end
12
+
13
+ def end_of_month
14
+ self.class.new(@date.next_month).beginning_of_month.prev_day
15
+ end
16
+
17
+ def split
18
+ @date.strftime('%d.%m.%Y').split('.')
19
+ end
20
+
21
+ def to_date(str)
22
+ ::Date.parse(str.to_s)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'periods/modules/halfyear'
2
+
3
+ module Periods
4
+ class Halfyear
5
+ include Periods::Modules::Halfyear
6
+ end
7
+ end
8
+
9
+
@@ -0,0 +1,8 @@
1
+ require 'periods/modules/halfyearly_period'
2
+
3
+ module Periods
4
+ class HalfyearlyPeriod
5
+ include Periods::Modules::HalfyearlyPeriod
6
+ end
7
+ end
8
+
@@ -0,0 +1,52 @@
1
+ require 'periods/halfyearly_period'
2
+
3
+ module Periods
4
+ module Modules
5
+ module Halfyear
6
+
7
+ def self.included(base)
8
+ base.class_eval do
9
+ include Periods::Modules::HalfyearlyPeriod
10
+ include InstanceMethods
11
+ extend ClassMethods
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ ##
17
+ # '25.06.2015' => 01.06.2015 - '30.11.2015'
18
+ #
19
+ def for(date)
20
+ new(date)
21
+ end
22
+ end
23
+
24
+ module InstanceMethods
25
+
26
+ def initialize(date)
27
+ date = Date.parse(date.to_s)
28
+ super(beginning_of_month(date), end_of_month(beginning_of_month(date).next_month(6).prev_day))
29
+ end
30
+
31
+ def months
32
+ months = [Periods::Month.for(start_date)]
33
+ 1.upto(5) do |idx|
34
+ months << Periods::Month.for(start_date.next_month(idx))
35
+ end
36
+ months
37
+ end
38
+
39
+ private
40
+
41
+ def beginning_of_month(date)
42
+ Periods::DateCalculator.new(date).beginning_of_month
43
+ end
44
+
45
+ def end_of_month(date)
46
+ Periods::DateCalculator.new(date).end_of_month
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ require 'periods/modules/period'
2
+
3
+ module Periods
4
+ module Modules
5
+ module HalfyearlyPeriod
6
+
7
+ def self.included(base)
8
+ base.class_eval do
9
+ include Periods::Modules::Period
10
+ include InstanceMethods
11
+ extend ClassMethods
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ ##
17
+ # '25.06.2015' => 25.06.2015 - '24.12.2015'
18
+ #
19
+ def for(date)
20
+ date = Date.parse(date.to_s)
21
+ new(date, date.next_month(6).prev_day)
22
+ end
23
+ end
24
+
25
+ module InstanceMethods
26
+ def next
27
+ self.class.for(start_date.next_month(6))
28
+ end
29
+
30
+ def previous
31
+ self.class.for(start_date.prev_month(6))
32
+ end
33
+
34
+ def days
35
+ (self.next.start_date - start_date).to_i
36
+ end
37
+
38
+ def include?(period)
39
+ if period.is_a?(String) || period.is_a?(Date)
40
+ super
41
+ elsif period.is_a?(Period)
42
+ start_date <= period.start_date && period.end_date <= end_date
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,61 @@
1
+ require 'periods/date_calculator'
2
+ require 'periods/modules/monthly_period'
3
+
4
+ module Periods
5
+ module Modules
6
+ module Month
7
+
8
+ def self.included(base)
9
+ base.class_eval do
10
+ include Periods::Modules::MonthlyPeriod
11
+ include InstanceMethods
12
+ extend ClassMethods
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def for(date)
18
+ new(date)
19
+ end
20
+ end
21
+
22
+ module InstanceMethods
23
+
24
+ def initialize(date)
25
+ date = Date.parse(date.to_s)
26
+ @start_date = beginning_of_month(date)
27
+ @end_date = end_of_month(date)
28
+ end
29
+
30
+ def month
31
+ start_date.month
32
+ end
33
+
34
+ alias_method :number, :month
35
+
36
+ def year
37
+ start_date.year
38
+ end
39
+
40
+ def to_s(*args)
41
+ if args.first.to_s == 'date'
42
+ "#{start_date.strftime("%m.%Y")} (#{start_date.strftime("%d.%m.%Y")} - #{end_date.strftime("%d.%m.%Y")})"
43
+ else
44
+ "#{start_date.strftime("%m.%Y")}"
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def beginning_of_month(date)
51
+ Periods::DateCalculator.new(date).beginning_of_month
52
+ end
53
+
54
+ def end_of_month(date)
55
+ Periods::DateCalculator.new(date).end_of_month
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ require 'periods/modules/period'
2
+
3
+ module Periods
4
+ module Modules
5
+ module MonthlyPeriod
6
+
7
+ def self.included(base)
8
+ base.class_eval do
9
+ include Periods::Modules::Period
10
+ include InstanceMethods
11
+ extend ClassMethods
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ ##
17
+ # '25.06.2015' => 25.06.2015 - '24.07.2015'
18
+ #
19
+ def for(date)
20
+ date = Date.parse(date.to_s)
21
+ new(date, date.next_month.prev_day)
22
+ end
23
+ end
24
+
25
+ module InstanceMethods
26
+ ##
27
+ # 25.06.2015 => 25.07.2015
28
+ #
29
+ def next
30
+ self.class.for(start_date.next_month)
31
+ end
32
+
33
+ ##
34
+ # 25.06.2015 => 25.05.2015
35
+ #
36
+ def previous
37
+ self.class.for(start_date.prev_month)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,58 @@
1
+ module Periods
2
+ module Modules
3
+ module Period
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include Comparable
8
+ include InstanceMethods
9
+ end
10
+ end
11
+
12
+ module InstanceMethods
13
+ attr_reader :start_date, :end_date
14
+
15
+ def initialize(start_date, end_date)
16
+ @start_date = Date.parse(start_date.to_s)
17
+ @end_date = Date.parse(end_date.to_s)
18
+ end
19
+
20
+ def ==(period)
21
+ start_date == period.start_date && end_date == period.end_date
22
+ end
23
+
24
+ def <=>(period)
25
+ if start_date > period.start_date
26
+ 1
27
+ elsif start_date < period.start_date
28
+ -1
29
+ else
30
+ 0
31
+ end
32
+ end
33
+
34
+ def next
35
+ self.class.new(start_date + days, end_date + days)
36
+ end
37
+
38
+ def previous
39
+ self.class.new(start_date - days, end_date - days)
40
+ end
41
+
42
+ def days
43
+ end_date.yday - start_date.yday + 1
44
+ end
45
+
46
+ def include?(date)
47
+ date = Date.parse(date.to_s)
48
+ start_date <= date && date <= end_date
49
+ end
50
+
51
+ def to_s
52
+ "#{start_date.strftime("%d.%m.%Y")} - #{end_date.strftime("%d.%m.%Y")}"
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,59 @@
1
+ require 'periods/date_calculator'
2
+ require 'periods/modules/quarterly_period'
3
+ require 'periods/month'
4
+
5
+ module Periods
6
+ module Modules
7
+ module Quarter
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ include Periods::Modules::Period
12
+ include Periods::Modules::QuarterlyPeriod
13
+ include InstanceMethods
14
+ extend ClassMethods
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ def for(date)
20
+ new(date)
21
+ end
22
+ end
23
+
24
+ module InstanceMethods
25
+
26
+ def initialize(date)
27
+ date = Date.parse(date.to_s)
28
+ @start_date = beginning_of_month(date)
29
+ @end_date = end_of_month(@start_date.next_month(2))
30
+ end
31
+
32
+ def months
33
+ [ Periods::Month.for(start_date),
34
+ Periods::Month.for(start_date.next_month),
35
+ Periods::Month.for(start_date.next_month(2)) ]
36
+ end
37
+
38
+ def start_year
39
+ start_date.year
40
+ end
41
+
42
+ def end_year
43
+ end_date.year
44
+ end
45
+
46
+ private
47
+
48
+ def beginning_of_month(date)
49
+ Periods::DateCalculator.new(date).beginning_of_month
50
+ end
51
+
52
+ def end_of_month(date)
53
+ Periods::DateCalculator.new(date).end_of_month
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,55 @@
1
+ require 'periods/date_calculator'
2
+ require 'periods/modules/period'
3
+
4
+ module Periods
5
+ module Modules
6
+ module QuarterlyPeriod
7
+
8
+ def self.included(base)
9
+ base.class_eval do
10
+ include Periods::Modules::Period
11
+ include InstanceMethods
12
+ extend ClassMethods
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ ##
18
+ # '25.06.2015' => 25.06.2015 - '24.07.2015'
19
+ #
20
+ def for(date)
21
+ date = Date.parse(date.to_s)
22
+ new(date, date.next_month(3).prev_day)
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+ ##
28
+ # 25.06.2015 => 25.07.2015
29
+ #
30
+ def next
31
+ self.class.for(start_date.next_month(3))
32
+ end
33
+
34
+ ##
35
+ # 25.06.2015 => 25.05.2015
36
+ #
37
+ def previous
38
+ self.class.for(start_date.prev_month(3))
39
+ end
40
+
41
+ def include?(period)
42
+ if period.is_a?(String) || period.is_a?(Date)
43
+ super
44
+ elsif period.is_a?(Period)
45
+ start_date <= period.start_date && period.end_date <= end_date
46
+ else
47
+ false
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+ end
55
+