time_pieces 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8dff9eff972d3afdaf7b581ed5a1523d6322ca96
4
+ data.tar.gz: 04cd28f75eadad0881be6e136b6f1ce30ba58348
5
+ SHA512:
6
+ metadata.gz: 271412cccca93941de02b4de970b7ac9caddc49a9f2356fea5bec374ae81d2433f79f57336f3874bb50595f3e9c122ca4e03e3c929bcca42d10b4ca0784775e6
7
+ data.tar.gz: 33efeab9c9575ec061703f737ea51bfc814b6a7b42351c5cd81e7e89e71ab99bc9c804097a45718f0ed49fd4e0795f41f4d7f5e5923eb41790bfa49b1d088f9a
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+ #group :test do
4
+ # gem "activesupport"
5
+ #
6
+ # gem "rake"
7
+ # gem "cucumber"
8
+ #end
9
+
10
+
11
+
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ time_pieces (0.2.0)
5
+ bundler
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (4.2.5.1)
11
+ i18n (~> 0.7)
12
+ json (~> 1.7, >= 1.7.7)
13
+ minitest (~> 5.1)
14
+ thread_safe (~> 0.3, >= 0.3.4)
15
+ tzinfo (~> 1.1)
16
+ builder (3.2.2)
17
+ cucumber (2.3.2)
18
+ builder (>= 2.1.2)
19
+ cucumber-core (~> 1.4.0)
20
+ cucumber-wire (~> 0.0.1)
21
+ diff-lcs (>= 1.1.3)
22
+ gherkin (~> 3.2.0)
23
+ multi_json (>= 1.7.5, < 2.0)
24
+ multi_test (>= 0.1.2)
25
+ cucumber-core (1.4.0)
26
+ gherkin (~> 3.2.0)
27
+ cucumber-wire (0.0.1)
28
+ diff-lcs (1.2.5)
29
+ gherkin (3.2.0)
30
+ i18n (0.7.0)
31
+ json (1.8.3)
32
+ minitest (5.8.4)
33
+ multi_json (1.11.2)
34
+ multi_test (0.1.2)
35
+ rake (10.5.0)
36
+ thread_safe (0.3.5)
37
+ tzinfo (1.2.2)
38
+ thread_safe (~> 0.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ activesupport (~> 4.2)
45
+ cucumber (~> 2.3.2)
46
+ rake (~> 10.5)
47
+ time_pieces!
48
+
49
+ BUNDLED WITH
50
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # TimePieces
2
+
3
+ This gem is for managing time pieces. It lets you add and subtract durations to help you with scheduling. For example if you have a duration (9:00am - 5:00pm) and you subtract the duration (1:00pm - 2:00pm) it will result in a time set with 2 time duration of (9:00am - 1:00pm) and (2:00pm - 5:00pm). You can also add durations. To make an object into a duration just use. You also have to include the method duration_copy which is used when creating new objects, for example when a duration is split.
4
+ ```ruby
5
+ include TimePieces::Duration
6
+
7
+ def duration_copy
8
+ return self.clone
9
+ end
10
+
11
+ ```
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'time_pieces'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install time_pieces
28
+
29
+ <!---
30
+ ## Usage
31
+
32
+ TODO: Write usage instructions here
33
+
34
+ ## Development
35
+
36
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
37
+
38
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
39
+ -->
40
+ ## Contributing
41
+
42
+ Bug reports and pull requests are welcome on GitHub at https://github.com/riggleg/time_pieces
43
+
44
+
45
+ ## License
46
+
47
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
48
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ <%
2
+ std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
3
+ %>
4
+ default: <%= std_opts %> features
@@ -0,0 +1,131 @@
1
+ module TimePieces
2
+ module Duration
3
+ attr_accessor :start_at_seconds, :duration_seconds
4
+ def end_at_seconds
5
+ return start_at_seconds + duration_seconds
6
+ end
7
+ def end_at_seconds=(new_end_at_seconds)
8
+ self.duration_seconds = new_end_at_seconds - start_at_seconds
9
+ end
10
+ def update_start_seconds_and_end_seconds(new_start_seconds, new_end_seconds)
11
+ self.start_at_seconds = new_start_seconds
12
+ self.end_at_seconds = new_end_seconds
13
+ return self
14
+ end
15
+ def left_duration_copy
16
+ duration_copy
17
+ end
18
+ def right_duration_copy
19
+ duration_copy
20
+ end
21
+
22
+
23
+ def overlaps_start?(other_td)
24
+ return true if (start_at_seconds >= other_td.start_at_seconds) && (start_at_seconds < other_td.end_at_seconds)
25
+ return false
26
+ end
27
+ def overlaps_end?(other_td)
28
+ return true if (end_at_seconds <= other_td.end_at_seconds) && (end_at_seconds > other_td.start_at_seconds)
29
+ return false
30
+ end
31
+ def overlaps_inside?(other_td)
32
+ return true if (other_td.end_at_seconds > start_at_seconds) && (other_td.end_at_seconds <= end_at_seconds) && (other_td.start_at_seconds >= start_at_seconds) && (other_td.start_at_seconds < end_at_seconds)
33
+ return false
34
+ end
35
+ def overlaps_outside?(other_td)
36
+ return other_td.overlaps_inside?(self)
37
+ end
38
+ def overlaps?(other_td)
39
+ return true if overlaps_outside?(other_td)
40
+ return true if overlaps_start?(other_td)
41
+ return true if overlaps_end?(other_td)
42
+ return true if overlaps_inside?(other_td)
43
+ return false
44
+ end
45
+ def touches_at_start?(other_td)
46
+ return true if other_td.end_at_seconds == start_at_seconds
47
+ return false
48
+ end
49
+ def touches_at_end?(other_td)
50
+ return true if other_td.start_at_seconds == end_at_seconds
51
+ return false
52
+ end
53
+ def touches?(other_td)
54
+ return (touches_at_start?(other_td) || touches_at_end?(other_td))
55
+ return false
56
+ end
57
+ def <=>(other)
58
+ start_at_seconds <=> other.start_at_seconds
59
+ end
60
+ def +(other_td)
61
+ ts_ret = TimeSet.new
62
+ if overlaps?(other_td)
63
+ if overlaps_start?(other_td) && !overlaps_outside?(other_td)
64
+ update_start_seconds_and_end_seconds(other_td.start_at_seconds, end_at_seconds)
65
+ ts_ret << self
66
+ return ts_ret
67
+ end
68
+ if overlaps_end?(other_td) && !overlaps_outside?(other_td)
69
+
70
+ update_start_seconds_and_end_seconds(start_at_seconds, other_td.end_at_seconds)
71
+ ts_ret << self
72
+ return ts_ret
73
+ end
74
+ if overlaps_inside?(other_td)
75
+ ts_ret << self
76
+ return ts_ret
77
+ end
78
+ if overlaps_outside?(other_td)
79
+ ts_ret << other_td
80
+ end
81
+ return ts_ret
82
+ end
83
+ if touches?(other_td)
84
+ if touches_at_end?(other_td) && other_td.end_at_seconds > end_at_seconds
85
+ update_start_seconds_and_end_seconds(start_at_seconds, other_td.end_at_seconds)
86
+ ts_ret << self
87
+ return ts_ret
88
+ end
89
+ if touches_at_start?(other_td) && other_td.start_at_seconds < start_at_seconds
90
+ update_start_seconds_and_end_seconds(other_td.start_at_seconds, end_at_seconds)
91
+ ts_ret << self
92
+ return ts_ret
93
+ end
94
+ return false
95
+ end
96
+ ts_ret << self
97
+ ts_ret << other_td
98
+ return ts_ret
99
+ end
100
+ def -(other_td)
101
+ ts_ret = TimeSet.new
102
+ unless overlaps?(other_td)
103
+ ts_ret << self
104
+ return ts_ret
105
+ end
106
+ if overlaps?(other_td)
107
+ if overlaps_start?(other_td)
108
+ update_start_seconds_and_end_seconds(other_td.end_at_seconds, end_at_seconds)
109
+ ts_ret << self
110
+ return ts_ret
111
+ end
112
+ if overlaps_end?(other_td)
113
+ puts inspect
114
+ update_start_seconds_and_end_seconds(start_at_seconds, other_td.start_at_seconds)
115
+ puts "RUNNING OVERLAPPING END"
116
+ puts inspect
117
+ ts_ret << self
118
+ return ts_ret
119
+ end
120
+ if overlaps_inside?(other_td)
121
+ left_of_break = left_duration_copy.update_start_seconds_and_end_seconds(start_at_seconds, other_td.start_at_seconds)
122
+ right_of_break = right_duration_copy.update_start_seconds_and_end_seconds(other_td.end_at_seconds, end_at_seconds)
123
+ ts_ret << left_of_break
124
+ ts_ret << right_of_break
125
+ end
126
+ return ts_ret
127
+ end
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,30 @@
1
+ module TimePieces
2
+ class SimpleDuration
3
+ include TimePieces::Duration
4
+ #Time is measured as seconds since midnight
5
+ def start_at=(s_at)
6
+ self.start_at_seconds = s_at.seconds_since_midnight
7
+ end
8
+ def initialize(start_at_seconds, duration_seconds)
9
+ self.start_at_seconds = start_at_seconds
10
+ self.duration_seconds = duration_seconds
11
+ end
12
+ def self.parse_from_time_string(start_at_str, end_at_str)
13
+ start_at_seconds = Time.parse(start_at_str).seconds_since_midnight
14
+ end_at_seconds = Time.parse(end_at_str).seconds_since_midnight
15
+ return self.new(start_at_seconds, end_at_seconds - start_at_seconds)
16
+ end
17
+ def self.new_using_seconds_and_end_at(start_at_seconds, end_at_seconds)
18
+ return self.new(start_at_seconds, end_at_seconds - start_at_seconds)
19
+ end
20
+ def inspect
21
+ hours_start = start_at_seconds / 60 / 60
22
+ hours_end = end_at_seconds / 60 / 60
23
+ duration = duration_seconds / 60 / 60
24
+ return "TD: #{hours_start} - #{hours_end} time in seconds: #{duration_seconds}"
25
+ end
26
+ def bookable_copy
27
+ return SimpleDuration.new(1,10)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,64 @@
1
+ module TimePieces
2
+ class TimeSet
3
+ attr_accessor :time_durations
4
+ def initialize
5
+ @time_durations = []
6
+ end
7
+ #Adds a new time duration. Removes invalid time durations.
8
+ def <<(new_td)
9
+ if new_td.duration_seconds == 0
10
+
11
+ else
12
+ new_tds = []
13
+ has_combined = false
14
+ time_durations.each do |td|
15
+ if new_td.overlaps?(td) || new_td.touches?(td)
16
+ combined_td = td + new_td
17
+ combined_td.time_durations.each do |td3|
18
+ new_tds << td3
19
+ end
20
+ has_combined = true
21
+ else
22
+ new_tds << td
23
+ end
24
+ end
25
+ new_tds << new_td unless has_combined
26
+ self.time_durations = new_tds
27
+ end
28
+ return self
29
+ end
30
+ def >>(subtracting_td)
31
+ new_tds = []
32
+ time_durations.each do |td|
33
+ if subtracting_td.overlaps?(td)
34
+ combined_td = td - subtracting_td
35
+ combined_td.time_durations.each do |td3|
36
+ new_tds << td3
37
+ end
38
+ else
39
+ new_tds << td
40
+ end
41
+
42
+ end
43
+ self.time_durations = new_tds
44
+ return self
45
+ end
46
+ def +(other_ts)
47
+ ret_ts = TimeSet.new
48
+ ret_ts.time_durations = time_durations.map{|td| td}
49
+ other_ts.time_durations.each do |td|
50
+ ret_ts << td
51
+ end
52
+ return ret_ts
53
+ end
54
+ def -(other_ts)
55
+ ret_ts = TimeSet.new
56
+ ret_ts.time_durations = Array.new(time_durations)
57
+ other_ts.time_durations.each do |td|
58
+ ret_ts >> td
59
+ end
60
+ return ret_ts
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module TimePieces
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_support/all'
2
+ #lib = File.expand_path('../lib/', __FILE__)
3
+ lib = File.expand_path('.', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'time_pieces/version'
6
+ require 'time_pieces/duration'
7
+
8
+ require 'time_pieces/simple_duration'
9
+ require 'time_pieces/time_set'
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'time_pieces/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+
8
+ spec.name = "time_pieces"
9
+ spec.version = TimePieces::VERSION
10
+ spec.license = "MIT"
11
+ spec.authors = ["Grant R."]
12
+ spec.email = "grant@arsemporium.com"
13
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
14
+ spec.bindir = "exe"
15
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
+ spec.require_paths = ["lib"]
17
+ spec.homepage = "http://github.com/riggleg/time_pieces"
18
+ spec.summary = "Time based operations."
19
+ spec.description = "time_pieces is a library to make it easy to add/subtract time from a schedule"
20
+
21
+ # s.files = `git ls-files -- lib/*`.split("\n")
22
+ # s.files += %w[README.md LICENSE.md Changelog.md Capybara.md .yardopts .document]
23
+ # s.test_files = []
24
+ # s.require_path = "lib"
25
+
26
+ # private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
27
+ # if File.exist?(private_key)
28
+ # s.signing_key = private_key
29
+ # s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
30
+ # end
31
+
32
+
33
+ # if RUBY_VERSION <= '1.8.7' && ENV['RAILS_VERSION'] != '3-2-stable'
34
+ # version_string << '!= 3.2.22.1'
35
+ # end
36
+ spec.add_dependency 'bundler'
37
+ spec.add_development_dependency %q<activesupport>, '~> 4.2'
38
+
39
+ spec.add_development_dependency 'rake', '~> 10.5'
40
+ spec.add_development_dependency 'cucumber', '~> 2.3.2'
41
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_pieces
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Grant R.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-02-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: cucumber
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.3.2
69
+ description: time_pieces is a library to make it easy to add/subtract time from a
70
+ schedule
71
+ email: grant@arsemporium.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - Gemfile
77
+ - Gemfile.lock
78
+ - README.md
79
+ - Rakefile
80
+ - config/cucumber.yml
81
+ - lib/time_pieces.rb
82
+ - lib/time_pieces/duration.rb
83
+ - lib/time_pieces/simple_duration.rb
84
+ - lib/time_pieces/time_set.rb
85
+ - lib/time_pieces/version.rb
86
+ - time_pieces.gemspec
87
+ homepage: http://github.com/riggleg/time_pieces
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.6
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Time based operations.
111
+ test_files: []