kalendor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +34 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/MIT-LICENSE.txt +22 -0
  6. data/README.md +31 -0
  7. data/Rakefile +2 -0
  8. data/kalendor.gemspec +25 -0
  9. data/lib/kalendor.rb +9 -0
  10. data/lib/kalendor/annual.rb +15 -0
  11. data/lib/kalendor/date_helper.rb +85 -0
  12. data/lib/kalendor/date_list.rb +9 -0
  13. data/lib/kalendor/factory.rb +57 -0
  14. data/lib/kalendor/instance.rb +4 -0
  15. data/lib/kalendor/instance/annual.rb +10 -0
  16. data/lib/kalendor/instance/composite.rb +7 -0
  17. data/lib/kalendor/instance/date_list.rb +11 -0
  18. data/lib/kalendor/instance/intersect.rb +6 -0
  19. data/lib/kalendor/instance/interval.rb +10 -0
  20. data/lib/kalendor/instance/month.rb +10 -0
  21. data/lib/kalendor/instance/store.rb +12 -0
  22. data/lib/kalendor/instance/subtract.rb +10 -0
  23. data/lib/kalendor/instance/union.rb +6 -0
  24. data/lib/kalendor/instance/weekday.rb +9 -0
  25. data/lib/kalendor/intersect.rb +6 -0
  26. data/lib/kalendor/interval.rb +8 -0
  27. data/lib/kalendor/month.rb +18 -0
  28. data/lib/kalendor/named.rb +7 -0
  29. data/lib/kalendor/subtract.rb +11 -0
  30. data/lib/kalendor/union.rb +6 -0
  31. data/lib/kalendor/version.rb +3 -0
  32. data/lib/kalendor/weekday.rb +21 -0
  33. data/spec/annual_spec.rb +35 -0
  34. data/spec/date_list_spec.rb +22 -0
  35. data/spec/date_spec.rb +245 -0
  36. data/spec/examples.txt +34 -0
  37. data/spec/intersect_spec.rb +20 -0
  38. data/spec/interval_spec.rb +48 -0
  39. data/spec/month_spec.rb +57 -0
  40. data/spec/spec_helper.rb +87 -0
  41. data/spec/subtract_spec.rb +26 -0
  42. data/spec/union_spec.rb +27 -0
  43. data/spec/weekday_spec.rb +27 -0
  44. data/todo.txt +98 -0
  45. metadata +168 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ff7ade1da5a9663e8adb7a0297fb1326e62618b2
