units-time 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3894ab823f4d595259a95b23637fa877737a7632
4
- data.tar.gz: d9a684989b45c322a6ad86af619ca107a9d588eb
3
+ metadata.gz: cd753e92ae05a7b8124067b1530096616392cb33
4
+ data.tar.gz: 16ded8e6519cdc289e8ea6f452a7e985571ac602
5
5
  SHA512:
6
- metadata.gz: a08e3e095f76c77428ffdeb0ae5816b092a43a531266156750cbb2eccc7fb5ed969c35b83656d2c3b78ec1f5b44cc52255f7b167222097583465398a97313c7c
7
- data.tar.gz: 86c076784ddd8dead6797d797fce9adccb75bcce43cf04e22df5b676a9d3dd67ab1c355605ff79196c0c8758935f67f0f5923b96f9ffe5ea3045013cea27c49e
6
+ metadata.gz: d2e4132b9194102097f6ebcfbf1c78145f6467965c19df49d30b61808b5732a168c38e00af35a371af8357d34bc730568be7bf628c87f075d276851098d4ea65
7
+ data.tar.gz: 0c3f079769f959f77f58913f79396a87bbbed7032b5fe435933f7ac6e3c3fc715fd91352412d3afca32362d56025f745d72052f7b0cdb75ffd8120650bce5113
data/README.md CHANGED
@@ -11,7 +11,93 @@ units-time library / gem - units of time (in epoch time) incl. seconds, minutes,
11
11
 
12
12
  ## Usage
13
13
 
