timeleap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Pierre Sugar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,41 @@
1
+ # syc-timeleap
2
+
3
+ Creates dynamically date methods to jump through time
4
+
5
+ ## Usage
6
+
7
+ time_leap = SycTimeLeap::TimeLeap.new
8
+ time_leap.now
9
+ => #<Date: 2014-06-12 ((2456823j,0s,0n),+0s,2299161j)>
10
+ time_leap.in2days
11
+ => #<Date: 2014-06-14 ((2456823j,0s,0n),+0s,2299161j)>
12
+
13
+ ## Methods
14
+
15
+ There are two forms how to invoke the methods. Actually the methods have to be
16
+ unique (see Short Forms) to be recognized
17
+
18
+ ### Long Forms
19
+ * in2days|weeks|months|years
20
+ * back1day|week|month|year
21
+ * yesterday
22
+ * today
23
+ * tomorrow
24
+ * nextmonday|tuesday|wednesday|thursday|friday|saturday|sunday
25
+ * previousmonday|tuesday|wednesday|thursday|friday|saturday|sunday
26
+ * monday|tuesday|wednesday|thursday|friday|saturday|sundayin2weeks|months|years
27
+ * monday|tuesday|wednesday|thursday|friday|saturday|sundayback1week|month|year
28
+
29
+ ### Short Forms
30
+ * i2d|w|m|y
31
+ * b2d|w|m|y
32
+ * y
33
+ * tod
34
+ * tom
35
+ * nmo|tu|we|th|fr|sa|su
36
+ * pmo|tu|we|th|fr|sa|su
37
+ * mo|tu|we|th|fr|sa|sui2w|m|y
38
+ * mo|tu|we|th|fr|sa|sub2w|m|y
39
+
40
+ ## Contact
41
+ <pierre@sugaryourcoffee.de>
@@ -0,0 +1,142 @@
1
+ require 'date'
2
+
3
+ # Provides date operations like in_1_day
4
+ module SycTimeleap
5
+
6
+ # Base class for date operations
7
+ class TimeLeap
8
+
9
+ # Holds the weekdays of the week starts with sunday at index 0
10
+ WEEKDAYS = { "su" => [0, "sunday"],
11
+ "mo" => [1, "monday"],
12
+ "tu" => [2, "tuesday"],
13
+ "we" => [3, "wednesday"],
14
+ "th" => [4, "thursday"],
15
+ "fr" => [5, "friday"],
16
+ "sa" => [6, "saturday"] }
17
+
18
+ # The base date that is used to calculate date operations
19
+ attr_accessor :now
20
+
21
+ # Creates a new Temp and initializes it with the current date if no date
22
+ # is provided
23
+ def initialize(date = Time.now.to_date)
24
+ @now = date
25
+ end
26
+
27
+ # Provides the date calculation methods dynamically
28
+ def method_missing(name, *args)
29
+ add_regex = %r{
30
+ ^([ib])(?:n|ack)?
31
+ (?:\.|_|-| )?
32
+ (\d+)
33
+ (?:\.|_|-| )?
34
+ ([dwmy])
35
+ (?:ays?|eeks?|onths?|ears?)?$
36
+ }x
37
+
38
+ weekday_regex = %r{
39
+ ^(tod|tom|y)(?:a?y?|o?r?r?o?w?|e?s?t?e?r?d?a?y?)?$
40
+ }xi
41
+
42
+ next_weekday_regex = %r{
43
+ ^(n|p)(?:e?x?t|r?e?v?i?o?u?s?)?
44
+ (?:\.|_| |-)?
45
+ (mo|tu|we|th|fr|sa|su)
46
+ (?:n?|e?s?|d?n?e?s?|u?r?s?|i?|t?u?r?|n?)(?:d?a?y?)$
47
+ }xi
48
+
49
+ next_weekday_in_regex = %r{
50
+ ^(mo|tu|we|th|fr|sa|su)
51
+ (?:n?|e?s?|d?n?e?s?|u?r?s?|i?|t?u?r?|n?)(?:d?a?y?)(?:_?)
52
+ (i|b)
53
+ (?:n?|a?c?k?)(?:_?)
54
+ (\d+)(?:_?)([dwmy])(?:a?y?s?|e?e?k?s?|o?n?t?h?s?|e?a?r?s?)$
55
+ }xi
56
+
57
+ return add($1, $2, $3) if name =~ add_regex
58
+ return weekday($1) if name =~ weekday_regex
59
+ return next_weekday($1, $2) if name =~ next_weekday_regex
60
+ return next_weekday_in($1, $2, $3, $4) if name =~ next_weekday_in_regex
61
+ super
62
+ end
63
+
64
+ # Determines whether to move back or forward in time and returns the
65
+ # distance in days, weeks, months or years
66
+ # Example: move(10, 'd') adds 10 days to :now
67
+ def add(direction, count, distance)
68
+ count = direction.downcase == 'b' ? -count.to_i : count.to_i
69
+
70
+ case distance
71
+ when 'd'
72
+ @now + count
73
+ when 'w'
74
+ @now + count * 7
75
+ when 'm'
76
+ @now >> count
77
+ when 'y'
78
+ @now >> count * 12
79
+ end
80
+
81
+ end
82
+
83
+ # Returns yesterday, today or tomorrow
84
+ def weekday(weekday)
85
+ case weekday
86
+ when 'tod'
87
+ @now
88
+ when 'tom'
89
+ @now + 1
90
+ when 'y'
91
+ @now - 1
92
+ end
93
+ end
94
+
95
+ # Returns the next or previous weekday
96
+ # Exampel: next_monday or n_mo
97
+ # Su Mo Tu We Th Fr Sa
98
+ # 0 1 2 3 4 5 6
99
+ # x Today
100
+ # * Next Wednesday
101
+ # @now + (3 - 1 + 7) % 7 = +2
102
+ # x Today
103
+ # * Next Sunday
104
+ # @now + (0 - 4 + 7) % 7 = +3
105
+ # x Today
106
+ # * Previous Wednesday
107
+ # @now + (3 - 2 + 7) % -7 = -6
108
+ # x Today
109
+ # * Previous Tuesday
110
+ # @now + (2 - 4 + 7) % -7 = -2
111
+ def next_weekday(direction, abbreviated_weekday)
112
+ count = direction.downcase == 'n' ? 1 : -1
113
+
114
+ weekday = WEEKDAYS[abbreviated_weekday.downcase]
115
+ raise "No valid weekday: #{abbreviated_weekday}" if weekday.nil?
116
+
117
+ offset = @now.send("#{weekday[1]}?") ? count * 7 : 0
118
+ @now + (weekday[0] - @now.wday + 7) % (count * 7) + offset
119
+ end
120
+
121
+ # Returns the next weekday in n days, weeks, month or years
122
+ # Example: monday_in_3_weeks or mo_i_3_w
123
+ def next_weekday_in(weekday_abbreviation, direction, count, distance)
124
+ count = direction.downcase == 'b' ? -count.to_i : count.to_i
125
+ weekday = WEEKDAYS[weekday_abbreviation.downcase]
126
+
127
+ case distance.downcase
128
+ when "d"
129
+ when "w"
130
+ (@now + count * 7) + weekday[0] - @now.wday
131
+ when "m"
132
+ future = @now >> count
133
+ future + weekday[0] - future.wday
134
+ when "y"
135
+ future = @now >> count * 12
136
+ future + weekday[0] - future.wday
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -0,0 +1,140 @@
1
+ require 'syctimeleap/time_leap'
2
+ require 'date'
3
+
4
+ module SycTimeleap
5
+
6
+ describe TimeLeap do
7
+
8
+ before do
9
+ @date = Date.new(2014, 3, 31)
10
+ @time_leap = TimeLeap.new(@date)
11
+ end
12
+
13
+ it "shows the date of the following date (e.g. in_1_day)" do
14
+ @time_leap.in_1_day.should eq @date + 1
15
+ @time_leap.i1d.should eq @date + 1
16
+ end
17
+
18
+ it "shows the date of the previous date (e.g. 1_day_ago)" do
19
+ @time_leap.back_1_day.should eq @date - 1
20
+ @time_leap.b1d.should eq @date - 1
21
+ end
22
+
23
+ it "shows the date of today plus n days" do
24
+ @time_leap.in_22_days.should eq @date + 22
25
+ @time_leap.in22days.should eq @date + 22
26
+ end
27
+
28
+ it "shows the date of today minus n days" do
29
+ @time_leap.back_22_day.should eq @date - 22
30
+ @time_leap.back22days.should eq @date - 22
31
+ end
32
+
33
+ it "shows the date of today plus n weeks" do
34
+ @time_leap.in_1_week.should eq @date + 7
35
+ @time_leap.i1w.should eq @date + 7
36
+ @time_leap.in2weeks.should eq @date + 14
37
+ end
38
+
39
+ it "shows the date of today minus n weeks" do
40
+ @time_leap.back_1_week.should eq @date - 7
41
+ @time_leap.b1w.should eq @date - 7
42
+ @time_leap.back2weeks.should eq @date - 14
43
+ end
44
+
45
+ it "shows the date of today plus n months" do
46
+ @time_leap.in_1_month.should eq @date >> 1
47
+ @time_leap.i1m.should eq @date >> 1
48
+ @time_leap.in3months.should eq @date >> 3
49
+ end
50
+
51
+ it "shows the date of today minus n months" do
52
+ @time_leap.back_1_month.should eq @date << 1
53
+ @time_leap.b1m.should eq @date << 1
54
+ @time_leap.back3months.should eq @date << 3
55
+ end
56
+
57
+ it "shows the date of today plus n years" do
58
+ @time_leap.in_12_years.should eq @date >> 12 * 12
59
+ @time_leap.i12y.should eq @date >> 12 * 12
60
+ @time_leap.in12years.should eq @date >> 12 * 12
61
+ end
62
+
63
+ it "shows the date of today minus n years" do
64
+ @time_leap.back_10_years.should eq @date << 10 * 12
65
+ @time_leap.b10y.should eq @date << 10 * 12
66
+ @time_leap.back10years.should eq @date << 10 * 12
67
+ end
68
+
69
+ it "shows the date of today" do
70
+ @time_leap.send("today").should eq @date
71
+ @time_leap.today.should eq @date
72
+ @time_leap.tod.should eq @date
73
+ end
74
+
75
+ it "shows the date of tomorrow" do
76
+ @time_leap.send("tomorrow").should eq @date + 1
77
+ @time_leap.tomorrow.should eq @date + 1
78
+ @time_leap.tom.should eq @date + 1
79
+ end
80
+
81
+ it "shows the date of yesterday" do
82
+ @time_leap.yesterday.should eq @date - 1
83
+ @time_leap.y.should eq @date - 1
84
+ end
85
+
86
+ it "shows the date of a next weekday (e.g. next_monday)" do
87
+ @time_leap.next_monday.should eq @date + 7
88
+ @time_leap.next_wednesday.should eq @date + 2
89
+ @time_leap.nwe.should eq @date + 2
90
+ @time_leap.NwE.should eq @date + 2
91
+ end
92
+
93
+ it "shows the date of a previous weekday (e.g. previous_monday)" do
94
+ @time_leap.previous_monday.should eq @date - 7
95
+ @time_leap.previous_wednesday.should eq @date - 5
96
+ @time_leap.pwe.should eq @date -5
97
+ @time_leap.PWednesDay.should eq @date -5
98
+ @time_leap.pReviouSWe.should eq @date -5
99
+ end
100
+
101
+ it "shows date of a weekday in n weeks (e.g. monday_in_2_weeks)" do
102
+ @time_leap.monday_in_2_weeks.should eq @date + 14
103
+ @time_leap.moi2w.should eq @date + 14
104
+ @time_leap.tuesday_in_2_weeks.should eq @date + 15
105
+ @time_leap.tuIN2weE.should eq @date + 15
106
+ end
107
+
108
+ it "shows date of a weekday n weeks ago (e.g. monday_2_weeks_ago)" do
109
+ @time_leap.monday_back_2_weeks.should eq @date - 14
110
+ @time_leap.moba2we.should eq @date - 14
111
+ @time_leap.tuesday_back_2_weeks.should eq @date - 13
112
+ @time_leap.tub2w.should eq @date - 13
113
+ end
114
+
115
+ it "shows date of a weekday in n months (e.g. monday_in_1_month)" do
116
+ @time_leap.monday_in_1_month.should eq @date + 28
117
+ @time_leap.moi1m.should eq @date + 28
118
+ @time_leap.wednesday_in_1_month.should eq @date + 30
119
+ @time_leap.wei1m.should eq @date + 30
120
+ end
121
+
122
+ it "shows date of a weekday n months before today" do
123
+ @time_leap.monday_back_1_month.should eq @date - 35
124
+ @time_leap.mob1m.should eq @date - 35
125
+ @time_leap.wednesday_back_1_month.should eq @date - 33
126
+ @time_leap.weDBA1mO.should eq @date - 33
127
+ end
128
+
129
+ it "shows date of a weekday in n years from today" do
130
+ @time_leap.monday_in_1_year.should eq Date.new(2015, 3, 30)
131
+ @time_leap.moi1y.should eq Date.new(2015, 3, 30)
132
+ end
133
+
134
+ it "shows date of a weekday n years before today" do
135
+ @time_leap.monday_back_1_year.should eq Date.new(2013, 4, 1)
136
+ @time_leap.mob1YE.should eq Date.new(2013, 4, 1)
137
+ end
138
+ end
139
+
140
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timeleap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pierre Sugar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-06-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.13.1
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.13.1
30
+ description:
31
+ email: pierre@sugaryourcoffee.de
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/syctimeleap/time_leap.rb
37
+ - spec/syctimeleap/time_leap_spec.rb
38
+ - LICENSE
39
+ - README.md
40
+ homepage: https://github.com/sugaryourcoffee/timeleap
41
+ licenses:
42
+ - MIT
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '1.9'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.23
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Dynamically create date methods to jump through time
65
+ test_files:
66
+ - spec/syctimeleap/time_leap_spec.rb