4
+ data.tar.gz: 69837728d8368cc77ef9c59beaf027531b4574b0
5
+ SHA512:
6
+ metadata.gz: 486e1bcf993cc52e07727209de693d60e1d125a5b65d02ce1dc59fb5ed28e264017a03479c7f705a61b242d285fca1426857c800ee4b546cff6994d38b20ffc1
7
+ data.tar.gz: a6b49673e62ae9f9faef5e4295dc80058124339a2cece08fbf9743ac9eec0a1ef95bcebb0b738a27c6f97b018442b1e98d5c926cc4e76b0e480407b171cbf7fb
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ lib/lisp/scratch
19
+ .#*
20
+ bm.txt
21
+ /.bundle/
22
+ /.yardoc
23
+ /Gemfile.lock
24
+ /_yardoc/
25
+ /coverage/
26
+ /doc/
27
+ /pkg/
28
+ /spec/reports/
29
+ /tmp/
30
+ *.bundle
31
+ *.so
32
+ *.o
33
+ *.a
34
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kalendor.gemspec
4
+ gemspec
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Conan Dalton conan@conandalton.net
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,31 @@
1
+ # Kalendor
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'kalendor'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install kalendor
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/kalendor/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/kalendor.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'kalendor/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "kalendor"
7
+ spec.version = Kalendor::VERSION
8
+ spec.authors = ["Conan Dalton"]
9
+ spec.email = ["conan@conandalton.net"]
10
+ spec.description = %q{Utility classes for generating sets of dates}
11
+ spec.summary = %q{Utility classes for generating sets of dates}
12
+ spec.homepage = "http://github.com/conanite/kalendor"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency 'aduki'
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency 'rspec', '>= 2.9'
24
+ spec.add_development_dependency 'rspec_numbering_formatter'
25
+ end
data/lib/kalendor.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "aduki"
2
+ require "kalendor/version"
3
+ require "kalendor/instance"
4
+ require "kalendor/date_helper"
5
+ require "kalendor/factory"
6
+
7
+ module Kalendor
8
+ module Instance ; end # marker module
9
+ end
@@ -0,0 +1,15 @@
1
+ module Kalendor
2
+ module Annual
3
+ include Instance
4
+ def get_dates from, upto
5
+ first = Date.new(from.year, annual_month, annual_date)
6
+ first = Date.new(from.year + 1, annual_month, annual_date) if first < from
7
+ result = []
8
+ while first && (first <= upto)
9
+ result << first
10
+ first = Date.new(first.year + 1, annual_month, annual_date)
11
+ end
12
+ result
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,85 @@
1
+ module Kalendor
2
+ module DateHelper
3
+ MONTH_SIZES = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
4
+
5
+ def array_wrap thing ; thing.is_a?(Array) ? thing : [thing] ; end
6
+ def date_set schedule, from, upto ; Set.new(schedule.get_dates(from, upto)) ; end
7
+
8
+ def to_date d
9
+ if d.is_a?(Date) ; d
10
+ elsif d.respond_to?(:to_date) ; d.to_date
11
+ elsif d.is_a?(Array) ; Date.new(*(d.map(&:to_i)))
12
+ elsif d ; Date.parse(d.to_s)
13
+ end
14
+ end
15
+
16
+ def build y, m, d
17
+ if m < 1
18
+ build( y - 1, m + 12, d )
19
+ elsif m > 12
20
+ build( y + 1, m - 12, d )
21
+ else
22
+ s = MONTH_SIZES[m]
23
+ if d < 1
24
+ build(y, m - 1, d + s)
25
+ elsif d > s
26
+ build(y, m + 1, d - s)
27
+ else
28
+ ::Date.new(y, m, d)
29
+ end
30
+ end
31
+ end
32
+
33
+ def last_day_of_month m ; MONTH_SIZES[m] ; end
34
+ def year d ; d.year ; end
35
+ def month d ; d.month ; end
36
+ def day d ; d.day ; end
37
+ def week_day d ; d.wday ; end
38
+
39
+ def last_year d ; build(d.year - 1, d.month, d.day) ; end
40
+ def next_year d ; d.next_year ; end
41
+ def beginning_of_year d ; build(d.year, 1, 1) ; end
42
+ def end_of_year d ; build(d.year, 12, 31) ; end
43
+
44
+ def last_month d ; build(d.year, m - 1, d.day) ; end
45
+ def next_month d ; d.next_month ; end
46
+ def beginning_of_month d ; build(d.year, d.month, 1) ; end
47
+ def end_of_month d ; build(d.year, d.month, last_day_of_month(d.month)) ; end
48
+
49
+ def last_week d ; d - 7 ; end
50
+ def next_week d ; d + 7 ; end
51
+ def beginning_of_week d ; d - ((d.wday - 1) % 7) ; end
52
+ def end_of_week d ; d + ((7 - d.wday) % 7) ; end
53
+
54
+ def yesterday d ; d - 1 ; end
55
+ def tomorrow d ; d + 1 ; end
56
+
57
+ def nth_day_of_month d
58
+ 1 + ( (d.mday - 1) / 7 )
59
+ end
60
+
61
+ def nth_last_day_of_month d
62
+ last_day = end_of_month(d).mday
63
+ - 1 - (last_day - d.mday) / 7
64
+ end
65
+
66
+ #
67
+ # return true if this is the nth of this day within the month,
68
+ # for example, if n is 2, and this is the second wednesday of the month,
69
+ # return true. If n is -1, and this is the last saturday of the month,
70
+ # return true. It doesn't matter which *day* it is, it matters whether
71
+ # it's the first, second, third, etc, or if it's the last, second last,
72
+ # third last, etc
73
+ #
74
+ def nth_day_of_month? d, n
75
+ case n <=> 0
76
+ when -1
77
+ nth_last_day_of_month(d) == n
78
+ when 0
79
+ raise ArgumentError.new("must be non-zero integer")
80
+ when 1
81
+ nth_day_of_month(d) == n
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,9 @@
1
+ require 'aduki'
2
+ require 'kalendor'
3
+
4
+ module Kalendor
5
+ module DateList
6
+ include DateHelper, Instance
7
+ def get_dates from, upto ; self.dates.select { |d| d >= from && d <= upto } ; end
8
+ end
9
+ end
@@ -0,0 +1,57 @@
1
+ require "aduki"
2
+ require "kalendor/date_helper"
3
+ require "kalendor/named"
4
+ require "kalendor/instance/date_list"
5
+ require "kalendor/instance/weekday"
6
+ require "kalendor/instance/annual"
7
+ require "kalendor/instance/month"
8
+ require "kalendor/instance/union"
9
+ require "kalendor/instance/intersect"
10
+ require "kalendor/instance/subtract"
11
+ require "kalendor/instance/interval"
12
+
13
+ module Kalendor
14
+ class Factory
15
+ include DateHelper
16
+
17
+ def named name, label, kal
18
+ Kalendor::Named.new name: name, label: label, kalendor: kal
19
+ end
20
+
21
+ def annual date, month
22
+ Kalendor::Instance::Annual.new annual_month: month, annual_date: date
23
+ end
24
+
25
+ def union *schedules
26
+ Kalendor::Instance::Union.new schedules: schedules
27
+ end
28
+
29
+ def intersect *schedules
30
+ Kalendor::Instance::Intersect.new schedules: schedules
31
+ end
32
+
33
+ def subtract x, y
34
+ Kalendor::Instance::Subtract.new include_dates: x, exclude_dates: y
35
+ end
36
+
37
+ def list *dates
38
+ Kalendor::Instance::DateList.new dates: dates.map { |d| date d }
39
+ end
40
+
41
+ def interval from, upto
42
+ Kalendor::Instance::Interval.new interval_from: date(from), interval_upto: date(upto)
43
+ end
44
+
45
+ def weekday weekday, nth_of_month=nil
46
+ Kalendor::Instance::Weekday.new weekday: weekday, nth_of_month: nth_of_month
47
+ end
48
+
49
+ def month n
50
+ Kalendor::Instance::Month.new month: n
51
+ end
52
+
53
+ alias date to_date
54
+ end
55
+
56
+ def self.build &block ; Factory.new.instance_eval &block ; end
57
+ end
@@ -0,0 +1,4 @@
1
+ module Kalendor
2
+ module Instance
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ require 'kalendor/annual'
2
+
3
+ module Kalendor
4
+ module Instance
5
+ class Annual
6
+ include Aduki::Initializer, Kalendor::Annual
7
+ attr_accessor :annual_date, :annual_month
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'aduki'
2
+ require 'kalendor'
3
+
4
+ class Kalendor::Instance::Composite
5
+ include Aduki::Initializer
6
+ attr_accessor :schedules
7
+ end
@@ -0,0 +1,11 @@
1
+ require 'kalendor/date_list'
2
+
3
+ module Kalendor
4
+ module Instance
5
+ class DateList
6
+ include Aduki::Initializer, Kalendor::DateList
7
+ attr_accessor :dates
8
+ def aduki_after_initialize ; self.dates = array_wrap(dates || []).map { |d| to_date d }.compact ; end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ require "kalendor/intersect"
2
+ require "kalendor/instance/composite"
3
+
4
+ class Kalendor::Instance::Intersect < Kalendor::Instance::Composite
5
+ include Kalendor::Intersect
6
+ end
@@ -0,0 +1,10 @@
1
+ require 'kalendor/interval'
2
+
3
+ module Kalendor
4
+ module Instance
5
+ class Interval
6
+ include Aduki::Initializer, Kalendor::Interval
7
+ attr_accessor :interval_from, :interval_upto
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'kalendor/month'
2
+
3
+ module Kalendor
4
+ module Instance
5
+ class Month
6
+ include Aduki::Initializer, Kalendor::Month
7
+ attr_accessor :month
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module Kalendor
2
+ module Instance
3
+ class Store
4
+ def initialize hsh={ } ; @store = hsh ; end
5
+ def add kal ; @store[kal.name] = kal ; end
6
+ def find name ; @store[name] ; end
7
+ def delete name ; @store.delete[name] ; end
8
+ def names ; @store.keys ; end
9
+ def list ; @store.values ; end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'kalendor/subtract'
2
+
3
+ module Kalendor
4
+ module Instance
5
+ class Subtract
6
+ include Aduki::Initializer, Kalendor::Subtract
7
+ attr_accessor :include_dates, :exclude_dates
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ require "kalendor/union"
2
+ require "kalendor/instance/composite"
3
+
4
+ class Kalendor::Instance::Union < Kalendor::Instance::Composite
5
+ include Kalendor::Union
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'kalendor'
2
+ require 'kalendor/weekday'
3
+
4
+ module Kalendor::Instance
5
+ class Weekday
6
+ include Aduki::Initializer, Kalendor::Weekday
7
+ attr_accessor :weekday, :nth_of_month
8
+ end
9
+ end