14
- to be done
14
+ [Timestamp](#timestamp) [Timedelta](#timedelta)
15
+
16
+
17
+ The following methods are added on `Integer` (`Fixnum` and `Bignum`)
18
+ and always return a `Timedelta` object (in seconds):
19
+
20
+ ``` ruby
21
+ # plural versions
22
+ 2.seconds #=> <Timedelta seconds=2>
23
+ 2.secs #=> <Timedelta seconds=2>
24
+ 3.minutes #=> <Timedelta seconds=180>
25
+ 3.mins #=> <Timedelta seconds=180>
26
+ 4.hours #=> <Timedelta seconds=14_400>
27
+ 5.days #=> <Timedelta seconds=432_000>
28
+ 6.weeks #=> <Timedelta seconds=3_628_800>
29
+ 7.fortnights #=> <Timedelta seconds=8_467_200>
30
+ 8.years #=> <Timedelta seconds=252_288_000>
31
+
32
+ # singular versions
33
+ 1.second #=> <Timedelta seconds=1>
34
+ 1.sec #=> <Timedelta seconds=1>
35
+ 1.minute #=> <Timedelta seconds=60>
36
+ 1.min #=> <Timedelta seconds=60>
37
+ 1.hour #=> <Timedelta seconds=3600>
38
+ 1.day #=> <Timedelta seconds=86_400>
39
+ 1.week #=> <Timedelta seconds=604_800>
40
+ 1.fortnight #=> <Timedelta seconds=1_209_600>
41
+ 1.year #=> <Timedelta seconds=31_536_000>
42
+ ```
43
+
44
+
45
+ ### Time arithmetics
46
+
47
+ You can add and subtract durations from `Timestamp` or `Timedelta` objects.
48
+
49
+ ``` ruby
50
+ Timestamp.now + 2.hours #=> <Timestamp seconds= >
51
+ 1.week + 1.day #=> <Timedelta seconds= >
52
+ 2.minutes - 1.second #=> <TimeDelta seconds= >
53
+ ```
54
+
55
+ Note: You CANNOT add or subtract integers to `Timestamp` or `Timedelta` objects
56
+ and vice versa.
57
+
58
+ ``` ruby
59
+ # Bad
60
+ 10 + 1.minute #=> Boom! <TypeError>
61
+ 1.minute + 10 #=> Boom! <TypeError>
62
+
63
+ # Good
64
+ 10.seconds + 1.minute #=> <Timedelta seconds=70>
65
+ 1.minute.to_i + 10 #=> Integer
66
+ ```
67
+
68
+ Note: Multiply an integer with `1.hour` or `1.minute` or `1.second` and so on
69
+ to convert to a time unit.
70
+
71
+ ``` ruby
72
+ 100*1.hour #=> <Timedelta seconds=360_000>
73
+ ```
74
+
75
+
76
+ ### Timestamp
77
+
78
+ The `Timestamp` class holds the time in seconds since unix epoch time (that is, January 1st, 1970).
79
+
80
+ ``` ruby
81
+ Timestamp.new(0) # or Timestamp(0)
82
+ ```
83
+
84
+ To get the time now use:
85
+
86
+ ``` ruby
87
+ Timestamp.now # or Timestamp.new
88
+ ```
89
+
90
+
91
+
92
+ ### Timedelta
93
+
94
+ The `Timedelta` class holds a time duration in seconds.
95
+
96
+ ``` ruby
97
+ Timedelta.new # or Timedelta(0)
98
+ ```
99
+
100
+
15
101
 
16
102
 
17
103
  ## License
data/lib/units-time.rb CHANGED
@@ -1,12 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- ##
4
- # todo/fix: use module
5
- ## use Timestamp and Timedelta classes etc.
6
-
7
-
8
3
  ## stdlibs
9
4
  require 'pp'
5
+ require 'time'
10
6
 
11
7
 
12
8
  ## our own code
@@ -14,52 +10,226 @@ require 'units-time/version' # note: let version always go first
14
10
 
15
11
 
16
12
 
13
+ #########################
14
+ # type constraints:
15
+ #
16
+ # note: for now
17
+ # - you CANNOT add a timestamp to another timestamp
18
+ # - you CAN only compare (<=>) timestamp to timestamp but NOT timedelta !!
19
+ # - you CAN only compare (<=>) timedelta to timedelta but NOT timestamp !!
20
+
21
+ class Timestamp
22
+
23
+ def self.now() new( Time.now.to_i ); end
24
+
25
+ attr_reader :seconds
26
+
27
+ def initialize( seconds=Time.now.to_i )
28
+ @seconds = seconds ## seconds since Jan 1st, 1970 (unix epoch time)
29
+ end
30
+
31
+ def ==( other )
32
+ if other.is_a?( self.class )
33
+ @seconds == other.seconds
34
+ else
35
+ ## note: allow for now integer comparision too - why? why not?
36
+ if other.is_a?( Integer )
37
+ @seconds == other
38
+ else
39
+ false
40
+ end
41
+ end
42
+ end
43
+ alias_method :eql?, :==
44
+
45
+ def +( other )
46
+ if other.is_a?( Timedelta )
47
+ self.class.new( @seconds + other.seconds )
48
+ else
49
+ ## fix/todo: use TypeError!!!!
50
+ raise ArgumentError.new( "[Timestamp] add(ition) - wrong type #{other.inspect} - Timedelta expected" )
51
+ end
52
+ end
53
+
54
+ def -( other )
55
+ if other.is_a?( Timedelta )
56
+ self.class.new( @seconds - other.seconds )
57
+ else
58
+ ## fix/todo: use TypeError!!!!
59
+ raise ArgumentError.new( "[Timestamp] sub(straction) - wrong type #{other.inspect} - Timedelta expected" )
60
+ end
61
+ end
62
+
63
+
64
+ include Comparable
65
+
66
+ def <=>( other )
67
+ if other.is_a?( self.class )
68
+ @seconds <=> other.seconds
69
+ else
70
+ ## fix/todo: use TypeError!!!!
71
+ raise ArgumentError.new( "[Timestamp] <=> - wrong type #{other.inspect} - Timestamp expected" )
72
+ end
73
+ end
74
+
75
+
76
+ ## todo/fix: always freeze by default (timestamp is immutable) - why? why not?
77
+ def self.zero() @@zero ||= new(0).freeze; end
78
+
79
+ alias_method :to_i, :seconds ## add to integer conversion - why? why not?
80
+ alias_method :to_int, :seconds
81
+ end ## class Timestamp
82
+
83
+
84
+
85
+ class Timedelta
86
+
87
+ attr_reader :seconds
88
+
89
+ def initialize( seconds=0 )
90
+ @seconds = seconds
91
+ end
92
+
93
+
94
+ def ==( other )
95
+ if other.is_a?( self.class )
96
+ @seconds == other.seconds
97
+ else
98
+ ## note: allow for now integer comparision too - why? why not?
99
+ if other.is_a?( Integer )
100
+ @seconds == other
101
+ else
102
+ false
103
+ end
104
+ end
105
+ end
106
+ alias_method :eql?, :==
107
+
108
+ def *( other )
109
+ if other.is_a?( Integer )
110
+ self.class.new( @seconds * other )
111
+ else
112
+ ## fix/todo: use TypeError!!!!
113
+ raise ArgumentError.new( "[Timedelta] mul(tiplication) - wrong type #{other.inspect} - integer number expected" )
114
+ end
115
+ end
116
+
117
+ def +( other )
118
+ if other.is_a?( self.class )
119
+ self.class.new( @seconds + other.seconds )
120
+ else
121
+ ## fix/todo: use TypeError!!!!
122
+ raise ArgumentError.new( "[Timedelta] add(ition) - wrong type #{other.inspect} - Timedelta expected" )
123
+ end
124
+ end
125
+
126
+ def -( other )
127
+ if other.is_a?( self.class )
128
+ self.class.new( @seconds - other.seconds )
129
+ else
130
+ ## fix/todo: use TypeError!!!!
131
+ raise ArgumentError.new( "[Timedelta] sub(straction) - wrong type #{other.inspect} - Timedelta expected" )
132
+ end
133
+ end
134
+
135
+
136
+ ### for details on coerce
137
+ ## see https://blog.dnsimple.com/2017/01/ruby-coercion-protocols-part-2/
138
+ def coerce( other )
139
+ if other.is_a?( Integer )
140
+ [self, other] ## allow communitative - switch left and right e.g. 365*24.hours to 24.hours*365
141
+ else
142
+ ## fix/todo: use TypeError!!!!
143
+ raise ArgumentError.new( "[Timedelta] coerce - wrong type #{other.inspect} - Integer number expected" )
144
+ end
145
+ end
146
+
147
+
148
+ include Comparable
149
+
150
+ def <=>( other )
151
+ if other.is_a?( self.class )
152
+ @seconds <=> other.seconds
153
+ else
154
+ ## fix/todo: use TypeError!!!!
155
+ raise ArgumentError.new( "[Timedelta] <=> - wrong type #{other.inspect} - Timedelta expected" )
156
+ end
157
+ end
158
+
159
+
160
+ ## todo/fix: always freeze by default (timedelta is immutable) - why? why not?
161
+ def self.zero() @@zero ||= new(0).freeze; end
17
162
 
18
- class Integer
19
-
163
+ alias_method :to_i, :seconds ## add to integer conversion - why? why not?
164
+ alias_method :to_int, :seconds
165
+ ## note: same as:
166
+ ## def to_i() @seconds; end ## add to integer conversion - why? why not?
167
+ ## def to_int() @seconds; end
168
+ end # class Timedelta
169
+
170
+
171
+ ### "global" converter functions use like
172
+ ## Timestamp(0) or Timedelta(0)
173
+ def Timestamp(arg) Timestamp.new( arg ); end
174
+ def Timedelta(arg) Timedelta.new( arg ); end
175
+
176
+
177
+
178
+ module TimeUnits
20
179
  ######################################
21
180
  ## note: there's NO month (for now)!!!
22
181
  ## why? month might be 28,29,30,31 days
23
182
  ## use days e.g. 30.days or 31.days etc.
24
183
 
184
+
25
185
  HOUR_IN_SECONDS = 60 * 60 # 60 minutes * 60 seconds
26
186
  DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS # 24 hours * 60 * 60
27
187
  WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS # 7 days * 24 * 60 * 60
28
188
  FORTNIGHT_IN_SECONDS = 14 * DAY_IN_SECONDS # 14 days * 24 * 60 * 60
189
+
190
+ #####
191
+ # note: for year use 365 days for now and NOT 365.25 (1/4)
192
+ # - why? why not? discuss
29
193
  YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS # 365 days * 24 * 60 * 60
30
194
 
31
- def second() self; end
32
- def minute() self * 60; end
33
- def hour() self * HOUR_IN_SECONDS; end
34
- def day() self * DAY_IN_SECONDS; end
35
- def week() self * WEEK_IN_SECONDS; end
36
- def fortnight() self * FORTNIGHT_IN_SECONDS; end
37
- def year() self * YEAR_IN_SECONDS; end
195
+ def second() Timedelta.new( self ); end
196
+ def minute() Timedelta.new( self * 60 ); end
197
+ def hour() Timedelta.new( self * HOUR_IN_SECONDS ); end
198
+ def day() Timedelta.new( self * DAY_IN_SECONDS ); end
199
+ def week() Timedelta.new( self * WEEK_IN_SECONDS ); end
200
+ def fortnight() Timedelta.new( self * FORTNIGHT_IN_SECONDS ); end
201
+ def year() Timedelta.new( self * YEAR_IN_SECONDS ); end
202
+
38
203
 
39
204
  ########################################################
40
- ## alias - use alias or alias_method - why? why not?
41
- def seconds() second; end
42
- def secs() second; end
43
- def sec() second; end
44
- def s() second; end
205
+ ## alias
206
+ alias_method :seconds, :second
207
+ alias_method :secs, :second
208
+ alias_method :sec, :second
209
+ ## def s() second; end ### todo/fix: remove/add - why? why not?
210
+
211
+ alias_method :minutes, :minute
212
+ alias_method :mins, :minute
213
+ alias_method :min, :minute
214
+ ## def m() minute; end ### todo/fix: remove/add - why? why not?
45
215
 
46
- def minutes() minute; end
47
- def mins() minute; end
48
- def min() minute; end
49
- def m() minute; end
216
+ alias_method :hours, :hour
217
+ ## def h() hour; end ### todo/fix: remove/add - why? why not?
50
218
 
51
- def hours() hour; end
52
- def h() hour; end
219
+ alias_method :days, :day
220
+ ## def d() day; end ### todo/fix: remove/add - why? why not?
53
221
 
54
- def days() day; end
55
- def d() day; end
222
+ alias_method :weeks, :week
223
+ ## def w() week; end ### todo/fix: remove/add - why? why not?
56
224
 
57
- def weeks() week; end
58
- def w() week; end
225
+ alias_method :fortnights, :fortnight
59
226
 
60
- def fortnights() fortnight; end
227
+ alias_method :years, :year
228
+ ## def y() year; end ### todo/fix: remove/add - why? why not?
229
+ end # module TimeUnits
61
230
 
62
- def years() year; end
63
- def y() year; end
64
231
 
232
+
233
+ class Integer
234
+ include TimeUnits
65
235
  end # class Integer
@@ -2,9 +2,9 @@
2
2
 
3
3
  module UnitsTime
4
4
 
5
- MAJOR = 0
5
+ MAJOR = 1
6
6
  MINOR = 0
7
- PATCH = 1
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -10,66 +10,103 @@ require 'helper'
10
10
 
11
11
  class TestUnitsTime < MiniTest::Test
12
12
 
13
- def test_time
14
- now = Time.now.to_i
15
-
16
- assert_equal 31_536_000, 1.year
17
- assert_equal 31_536_000, 1.y
18
- assert_equal 31_536_000*2, 2.years
19
- assert_equal 31_536_000*2, 1.y*2
20
- assert_equal now+31_536_000, now+1.year
21
- assert_equal 31_536_000, 365.days
22
- assert_equal 31_536_000, 365*24.hours
23
-
24
- assert_equal 1_209_600, 1.fortnight
25
- assert_equal 1_209_600*2, 2.fortnights
26
- assert_equal 1_209_600*2, 1.fortnight*2
27
- assert_equal now+1_209_600, now+1.fortnight
28
- assert_equal 1_209_600, 2.weeks
29
- assert_equal 1_209_600, 14.days
30
- assert_equal 1_209_600, 14*24.hours
31
-
32
- assert_equal 604_800, 1.week
33
- assert_equal 604_800, 1.w
34
- assert_equal 604_800*2, 2.weeks
35
- assert_equal 604_800*2, 1.week*2
36
- assert_equal now+604_800, now+1.week
37
- assert_equal 604_800, 7.days
38
- assert_equal 604_800, 7*24.hours
39
-
40
- assert_equal 86_400, 1.day
41
- assert_equal 86_400, 1.d
42
- assert_equal 86_400*2, 2.days
43
- assert_equal 86_400*2, 1.day*2
44
- assert_equal now+86_400, now+1.day
45
- assert_equal 86_400, 24.hours
46
- assert_equal 86_400, 24*1.hour
47
-
48
- assert_equal 3600, 1.hour
49
- assert_equal 3600, 1.h
50
- assert_equal 3600*2, 2.hours
51
- assert_equal 3600*2, 1.hour*2
52
- assert_equal now+3600, now+1.hour
53
- assert_equal 3600, 60.minutes
54
- assert_equal 3600, 60*1.minute
55
-
56
- assert_equal 60, 1.minute
57
- assert_equal 60, 1.min
58
- assert_equal 60, 1.m
59
- assert_equal 60*2, 2.minutes
60
- assert_equal 60*2, 2.mins
61
- assert_equal 60*2, 1.minute*2
62
- assert_equal now+60, now+1.minute
63
- assert_equal 60, 60.seconds
64
- assert_equal 60, 60*1.second
65
-
66
- assert_equal 1, 1.second
67
- assert_equal 1, 1.sec
68
- assert_equal 1, 1.s
69
- assert_equal 1*2, 2.seconds
70
- assert_equal 1*2, 2.secs
71
- assert_equal 1*2, 1.second*2
72
- assert_equal now+1, now+1.second
13
+ def test_timstamp
14
+ now = Timestamp.now
15
+
16
+ assert_equal now.to_i, now
17
+
18
+ assert_equal now+31_536_000.secs, now+1.year
19
+ assert_equal now+1_209_600.secs, now+1.fortnight
20
+ assert_equal now+604_800.secs, now+1.week
21
+ assert_equal now+86_400.secs, now+1.day
22
+ assert_equal now+3600.secs, now+1.hour
23
+ assert_equal now+60.secs, now+1.minute
24
+ assert_equal now+1.sec, now+1.second
25
+
26
+ assert_equal true, now+1.second > now
27
+ assert_equal true, now+1.second >= now
28
+ assert_equal false, now+1.second < now
29
+ assert_equal false, now+1.second <= now
30
+ end
31
+
32
+
33
+ def test_timedelta
34
+ assert_equal 31_536_000.secs, 1.year
35
+ ## assert_equal 31_536_000, 1.y
36
+ assert_equal 31_536_000.secs*2, 2.years
37
+ assert_equal 31_536_000.secs*2, 1.year*2
38
+ ## assert_equal 31_536_000*2, 1.y*2
39
+ assert_equal 31_536_000.secs, 365.days
40
+ assert_equal 31_536_000.secs, 24.hours*365 ## note: uses coerce for type coercion
41
+ assert_equal 31_536_000.secs, 365*24.hours
42
+
43
+ assert_equal 1_209_600.secs, 1.fortnight
44
+ assert_equal 1_209_600.secs*2, 2.fortnights
45
+ assert_equal 1_209_600.secs*2, 1.fortnight*2
46
+ assert_equal 1_209_600.secs, 2.weeks
47
+ assert_equal 1_209_600.secs, 14.days
48
+ assert_equal 1_209_600.secs, 14*24.hours ## note: uses coerce for type coercion
49
+ assert_equal 1_209_600.secs, 24.hours*14
50
+
51
+ assert_equal 604_800.secs, 1.week
52
+ ## assert_equal 604_800, 1.w
53
+ assert_equal 604_800.secs*2, 2.weeks
54
+ assert_equal 604_800.secs*2, 1.week*2
55
+ assert_equal 604_800.secs, 7.days
56
+ assert_equal 604_800.secs, 7*24.hours ## note: uses coerce for type coercion
57
+ assert_equal 604_800.secs, 24.hours*7
58
+
59
+ assert_equal 86_400.secs, 1.day
60
+ ## assert_equal 86_400, 1.d
61
+ assert_equal 86_400.secs*2, 2.days
62
+ assert_equal 86_400.secs*2, 1.day*2
63
+ assert_equal 86_400.secs, 24.hours
64
+ assert_equal 86_400.secs, 24*1.hour ## note: uses coerce for type coercion
65
+ assert_equal 86_400.secs, 1.hour*24
66
+
67
+ assert_equal 3600.secs, 1.hour
68
+ ## assert_equal 3600, 1.h
69
+ assert_equal 3600.secs*2, 2.hours
70
+ assert_equal 3600.secs*2, 1.hour*2
71
+ assert_equal 3600.secs, 60.minutes
72
+ assert_equal 3600.secs, 60*1.minute ## note: uses coerce for type coercion
73
+ assert_equal 3600.secs, 1.minute*60
74
+
75
+ assert_equal 60.secs, 1.minute
76
+ assert_equal 60.secs, 1.min
77
+ ## assert_equal 60, 1.m
78
+ assert_equal 60.secs*2, 2.minutes
79
+ assert_equal 60.secs*2, 2.mins
80
+ assert_equal 60.secs*2, 1.minute*2
81
+ assert_equal 60.secs, 60.seconds
82
+ assert_equal 60.secs, 60*1.second ## note: uses coerce for type coercion
83
+ assert_equal 60.secs, 1.second*60
84
+
85
+ assert_equal 1.sec, 1.second
86
+ assert_equal 1.sec, 1.sec
87
+ ## assert_equal 1, 1.s
88
+ assert_equal 1.sec*2, 2.seconds
89
+ assert_equal 1.sec*2, 2.secs
90
+ assert_equal 1.sec*2, 1.second*2
91
+ end
92
+
93
+ def test_timedelta_ops
94
+ assert_equal (31_536_000+1_209_600+604_800).secs, 1.year+1.fortnight+1.week
95
+
96
+ now = Timestamp.now
97
+ assert_equal Timedelta, (100 * 1.hour).class
98
+ assert_equal now+100*3600.secs, now + (100 * 1.hour)
99
+ assert_equal Timestamp, (now + (100 * 1.hour)).class
100
+ end
101
+
102
+ def test_conv
103
+ assert_equal Timestamp.new(0), Timestamp(0)
104
+ assert_equal Timedelta.new, Timedelta(0)
105
+
106
+ assert_equal Timestamp.zero, Timestamp(0)
107
+ assert_equal Timedelta.zero, Timedelta(0)
108
+
109
+ assert_equal 0.secs, Timedelta(0)
73
110
  end
74
111
 
75
112
  end # class TestUnitsTime
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: units-time
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-09 00:00:00.000000000 Z
11
+ date: 2019-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc