dateless_time 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +160 -0
- data/Rakefile +10 -0
- data/dateless_time.gemspec +25 -0
- data/lib/dateless_time.rb +211 -0
- data/lib/dateless_time/version.rb +3 -0
- data/test/creation_test.rb +323 -0
- data/test/query_test.rb +90 -0
- data/test/test_helper.rb +4 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 51230f82cbbac016a630c318ca4d61ecb5274769
|
4
|
+
data.tar.gz: 67fe4308f2fbd241819e1db9e23f414db0303504
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c5f0995c0479b2afa745dc7a737480670cbeeacfed805d4d7d7187e88df7be93b04b0db5138107749e486c2f9c3a45f7f56b3007e6c491ce1886af4a3f2bf4f
|
7
|
+
data.tar.gz: aed012ec5c33de7ed5af3a79ed4acdc44b27cfbb3a178cb6286e0bde1c1e61da39a731c4eb7bafdd62a9216e76707196943d07ec7b5469d49865c2f66677b26d
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
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
|
+
|
19
|
+
# OSX
|
20
|
+
.Spotlight-V100
|
21
|
+
.DS_Store
|
22
|
+
.Trashes
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Tommaso Pavese
|
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,160 @@
|
|
1
|
+
# DatelessTime
|
2
|
+
|
3
|
+
A class to handle __dateless time values__.
|
4
|
+
|
5
|
+
## What
|
6
|
+
|
7
|
+
There are a number of use cases where we need a simple and dumb time value. Think about the opening times of a theater or the daily airing time of a TV show.
|
8
|
+
|
9
|
+
In these situations the time doesn't need to be bound to a date.
|
10
|
+
It doesn't need to be adjusted to the user's timezone either, and it surely doesn't need to be pushed forward or backwards because of the dailight saving time.
|
11
|
+
|
12
|
+
Things become even messier when working with a framework (Rails) that handles these adjustments automatically.
|
13
|
+
|
14
|
+
This gem aims to fix this.
|
15
|
+
Drawing inspirations from the Unix time format, it stores static time values as the number of seconds since midnight.
|
16
|
+
It generates static and date-independent time values, that don't care about timezones or DST.
|
17
|
+
|
18
|
+
As easy as pie.
|
19
|
+
|
20
|
+
|
21
|
+
## Dependencies
|
22
|
+
|
23
|
+
None. No external gems, nothing from the stdlib either.
|
24
|
+
|
25
|
+
|
26
|
+
## Rubies
|
27
|
+
|
28
|
+
Tested with:
|
29
|
+
|
30
|
+
* MRI `1.9.3`, `2.0.0`, `2.1.0` and `2.1.1`
|
31
|
+
* Rubinius `2.2.4`
|
32
|
+
* JRuby `1.7.10`
|
33
|
+
|
34
|
+
|
35
|
+
## How
|
36
|
+
|
37
|
+
|
38
|
+
Creation:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'dateless_time'
|
42
|
+
|
43
|
+
# you can create a DatelessTime object with a shortcut
|
44
|
+
time = DatelessTime.now
|
45
|
+
|
46
|
+
# or a Time object
|
47
|
+
time = DatelessTime.new Time.now
|
48
|
+
|
49
|
+
# or a String (minutes and seconds are optional)
|
50
|
+
time = DatelessTime.new "13:37:00"
|
51
|
+
|
52
|
+
# or the number of seconds since midnight
|
53
|
+
time = DatelessTime.new 49020
|
54
|
+
|
55
|
+
# or a Hash (minutes and seconds are optional)
|
56
|
+
time = DatelessTime.new hours: 13, minutes: 37, seconds: 0
|
57
|
+
|
58
|
+
# or an Array (minutes and seconds are optional)
|
59
|
+
time = DatelessTime.new [13, 37, 0]
|
60
|
+
|
61
|
+
```
|
62
|
+
|
63
|
+
Interface:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'dateless_time'
|
67
|
+
|
68
|
+
time = DatelessTime.new "13:37:42"
|
69
|
+
|
70
|
+
time.hours
|
71
|
+
#=> 13
|
72
|
+
time.minutes
|
73
|
+
#=> 37
|
74
|
+
time.seconds
|
75
|
+
#=> 42
|
76
|
+
|
77
|
+
time.seconds_since_midnight
|
78
|
+
# or
|
79
|
+
time.to_i
|
80
|
+
# => 49062
|
81
|
+
|
82
|
+
# this uses Time.now to fill the date-related bits
|
83
|
+
time.to_time
|
84
|
+
# => 2014-04-01 13:37:42 +0100
|
85
|
+
|
86
|
+
# but you can supply a base time object instead
|
87
|
+
t.to_time(Time.new(1985, 10, 25, 0, 0, 0, "-08:00"))
|
88
|
+
# => 1985-10-25 13:37:42 -0800
|
89
|
+
|
90
|
+
time.to_time.class
|
91
|
+
# => Time
|
92
|
+
|
93
|
+
time.strftime("%-l:%M %P")
|
94
|
+
# => "1:37 pm"
|
95
|
+
|
96
|
+
time.to_s
|
97
|
+
# => "13:37:42"
|
98
|
+
|
99
|
+
time.to_h
|
100
|
+
# => {:hours=>13, :minutes=>37, :seconds=>42}
|
101
|
+
|
102
|
+
time.to_a
|
103
|
+
# => [13, 37, 42]
|
104
|
+
|
105
|
+
```
|
106
|
+
|
107
|
+
## Installation
|
108
|
+
|
109
|
+
Add this line to your application's Gemfile:
|
110
|
+
|
111
|
+
gem 'dateless_time'
|
112
|
+
|
113
|
+
And then execute:
|
114
|
+
|
115
|
+
$ bundle
|
116
|
+
|
117
|
+
Or install it yourself as:
|
118
|
+
|
119
|
+
$ gem install dateless_time
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
## Integration with Rails
|
124
|
+
|
125
|
+
The main goal is to keep this gem as small and lightweight as possible, thus I'm not planning to add any specific support for rails.
|
126
|
+
|
127
|
+
This doesn't mean that it can't be used with Rais, though!
|
128
|
+
Just choose how to store time values in you DB (time-only SQL values or seconds since midnight, for example), and use them to instantiate `DatelessTime` objects rather than Ruby's default `Time`.
|
129
|
+
|
130
|
+
For example:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
|
134
|
+
# opening_time_seconds is an INT value from the DB
|
135
|
+
|
136
|
+
def opening_time
|
137
|
+
@opening_time ||= DatelessTime.new opening_time_seconds
|
138
|
+
end
|
139
|
+
|
140
|
+
```
|
141
|
+
|
142
|
+
|
143
|
+
## To Do
|
144
|
+
|
145
|
+
|
146
|
+
1. include and support `Comparable` ([ruby doc](http://ruby-doc.org/core-2.1.0/Comparable.html))
|
147
|
+
2. implement the `+` and `-` artimetic operators, in a way consistent with Ruby's `Time`
|
148
|
+
3. nice to have: other methods from `Time`'s public interface
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
## Contributing
|
155
|
+
|
156
|
+
1. Fork it
|
157
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
158
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
159
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
160
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dateless_time/version'
|
5
|
+
#require "dateless_time"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "dateless_time"
|
9
|
+
spec.version = DatelessTime::VERSION
|
10
|
+
spec.author = "Tommaso Pavese"
|
11
|
+
spec.description = %q{A class to handle dateless time values.}
|
12
|
+
spec.summary = %q{A class to handle dateless time values. DatelessTime objects are a lightweight alternative Ruby's default Time class, and don't care about timezones and DST.}
|
13
|
+
spec.homepage = "https://github.com/tompave/dateless_time"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake", '~> 10.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'minitest', '~> 5.3.1'
|
25
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require "dateless_time/version"
|
2
|
+
|
3
|
+
class DatelessTime
|
4
|
+
|
5
|
+
SECONDS_IN_24_HOURS = 86400
|
6
|
+
|
7
|
+
MAX_HOURS = 24
|
8
|
+
MAX_MINUTES = 59
|
9
|
+
MAX_SECONDS = 59
|
10
|
+
|
11
|
+
TIME_STRING_REGEX = /\A\d{1,2}(:\d{2})?(:\d{2})?( ?(am|pm))?\z/i
|
12
|
+
AM_PM_REGEX = /( )?(am|pm)\z/i
|
13
|
+
|
14
|
+
SPRINTF_FORMAT = "%02d:%02d:%02d".freeze
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
attr_reader :hours, :minutes, :seconds
|
19
|
+
|
20
|
+
|
21
|
+
def self.now
|
22
|
+
new
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def initialize(source = Time.now)
|
27
|
+
conditional_init source
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
def to_time(base = Time.now)
|
33
|
+
@time_value ||= Time.new(base.year, base.month, base.day,
|
34
|
+
@hours, @minutes, @seconds, base.utc_offset)
|
35
|
+
rescue
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
@string_value ||= sprintf(SPRINTF_FORMAT, @hours, @minutes, @seconds)
|
42
|
+
rescue
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def to_h
|
48
|
+
@hash_value ||= { hours: @hours, minutes: @minutes, seconds: @seconds }
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def to_a
|
53
|
+
@array_value ||= [@hours, @minutes, @seconds]
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def seconds_since_midnight
|
58
|
+
@seconds_since_midnight ||= calculate_seconds_since_midnight
|
59
|
+
end
|
60
|
+
|
61
|
+
alias_method :to_i, :seconds_since_midnight
|
62
|
+
|
63
|
+
|
64
|
+
def strftime(template)
|
65
|
+
to_time.strftime(template)
|
66
|
+
rescue
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
|
75
|
+
def conditional_init(source)
|
76
|
+
case source
|
77
|
+
when Time then init_with_time(source)
|
78
|
+
when String then init_with_string(source)
|
79
|
+
when Fixnum then init_with_seconds(source)
|
80
|
+
when Hash then init_with_hash(source)
|
81
|
+
when Array then init_with_array(source)
|
82
|
+
else raise DatelessTime::InitializationError
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def init_with_time(time)
|
88
|
+
@hours = time.hour
|
89
|
+
@minutes = time.min
|
90
|
+
@seconds = time.sec
|
91
|
+
seconds_since_midnight
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def init_with_string(string)
|
96
|
+
validate_time_string string
|
97
|
+
data = time_string_to_array string
|
98
|
+
init_with_array data
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
def init_with_seconds(seconds)
|
103
|
+
validate_seconds_since_midnight seconds
|
104
|
+
#seconds = SECONDS_IN_24_HOURS if seconds > SECONDS_IN_24_HOURS
|
105
|
+
@seconds_since_midnight = seconds
|
106
|
+
calculate_hours_minutes_and_seconds
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def init_with_hash(hash)
|
111
|
+
validate_time_hash hash
|
112
|
+
@hours = hash[:hours]
|
113
|
+
@minutes = hash[:minutes] || 0
|
114
|
+
@seconds = hash[:seconds] || 0
|
115
|
+
seconds_since_midnight
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def init_with_array(array)
|
120
|
+
validate_time_array array
|
121
|
+
@hours = array[0]
|
122
|
+
@minutes = array[1] || 0
|
123
|
+
@seconds = array[2] || 0
|
124
|
+
seconds_since_midnight
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
def calculate_seconds_since_midnight
|
132
|
+
if @hours && @minutes && @seconds
|
133
|
+
cache = @seconds
|
134
|
+
cache += @minutes * 60
|
135
|
+
cache += @hours * 3600
|
136
|
+
validate_seconds_since_midnight cache
|
137
|
+
cache
|
138
|
+
else
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def calculate_hours_minutes_and_seconds
|
145
|
+
if @seconds_since_midnight
|
146
|
+
cache, @seconds = @seconds_since_midnight.divmod(60)
|
147
|
+
@hours, @minutes = cache.divmod(60)
|
148
|
+
else
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def validate_time_string(str)
|
155
|
+
unless TIME_STRING_REGEX =~ str
|
156
|
+
raise DatelessTime::InitializationError, "bad string format"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
# COLON = ":".freeze
|
162
|
+
# EMPTY = "".freeze
|
163
|
+
# PM = "pm".freeze
|
164
|
+
|
165
|
+
def time_string_to_array(str)
|
166
|
+
am_pm = false
|
167
|
+
|
168
|
+
if AM_PM_REGEX =~ str
|
169
|
+
am_pm = str[-2,2].downcase
|
170
|
+
str.sub!(AM_PM_REGEX, '')
|
171
|
+
end
|
172
|
+
|
173
|
+
ary = str.split(":").map(&:to_i)
|
174
|
+
ary[0] += 12 if (am_pm && am_pm == 'pm')
|
175
|
+
ary
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def validate_time_array(ary)
|
180
|
+
if ary.empty?
|
181
|
+
raise DatelessTime::InitializationError
|
182
|
+
elsif ary[0] > MAX_HOURS || (ary[1] && ary[1] > MAX_MINUTES) || (ary[2] && ary[2] > MAX_SECONDS)
|
183
|
+
raise DatelessTime::TimeOutOfRangeError
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def validate_time_hash(h)
|
189
|
+
if h.empty? || h[:hours].nil?
|
190
|
+
raise DatelessTime::InitializationError
|
191
|
+
elsif h[:hours] > MAX_HOURS || (h[:minutes] && h[:minutes] > MAX_MINUTES) || (h[:seconds] && h[:seconds] > MAX_SECONDS)
|
192
|
+
raise DatelessTime::TimeOutOfRangeError
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
def validate_seconds_since_midnight(seconds)
|
198
|
+
if seconds > SECONDS_IN_24_HOURS
|
199
|
+
raise DatelessTime::TimeOutOfRangeError
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
class DatelessTime::InitializationError < StandardError
|
208
|
+
end
|
209
|
+
|
210
|
+
class DatelessTime::TimeOutOfRangeError < DatelessTime::InitializationError
|
211
|
+
end
|
@@ -0,0 +1,323 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CreationTest < Minitest::Test
|
4
|
+
|
5
|
+
|
6
|
+
def test_create_with_now
|
7
|
+
@time = Time.now
|
8
|
+
@dl_time = DatelessTime.now
|
9
|
+
|
10
|
+
assert_equal @time.hour, @dl_time.hours
|
11
|
+
assert_equal @time.min, @dl_time.minutes
|
12
|
+
assert_equal @time.sec, @dl_time.seconds
|
13
|
+
assert_equal @time.strftime("%H:%M:%S"), @dl_time.to_s
|
14
|
+
assert_equal (@time.sec + (@time.min * 60) + (@time.hour * 60 * 60)), @dl_time.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def test_create_with_time
|
19
|
+
@time = Time.new 2014, 1, 1, 13, 37, 42
|
20
|
+
@dl_time = DatelessTime.new @time
|
21
|
+
|
22
|
+
assert_equal 13, @dl_time.hours
|
23
|
+
assert_equal 37, @dl_time.minutes
|
24
|
+
assert_equal 42, @dl_time.seconds
|
25
|
+
assert_equal (42 + (37 * 60) + (13 * 60 * 60)), @dl_time.to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def test_create_with_string
|
31
|
+
@dl_time = DatelessTime.new "12:13:14"
|
32
|
+
|
33
|
+
assert_equal 12, @dl_time.hours
|
34
|
+
assert_equal 13, @dl_time.minutes
|
35
|
+
assert_equal 14, @dl_time.seconds
|
36
|
+
assert_equal (14 + (13 * 60) + (12 * 60 * 60)), @dl_time.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
def test_create_with_string_without_seconds
|
42
|
+
@dl_time = DatelessTime.new "12:13"
|
43
|
+
|
44
|
+
assert_equal 12, @dl_time.hours
|
45
|
+
assert_equal 13, @dl_time.minutes
|
46
|
+
assert_equal 0, @dl_time.seconds
|
47
|
+
assert_equal ((13 * 60) + (12 * 60 * 60)), @dl_time.to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def test_create_with_string_without_seconds_and_minutes
|
52
|
+
@dl_time = DatelessTime.new "12"
|
53
|
+
|
54
|
+
assert_equal 12, @dl_time.hours
|
55
|
+
assert_equal 0, @dl_time.minutes
|
56
|
+
assert_equal 0, @dl_time.seconds
|
57
|
+
assert_equal (12 * 60 * 60), @dl_time.to_i
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
def test_create_with_bad_string
|
63
|
+
assert_raises DatelessTime::InitializationError do
|
64
|
+
@dl_time = DatelessTime.new "hello"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def test_create_with_bad_numerical_string
|
70
|
+
assert_raises DatelessTime::InitializationError do
|
71
|
+
@dl_time = DatelessTime.new "1000"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_create_with_empty_string
|
77
|
+
assert_raises DatelessTime::InitializationError do
|
78
|
+
@dl_time = DatelessTime.new("")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def test_create_with_string_with_am
|
84
|
+
@dl_time = DatelessTime.new "10:13:14 am"
|
85
|
+
|
86
|
+
assert_equal 10, @dl_time.hours
|
87
|
+
assert_equal 13, @dl_time.minutes
|
88
|
+
assert_equal 14, @dl_time.seconds
|
89
|
+
assert_equal (14 + (13 * 60) + (10 * 60 * 60)), @dl_time.to_i
|
90
|
+
|
91
|
+
@dl_time = DatelessTime.new "10:13AM"
|
92
|
+
|
93
|
+
assert_equal 10, @dl_time.hours
|
94
|
+
assert_equal 13, @dl_time.minutes
|
95
|
+
assert_equal 0, @dl_time.seconds
|
96
|
+
assert_equal ((13 * 60) + (10 * 60 * 60)), @dl_time.to_i
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def test_create_with_string_with_pm
|
101
|
+
@dl_time = DatelessTime.new "10:13:14 pm"
|
102
|
+
|
103
|
+
assert_equal 22, @dl_time.hours
|
104
|
+
assert_equal 13, @dl_time.minutes
|
105
|
+
assert_equal 14, @dl_time.seconds
|
106
|
+
assert_equal (14 + (13 * 60) + (22 * 60 * 60)), @dl_time.to_i
|
107
|
+
|
108
|
+
@dl_time = DatelessTime.new "10:13PM"
|
109
|
+
|
110
|
+
assert_equal 22, @dl_time.hours
|
111
|
+
assert_equal 13, @dl_time.minutes
|
112
|
+
assert_equal 0, @dl_time.seconds
|
113
|
+
assert_equal ((13 * 60) + (22 * 60 * 60)), @dl_time.to_i
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
def test_create_with_string_with_nonsensical_pm
|
119
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
120
|
+
@dl_time = DatelessTime.new "15:13:14 pm"
|
121
|
+
end
|
122
|
+
|
123
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
124
|
+
@dl_time = DatelessTime.new "13:13PM"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
def test_create_with_seconds
|
131
|
+
secs = 59 + (35 * 60) + (8 * 60 * 60)
|
132
|
+
@dl_time = DatelessTime.new secs
|
133
|
+
|
134
|
+
assert_equal 8, @dl_time.hours
|
135
|
+
assert_equal 35, @dl_time.minutes
|
136
|
+
assert_equal 59, @dl_time.seconds
|
137
|
+
assert_equal secs, @dl_time.to_i
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def test_create_with_very_few_seconds
|
142
|
+
secs = 10 + (2 * 60)
|
143
|
+
@dl_time = DatelessTime.new secs
|
144
|
+
|
145
|
+
assert_equal 0, @dl_time.hours
|
146
|
+
assert_equal 2, @dl_time.minutes
|
147
|
+
assert_equal 10, @dl_time.seconds
|
148
|
+
assert_equal secs, @dl_time.to_i
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
def test_create_with_zero_seconds
|
153
|
+
@dl_time = DatelessTime.new 0
|
154
|
+
|
155
|
+
assert_equal 0, @dl_time.hours
|
156
|
+
assert_equal 0, @dl_time.minutes
|
157
|
+
assert_equal 0, @dl_time.seconds
|
158
|
+
assert_equal 0, @dl_time.to_i
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def test_create_with_too_many_seconds
|
163
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
164
|
+
@dl_time = DatelessTime.new(DatelessTime::SECONDS_IN_24_HOURS + 1)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
def test_create_with_hash
|
171
|
+
@dl_time = DatelessTime.new({ hours: 1, minutes: 30, seconds: 45 })
|
172
|
+
|
173
|
+
assert_equal 1, @dl_time.hours
|
174
|
+
assert_equal 30, @dl_time.minutes
|
175
|
+
assert_equal 45, @dl_time.seconds
|
176
|
+
assert_equal (45 + (30 * 60) + (1 * 60 * 60)), @dl_time.to_i
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
def test_create_with_hash_with_extra_keys
|
181
|
+
@dl_time = DatelessTime.new({ hours: 1, minutes: 30, seconds: 45, foo: "bar" })
|
182
|
+
|
183
|
+
assert_equal 1, @dl_time.hours
|
184
|
+
assert_equal 30, @dl_time.minutes
|
185
|
+
assert_equal 45, @dl_time.seconds
|
186
|
+
assert_equal (45 + (30 * 60) + (1 * 60 * 60)), @dl_time.to_i
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
def test_create_with_hash_without_seconds
|
191
|
+
@dl_time = DatelessTime.new({ hours: 1, minutes: 30 })
|
192
|
+
|
193
|
+
assert_equal 1, @dl_time.hours
|
194
|
+
assert_equal 30, @dl_time.minutes
|
195
|
+
assert_equal 0, @dl_time.seconds
|
196
|
+
assert_equal ((30 * 60) + (1 * 60 * 60)), @dl_time.to_i
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
def test_create_with_hash_without_hours
|
201
|
+
assert_raises DatelessTime::InitializationError do
|
202
|
+
@dl_time = DatelessTime.new({ minutes: 30 })
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
def test_create_with_empty_hash
|
208
|
+
assert_raises DatelessTime::InitializationError do
|
209
|
+
@dl_time = DatelessTime.new({})
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
def test_create_with_hash_without_hours_but_other_random_keys
|
215
|
+
assert_raises DatelessTime::InitializationError do
|
216
|
+
@dl_time = DatelessTime.new({ batman: "nananana" })
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
def test_create_with_hash_without_seconds_and_minutes
|
222
|
+
@dl_time = DatelessTime.new({ hours: 1 })
|
223
|
+
|
224
|
+
assert_equal 1, @dl_time.hours
|
225
|
+
assert_equal 0, @dl_time.minutes
|
226
|
+
assert_equal 0, @dl_time.seconds
|
227
|
+
assert_equal (1 * 60 * 60), @dl_time.to_i
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
def test_create_with_array
|
232
|
+
@dl_time = DatelessTime.new [2, 11, 44]
|
233
|
+
|
234
|
+
assert_equal 2, @dl_time.hours
|
235
|
+
assert_equal 11, @dl_time.minutes
|
236
|
+
assert_equal 44, @dl_time.seconds
|
237
|
+
assert_equal (44 + (11 * 60) + (2 * 60 * 60)), @dl_time.to_i
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def test_create_with_array_with_extra_elements
|
242
|
+
@dl_time = DatelessTime.new [2, 11, 44, 1, 2, 3]
|
243
|
+
|
244
|
+
assert_equal 2, @dl_time.hours
|
245
|
+
assert_equal 11, @dl_time.minutes
|
246
|
+
assert_equal 44, @dl_time.seconds
|
247
|
+
assert_equal (44 + (11 * 60) + (2 * 60 * 60)), @dl_time.to_i
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
def test_create_with_array_without_seconds
|
252
|
+
@dl_time = DatelessTime.new [2, 11]
|
253
|
+
|
254
|
+
assert_equal 2, @dl_time.hours
|
255
|
+
assert_equal 11, @dl_time.minutes
|
256
|
+
assert_equal 0, @dl_time.seconds
|
257
|
+
assert_equal ((11 * 60) + (2 * 60 * 60)), @dl_time.to_i
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
def test_create_with_array_without_seconds_and_minutes
|
262
|
+
@dl_time = DatelessTime.new [2]
|
263
|
+
|
264
|
+
assert_equal 2, @dl_time.hours
|
265
|
+
assert_equal 0, @dl_time.minutes
|
266
|
+
assert_equal 0, @dl_time.seconds
|
267
|
+
assert_equal (2 * 60 * 60), @dl_time.to_i
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
def test_create_with_empty_array
|
272
|
+
assert_raises DatelessTime::InitializationError do
|
273
|
+
@dl_time = DatelessTime.new([])
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
def test_create_with_array_with_bad_data
|
279
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
280
|
+
@dl_time = DatelessTime.new([25, 10, 11])
|
281
|
+
end
|
282
|
+
|
283
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
284
|
+
@dl_time = DatelessTime.new([11, 67, 11])
|
285
|
+
end
|
286
|
+
|
287
|
+
assert_raises DatelessTime::TimeOutOfRangeError do
|
288
|
+
@dl_time = DatelessTime.new([9, 10, 100])
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
def test_create_without_argument
|
295
|
+
@time = Time.now
|
296
|
+
@dl_time = DatelessTime.new
|
297
|
+
|
298
|
+
assert_equal @time.hour, @dl_time.hours
|
299
|
+
assert_equal @time.min, @dl_time.minutes
|
300
|
+
assert_equal @time.sec, @dl_time.seconds
|
301
|
+
assert_equal @time.strftime("%H:%M:%S"), @dl_time.to_s
|
302
|
+
assert_equal (@time.sec + (@time.min * 60) + (@time.hour * 60 * 60)), @dl_time.to_i
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
def test_create_with_nil
|
308
|
+
assert_raises DatelessTime::InitializationError do
|
309
|
+
@dl_time = DatelessTime.new nil
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
|
314
|
+
def test_create_with_unsupported_objects
|
315
|
+
assert_raises DatelessTime::InitializationError do
|
316
|
+
@dl_time = DatelessTime.new (1..4)
|
317
|
+
end
|
318
|
+
|
319
|
+
assert_raises DatelessTime::InitializationError do
|
320
|
+
@dl_time = DatelessTime.new 1.21
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
data/test/query_test.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class QueryTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@dl_time = DatelessTime.new [13, 37, 42]
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
def test_to_time_without_base
|
12
|
+
@to_time = @dl_time.to_time
|
13
|
+
now = Time.now
|
14
|
+
expected = Time.new(now.year, now.month, now.day, 13, 37, 42, now.utc_offset)
|
15
|
+
|
16
|
+
assert_equal Time, @to_time.class
|
17
|
+
assert_equal expected, @to_time
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def test_to_time_with_base
|
22
|
+
base = Time.new(1990, 11, 10, 12, 13, 14)
|
23
|
+
@to_time = @dl_time.to_time(base)
|
24
|
+
|
25
|
+
assert_equal Time, @to_time.class
|
26
|
+
assert_equal Time.new(1990, 11, 10, 13, 37, 42), @to_time
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def test_to_s
|
31
|
+
assert_equal "13:37:42", @dl_time.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def test_to_s_with_padding_zeroes
|
36
|
+
@dl_time = DatelessTime.new [2, 7, 9]
|
37
|
+
assert_equal "02:07:09", @dl_time.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def test_to_h
|
42
|
+
assert_equal({ hours: 13, minutes: 37, seconds: 42 }, @dl_time.to_h)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def test_to_a
|
47
|
+
assert_equal [13, 37, 42], @dl_time.to_a
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def test_seconds_since_midnight
|
52
|
+
secs = 42 + (37 * 60) + (13 * 60 * 60)
|
53
|
+
assert_equal secs, @dl_time.seconds_since_midnight
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def test_to_i
|
58
|
+
secs = 42 + (37 * 60) + (13 * 60 * 60)
|
59
|
+
assert_equal secs, @dl_time.to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def test_accessor_hours
|
64
|
+
assert @dl_time.respond_to?(:hours)
|
65
|
+
assert_equal 13, @dl_time.hours
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def test_accessor_minutes
|
70
|
+
assert @dl_time.respond_to?(:minutes)
|
71
|
+
assert_equal 37, @dl_time.minutes
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def test_accessor_seconds
|
76
|
+
assert @dl_time.respond_to?(:seconds)
|
77
|
+
assert_equal 42, @dl_time.seconds
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def test_strftime
|
82
|
+
assert_equal "13:37", @dl_time.strftime("%H:%M")
|
83
|
+
assert_equal "13:37:42", @dl_time.strftime("%H:%M:%S")
|
84
|
+
assert_equal "13-37-42", @dl_time.strftime("%H-%M-%S")
|
85
|
+
|
86
|
+
assert_equal "1:37 pm", @dl_time.strftime("%-l:%M %P")
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dateless_time
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tommaso Pavese
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-05 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: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.3.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.3.1
|
55
|
+
description: A class to handle dateless time values.
|
56
|
+
email:
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".gitignore"
|
62
|
+
- Gemfile
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- dateless_time.gemspec
|
67
|
+
- lib/dateless_time.rb
|
68
|
+
- lib/dateless_time/version.rb
|
69
|
+
- test/creation_test.rb
|
70
|
+
- test/query_test.rb
|
71
|
+
- test/test_helper.rb
|
72
|
+
homepage: https://github.com/tompave/dateless_time
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.2.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: A class to handle dateless time values. DatelessTime objects are a lightweight
|
96
|
+
alternative Ruby's default Time class, and don't care about timezones and DST.
|
97
|
+
test_files:
|
98
|
+
- test/creation_test.rb
|
99
|
+
- test/query_test.rb
|
100
|
+
- test/test_helper.rb
|
101
|
+
has_rdoc:
|