time_only 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.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ .rbenv-version
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - jruby-18mode
5
+ - rbx-18mode
6
+ - ree
7
+ - 1.9.2
8
+ - jruby-19mode
9
+ - rbx-19mode
10
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in time_of_day.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 OrgSync and Aaron Lasseigne
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.
@@ -0,0 +1,59 @@
1
+ # TimeOnly
2
+
3
+ A simple class for handling time and only time. No dates, no time zones, just good old time of day.
4
+ At the moment, `TimeOnly` only supports resolution to 1 second.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'time_only'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install time_only
19
+
20
+ ## Usage
21
+
22
+ `TimeOnly` attempts to implement the same functionality as `Time` where it makes sense to do so.
23
+
24
+ require 'time_only'
25
+
26
+ time = TimeOnly.new(8, 0, 2)
27
+ # => '08:00:02'
28
+
29
+ time.hour
30
+ # => 8
31
+
32
+ time.min
33
+ # => 0
34
+
35
+ time.sec
36
+ # => 2
37
+
38
+ time.strftime('The time is %-l:%M:%S %P.')
39
+ # => 'The time is 1:03:56 pm.'
40
+
41
+ # adding times rolls the time forward and returns a new TimeOnly
42
+ TimeOnly.new(23, 59, 59) + 3
43
+ # => '00:00:02'
44
+
45
+ morning_flights, afternoon_flights = departure_times.partition(&:am?)
46
+
47
+ current_time = TimeOnly.now
48
+
49
+ # and many more...
50
+
51
+ Method documentation can be found in the source.
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ task :default => :spec
7
+
8
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,260 @@
1
+ class TimeOnly
2
+ include Comparable
3
+
4
+ SECONDS_PER_MIN = 60
5
+ SECONDS_PER_HOUR = 60 * SECONDS_PER_MIN
6
+ SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
7
+
8
+ # Public: Initialize a TimeOnly.
9
+ #
10
+ # seconds - The Integer number of seconds since midnight.
11
+ #
12
+ # Examples
13
+ #
14
+ # TimeOnly.at(4)
15
+ # # => '00:00:04'
16
+ def self.at(seconds)
17
+ new(seconds)
18
+ end
19
+
20
+ def self.now
21
+ time = Time.now
22
+
23
+ new(time.hour, time.min, time.sec)
24
+ end
25
+
26
+ # Public: Initialize a TimeOnly.
27
+ #
28
+ # seconds - The Integer number of seconds since midnight.
29
+ # OR
30
+ # hours - The Integer number of hours.
31
+ # minutes - The Integer number of minutes.
32
+ # seconds - The Integer number of seconds.
33
+ #
34
+ # Examples
35
+ #
36
+ # TimeOnly.new(4)
37
+ # # => '00:00:04'
38
+ #
39
+ # TimeOnly.new(13, 24, 56)
40
+ # # => '13:24:56'
41
+ def initialize(*args)
42
+ seconds = case args.size
43
+ when 1
44
+ args.first
45
+ when 3
46
+ hours, minutes, seconds = args
47
+
48
+ raise ArgumentError, 'hours must be between 0 and 23' if hours < 0 || hours > 23
49
+ raise ArgumentError, 'minutes must be between 0 and 59' if minutes < 0 || minutes > 59
50
+ raise ArgumentError, 'seconds must be between 0 and 59' if seconds < 0 || seconds > 59
51
+
52
+ (hours * SECONDS_PER_HOUR) + (minutes * SECONDS_PER_MIN) + seconds
53
+ else
54
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 1 or 3)"
55
+ end
56
+
57
+ @seconds_since_midnight = mod_by_day(seconds)
58
+ end
59
+
60
+ # Public: Add seconds to the time and return that as a new value. If the value
61
+ # exceeds the number of seconds in a day the time will roll forwardd.
62
+ #
63
+ # seconds - The Integer number of seconds.
64
+ #
65
+ # Examples
66
+ #
67
+ # TimeOnly.new(4) + 3
68
+ # # => '00:00:07'
69
+ #
70
+ # TimeOnly.new(23, 59, 59) + 3
71
+ # # => '00:00:02'
72
+ #
73
+ # Returns a new TimeOnly.
74
+ def +(seconds)
75
+ self.class.new(mod_by_day(@seconds_since_midnight + seconds))
76
+ end
77
+
78
+ # Public: Subtract seconds from the time and return that as a new value. If the
79
+ # value is less than zero seconds in a day the time will roll backwards.
80
+ #
81
+ # seconds - The Integer number of seconds.
82
+ #
83
+ # Examples
84
+ #
85
+ # TimeOnly.new(4) - 3
86
+ # # => '00:00:01'
87
+ #
88
+ # TimeOnly.new(0, 0, 0) - 3
89
+ # # => '23:59:57'
90
+ #
91
+ # Returns a new TimeOnly.
92
+ def -(seconds)
93
+ self + (seconds * -1)
94
+ end
95
+
96
+ def ==(other)
97
+ to_i == other.to_i
98
+ end
99
+ alias_method :eql?, :==
100
+
101
+ def <=>(other)
102
+ to_i <=> other.to_i
103
+ end
104
+
105
+ def am?
106
+ hour < 12
107
+ end
108
+
109
+ def hour
110
+ @hour ||= @seconds_since_midnight / SECONDS_PER_HOUR
111
+ end
112
+
113
+ def min
114
+ @min ||= (@seconds_since_midnight % SECONDS_PER_HOUR) / SECONDS_PER_MIN
115
+ end
116
+
117
+ def pm?
118
+ !am?
119
+ end
120
+
121
+ def sec
122
+ @sec ||= @seconds_since_midnight % SECONDS_PER_MIN
123
+ end
124
+
125
+ # Public: Formats time according to the directives in the given format string.
126
+ # The directives begins with a percent (%) character. Any text not listed as a
127
+ # directive will be passed through to the output string.)
128
+ #
129
+ # The directive consists of a percent (%) character, zero or more flags and a
130
+ # conversion specifier as follows.
131
+ #
132
+ # %<flags><conversion>
133
+ #
134
+ # Flags:
135
+ # - don't pad a numerical output
136
+ #
137
+ # Directives:
138
+ # %H - Hour of the day, 24-hour clock, zero-padded (00..23)
139
+ # %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
140
+ # %I - Hour of the day, 12-hour clock, zero-padded (01..12)
141
+ # %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
142
+ # %P - Meridian indicator, lowercase (``am' or ``pm')
143
+ # %p - Meridian indicator, uppercase (``AM' or ``PM')
144
+ # %M - Minute of the hour (00..59)
145
+ # %S - Second of the minute (00..60)
146
+ #
147
+ # Literal strings:
148
+ # %n - Newline character (\n)
149
+ # %t - Tab character (\t)
150
+ # %% - Literal ``%'' character)
151
+ #
152
+ # Combinations:
153
+ # %X - Same as %T
154
+ # %r - 12-hour time (%I:%M:%S %p)
155
+ # %R - 24-hour time (%H:%M)
156
+ # %T - 24-hour time (%H:%M:%S)
157
+ #
158
+ # format - The String containing directives.
159
+ #
160
+ # Examples
161
+ #
162
+ # TimeOnly.new(12, 34, 56).strftime('%r')
163
+ # # => '12:34:56 PM'
164
+ #
165
+ # TimeOnly.new(1, 3, 56).strftime('The time is %-l:%M:%S %P.')
166
+ # # => 'The time is 1:03:56 pm.'
167
+ #
168
+ # Returns the formatted String.
169
+ def strftime(format)
170
+ format = format.dup
171
+
172
+ format.gsub!(/%[rRTX]/) do |token|
173
+ case token
174
+ when '%r'
175
+ '%I:%M:%S %p'
176
+ when '%R'
177
+ '%H:%M'
178
+ when '%T', '%X'
179
+ '%H:%M:%S'
180
+ end
181
+ end
182
+
183
+ format.gsub(/%-?[HkIlPpMSnt%]/) do |token|
184
+ case token
185
+ when '%H'
186
+ zero_pad(hour)
187
+ when '%k'
188
+ blank_pad(hour)
189
+ when '%-H', '%-k'
190
+ hour
191
+ when '%I'
192
+ zero_pad(twelve_hour)
193
+ when '%l'
194
+ blank_pad(twelve_hour)
195
+ when '%-I', '%-l'
196
+ twelve_hour
197
+ when '%P'
198
+ am? ? 'am' : 'pm'
199
+ when '%p'
200
+ am? ? 'AM' : 'PM'
201
+ when '%M'
202
+ zero_pad(min)
203
+ when '%-M'
204
+ min
205
+ when '%S'
206
+ zero_pad(sec)
207
+ when '%-S'
208
+ sec
209
+ when '%n'
210
+ "\n"
211
+ when '%t'
212
+ "\t"
213
+ when '%%'
214
+ '%'
215
+ end
216
+ end
217
+ end
218
+
219
+ def succ
220
+ self + 1
221
+ end
222
+
223
+ def to_a
224
+ [hour, min, sec]
225
+ end
226
+
227
+ def to_f
228
+ @seconds_since_midnight.to_f
229
+ end
230
+
231
+ def to_i
232
+ @seconds_since_midnight
233
+ end
234
+ alias_method :tv_sec, :to_i
235
+
236
+ def to_s
237
+ strftime('%T')
238
+ end
239
+ alias_method :asctime, :to_s
240
+ alias_method :ctime, :to_s
241
+ alias_method :inspect, :to_s
242
+
243
+ private
244
+
245
+ def mod_by_day(seconds)
246
+ seconds % SECONDS_PER_DAY
247
+ end
248
+
249
+ def twelve_hour
250
+ hour > 12 ? hour % 12 : hour
251
+ end
252
+
253
+ def zero_pad(number)
254
+ number < 10 ? "0#{number}" : number
255
+ end
256
+
257
+ def blank_pad(number)
258
+ number < 10 ? " #{number}" : number
259
+ end
260
+ end
@@ -0,0 +1,3 @@
1
+ class TimeOnly
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,391 @@
1
+ require 'rspec'
2
+ require 'timecop'
3
+ require 'time_only'
4
+
5
+ describe TimeOnly do
6
+ describe '.new(args)' do
7
+ context 'one arg' do
8
+ it 'creates as the seconds since midnight' do
9
+ expect(described_class.new(45296).to_i).to eq(45296)
10
+ end
11
+
12
+ it "rolls over seconds that are greater than #{described_class::SECONDS_PER_DAY}" do
13
+ expect(described_class.new(described_class::SECONDS_PER_DAY * 2 + 1).to_i).to eq(1)
14
+ end
15
+
16
+ it 'handles negative seconds which rolls back' do
17
+ expect(described_class.new(-10).to_i).to eq(described_class::SECONDS_PER_DAY - 10)
18
+ end
19
+ end
20
+
21
+ context 'three argss' do
22
+ it 'creates based on hours, minutes and seconds' do
23
+ expect(described_class.new(12, 34, 56).to_i).to eq(45296)
24
+ end
25
+
26
+ it 'raises an error when the hours arg is outside of 0 - 23' do
27
+ expect{ described_class.new(24, 0, 0) }.to raise_error(ArgumentError)
28
+ end
29
+
30
+ it 'raises an error when the minutes arg is outside of 0 - 59' do
31
+ expect{ described_class.new(0, 60, 0) }.to raise_error(ArgumentError)
32
+ end
33
+
34
+ it 'raises an error when the seconds arg is outside of 0 - 59' do
35
+ expect{ described_class.new(0, 0, 60) }.to raise_error(ArgumentError)
36
+ end
37
+ end
38
+
39
+ it 'raises an error when the wrong number of arguments is passed' do
40
+ expect{ described_class.new(1, 2) }.to raise_error(ArgumentError)
41
+ end
42
+ end
43
+
44
+ describe '.at(seconds)' do
45
+ it 'creates a time based on the number of seconds since midnight' do
46
+ expect(described_class.at(300).to_i).to eq(300)
47
+ end
48
+
49
+ it "rolls over seconds that are greater than #{described_class::SECONDS_PER_DAY}" do
50
+ expect(described_class.at(described_class::SECONDS_PER_DAY * 2 + 1).to_i).to eq(1)
51
+ end
52
+
53
+ it 'handles negative seconds which rolls back' do
54
+ expect(described_class.at(-10).to_i).to eq(described_class::SECONDS_PER_DAY - 10)
55
+ end
56
+ end
57
+
58
+ describe '.now' do
59
+ it "returns a #{described_class} object for the current system time" do
60
+ hour, min, sec = 12, 34, 56
61
+
62
+ Timecop.freeze(Time.local(2012, 11, 30, hour, min, sec)) do
63
+ expect(described_class.now.to_s).to eq("#{hour}:#{min}:#{sec}")
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#+(seconds)' do
69
+ it "returns a new #{described_class} object with n seconds added to it" do
70
+ current_time = described_class.new(0)
71
+ new_time = current_time + 1
72
+
73
+ expect(current_time).not_to equal(new_time)
74
+ expect(new_time).to eq(described_class.new(1))
75
+ end
76
+
77
+ it 'rolls over time when greater than 23:59:59' do
78
+ expect(described_class.new(23, 59, 59) + 2).to eq(described_class.new(0, 0, 1))
79
+ end
80
+ end
81
+
82
+ describe '#-(seconds)' do
83
+ it "returns a new #{described_class} object with n seconds subtracted from it" do
84
+ current_time = described_class.new(1)
85
+ new_time = current_time - 1
86
+
87
+ expect(current_time).not_to equal(new_time)
88
+ expect(new_time).to eq(described_class.new(0))
89
+ end
90
+
91
+ it 'rolls back time when less than 00:00:00' do
92
+ expect(described_class.new(00, 00, 01) - 2).to eq(described_class.new(23, 59, 59))
93
+ end
94
+ end
95
+
96
+ describe '#==(other)' do # aliases: eql?
97
+ it 'returns true when the times are the same' do
98
+ expect(described_class.new(12, 34, 56) == described_class.new(12, 34, 56)).to be_true
99
+ end
100
+
101
+ it 'returns false when the times are not the same' do
102
+ expect(described_class.new(12, 34, 56) == described_class.new(0, 0, 0)).to be_false
103
+ end
104
+ end
105
+
106
+ describe '#<=>(other)' do
107
+ it 'returns 0 when the times are equal' do
108
+ other = described_class.new(0)
109
+
110
+ expect(described_class.new(0) <=> other).to eq(0)
111
+ end
112
+
113
+ it 'returns -1 when the times are equal' do
114
+ other = described_class.new(1)
115
+
116
+ expect(described_class.new(0) <=> other).to eq(-1)
117
+ end
118
+
119
+ it 'returns 1 when the times are equal' do
120
+ other = described_class.new(0)
121
+
122
+ expect(described_class.new(1) <=> other).to eq(1)
123
+ end
124
+ end
125
+
126
+ describe '#am?' do
127
+ context 'time is before noon' do
128
+ subject { described_class.new(2, 4, 6) }
129
+
130
+ its(:am?) { should be_true }
131
+ end
132
+
133
+ context 'time is after noon' do
134
+ subject { described_class.new(12, 4, 6) }
135
+
136
+ its(:am?) { should be_false }
137
+ end
138
+ end
139
+
140
+ describe '#hour' do
141
+ subject { described_class.new(2, 4, 6) }
142
+
143
+ its(:hour) { should be 2 }
144
+ end
145
+
146
+ describe '#min' do
147
+ subject { described_class.new(2, 4, 6) }
148
+
149
+ its(:min) { should be 4 }
150
+ end
151
+
152
+ describe '#pm?' do
153
+ context 'time is before noon' do
154
+ subject { described_class.new(2, 4, 6) }
155
+
156
+ its(:pm?) { should be_false }
157
+ end
158
+
159
+ context 'time is after noon' do
160
+ subject { described_class.new(12, 4, 6) }
161
+
162
+ its(:pm?) { should be_true }
163
+ end
164
+ end
165
+
166
+ describe '#sec' do
167
+ subject { described_class.new(2, 4, 6) }
168
+
169
+ its(:sec) { should be 6 }
170
+ end
171
+
172
+ describe '#strftime' do
173
+ context 'flags' do
174
+ context "- don't pad a numerical output" do
175
+ context 'hour' do
176
+ %w(H k I l).each do |directive|
177
+ context "using %#{directive}" do
178
+ it 'hour is one digit' do
179
+ expect(described_class.new(8, 0, 0).strftime("%-#{directive}")).to eq('8')
180
+ end
181
+
182
+ it 'hour is two digits' do
183
+ if directive == 'I' || directive == 'l'
184
+ hour, hour_s = 13, '1'
185
+ else
186
+ hour, hour_s = 12, '12'
187
+ end
188
+
189
+ expect(described_class.new(hour, 0, 0).strftime("%-#{directive}")).to eq(hour_s)
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ context 'min' do
196
+ it 'min is one digit' do
197
+ expect(described_class.new(0, 8, 0).strftime('%-M')).to eq('8')
198
+ end
199
+
200
+ it 'min is two digits' do
201
+ expect(described_class.new(0, 12, 0).strftime('%-M')).to eq('12')
202
+ end
203
+ end
204
+
205
+ context 'sec' do
206
+ it 'sec is one digit' do
207
+ expect(described_class.new(0, 0, 8).strftime('%-S')).to eq('8')
208
+ end
209
+
210
+ it 'sec is two digits' do
211
+ expect(described_class.new(0, 0, 12).strftime('%-S')).to eq('12')
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ context 'directives' do
218
+ context '%H - Hour of the day, 24-hour clock, zero-padded (00..23)' do
219
+ it 'hour is one digit' do
220
+ expect(described_class.new(8, 0, 0).strftime('%H')).to eq('08')
221
+ end
222
+
223
+ it 'hour is two digits' do
224
+ expect(described_class.new(12, 0, 0).strftime('%H')).to eq('12')
225
+ end
226
+ end
227
+
228
+ context '%k - Hour of the day, 24-hour clock, blank-padded ( 0..23)' do
229
+ it 'hour is one digit' do
230
+ expect(described_class.new(8, 0, 0).strftime('%k')).to eq(' 8')
231
+ end
232
+
233
+ it 'hour is two digits' do
234
+ expect(described_class.new(12, 0, 0).strftime('%k')).to eq('12')
235
+ end
236
+ end
237
+
238
+ context '%I - Hour of the day, 12-hour clock, zero-padded (01..12)' do
239
+ context 'before 1pm' do
240
+ it 'hour is one digit' do
241
+ expect(described_class.new(8, 0, 0).strftime('%I')).to eq('08')
242
+ end
243
+
244
+ it 'hour is two digits' do
245
+ expect(described_class.new(12, 0, 0).strftime('%I')).to eq('12')
246
+ end
247
+ end
248
+
249
+ context 'after or equal to 1pm' do
250
+ it 'hour is one digit' do
251
+ expect(described_class.new(13, 0, 0).strftime('%I')).to eq('01')
252
+ end
253
+
254
+ it 'hour is two digits' do
255
+ expect(described_class.new(22, 0, 0).strftime('%I')).to eq('10')
256
+ end
257
+ end
258
+ end
259
+
260
+ context '%l - Hour of the day, 12-hour clock, blank-padded ( 1..12)' do
261
+ context 'before 1pm' do
262
+ it 'hour is one digit' do
263
+ expect(described_class.new(8, 0, 0).strftime('%l')).to eq(' 8')
264
+ end
265
+
266
+ it 'hour is two digits' do
267
+ expect(described_class.new(12, 0, 0).strftime('%l')).to eq('12')
268
+ end
269
+ end
270
+
271
+ context 'after or equal to 1pm' do
272
+ it 'hour is one digit' do
273
+ expect(described_class.new(13, 0, 0).strftime('%l')).to eq(' 1')
274
+ end
275
+
276
+ it 'hour is two digits' do
277
+ expect(described_class.new(22, 0, 0).strftime('%l')).to eq('10')
278
+ end
279
+ end
280
+ end
281
+
282
+ context '%P - Meridian indicator, lowercase ("am" or "pm")' do
283
+ it 'hours are before noon' do
284
+ expect(described_class.new(8, 0, 0).strftime('%P')).to eq('am')
285
+ end
286
+
287
+ it 'hours are after noon' do
288
+ expect(described_class.new(13, 0, 0).strftime('%P')).to eq('pm')
289
+ end
290
+ end
291
+
292
+ context '%p - Meridian indicator, uppercase ("AM" or "PM")' do
293
+ it 'hours are before noon' do
294
+ expect(described_class.new(8, 0, 0).strftime('%p')).to eq('AM')
295
+ end
296
+
297
+ it 'hours are after noon' do
298
+ expect(described_class.new(13, 0, 0).strftime('%p')).to eq('PM')
299
+ end
300
+ end
301
+
302
+ context '%M - Minute of the hour (00..59)' do
303
+ it 'min is one digit' do
304
+ expect(described_class.new(0, 8, 0).strftime('%M')).to eq('08')
305
+ end
306
+
307
+ it 'min is two digits' do
308
+ expect(described_class.new(0, 12, 0).strftime('%M')).to eq('12')
309
+ end
310
+ end
311
+
312
+ context '%S - Second of the minute (00..60)' do
313
+ it 'sec is one digit' do
314
+ expect(described_class.new(0, 0, 8).strftime('%S')).to eq('08')
315
+ end
316
+
317
+ it 'sec is two digits' do
318
+ expect(described_class.new(0, 0, 12).strftime('%S')).to eq('12')
319
+ end
320
+ end
321
+ end
322
+
323
+ context 'literals' do
324
+ it '%n - Newline character (\n)' do
325
+ expect(described_class.at(0).strftime('%n')).to eq("\n")
326
+ end
327
+
328
+ it '%t - Tab character (\t)' do
329
+ expect(described_class.at(0).strftime('%t')).to eq("\t")
330
+ end
331
+
332
+ it '%% - Literal "%" character' do
333
+ expect(described_class.at(0).strftime('%%')).to eq('%')
334
+ end
335
+ end
336
+
337
+ context 'combinations' do
338
+ it '%r - 12-hour time (%I:%M:%S %p)' do
339
+ expect(described_class.new(1, 0, 12).strftime('%r')).to eq('01:00:12 AM')
340
+ end
341
+
342
+ it '%R - 24-hour time (%H:%M)' do
343
+ expect(described_class.new(1, 0, 12).strftime('%R')).to eq('01:00')
344
+ end
345
+
346
+ %w(X T).each do |combination|
347
+ it "%#{combination} - 24-hour time (%H:%M:%S)" do
348
+ expect(described_class.new(1, 0, 12).strftime("%#{combination}")).to eq('01:00:12')
349
+ end
350
+ end
351
+ end
352
+ end
353
+
354
+ describe '#succ' do
355
+ it "returns a new #{described_class} object, one second later than the original" do
356
+ current_time = described_class.new(0)
357
+ new_time = current_time.succ
358
+
359
+ expect(current_time).not_to equal(new_time)
360
+ expect(new_time).to eq(described_class.new(1))
361
+ end
362
+
363
+ it 'rolls over time when greater than 23:59:59' do
364
+ expect(described_class.new(23, 59, 59).succ).to eq(described_class.new(0, 0, 0))
365
+ end
366
+ end
367
+
368
+ describe '#to_a' do
369
+ subject { described_class.new(2, 3, 4) }
370
+
371
+ its(:to_a) { should == [2, 3, 4] }
372
+ end
373
+
374
+ describe '#to_f' do
375
+ subject { described_class.new(300) }
376
+
377
+ its(:to_f) { should == 300.0 }
378
+ end
379
+
380
+ describe '#to_i' do # aliases: tv_sec
381
+ subject { described_class.new(300) }
382
+
383
+ its(:to_i) { should == 300 }
384
+ end
385
+
386
+ describe '#to_s' do # aliases: asctime, ctime, inspect
387
+ subject { described_class.new(2, 4, 6) }
388
+
389
+ its(:to_s) { should == '02:04:06' }
390
+ end
391
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/time_only/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'time_only'
6
+ gem.version = TimeOnly::VERSION
7
+ gem.summary = 'A simple class for handling time and only time.'
8
+ gem.description = "#{gem.summary} No dates, no time zones, just good old time of day."
9
+
10
+ gem.authors = ['Aaron Lasseigne']
11
+ gem.email = ['aaron@orgsync.com']
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ['lib']
17
+
18
+ gem.add_development_dependency 'rake'
19
+ gem.add_development_dependency 'rspec'
20
+ gem.add_development_dependency 'timecop'
21
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_only
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Aaron Lasseigne
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-04 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rake
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ requirement: *id001
33
+ prerelease: false
34
+ - !ruby/object:Gem::Dependency
35
+ name: rspec
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :development
46
+ requirement: *id002
47
+ prerelease: false
48
+ - !ruby/object:Gem::Dependency
49
+ name: timecop
50
+ version_requirements: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ type: :development
60
+ requirement: *id003
61
+ prerelease: false
62
+ description: A simple class for handling time and only time. No dates, no time zones, just good old time of day.
63
+ email:
64
+ - aaron@orgsync.com
65
+ executables: []
66
+
67
+ extensions: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ files:
72
+ - .gitignore
73
+ - .travis.yml
74
+ - Gemfile
75
+ - LICENSE
76
+ - README.md
77
+ - Rakefile
78
+ - lib/time_only.rb
79
+ - lib/time_only/version.rb
80
+ - spec/time_only_spec.rb
81
+ - time_only.gemspec
82
+ homepage:
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options: []
87
+
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.8.24
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: A simple class for handling time and only time.
115
+ test_files:
116
+ - spec/time_only_spec.rb