ruby-units 1.0.1 → 1.0.2
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.
- data/CHANGELOG.txt +146 -128
- data/Manifest.txt +11 -1
- data/Rakefile +2 -1
- data/lib/ruby-units.rb +10 -1413
- data/lib/ruby_units/array.rb +9 -0
- data/lib/ruby_units/complex.rb +10 -0
- data/lib/ruby_units/date.rb +51 -0
- data/lib/ruby_units/math.rb +87 -0
- data/lib/ruby_units/numeric.rb +8 -0
- data/lib/ruby_units/object.rb +8 -0
- data/lib/ruby_units/ruby-units.rb +1104 -0
- data/lib/ruby_units/string.rb +94 -0
- data/lib/ruby_units/time.rb +73 -0
- data/lib/{units.rb → ruby_units/units.rb} +12 -2
- data/lib/ruby_units.rb +11 -1
- data/test/test_ruby-units.rb +28 -23
- metadata +12 -3
@@ -0,0 +1,94 @@
|
|
1
|
+
# make a string into a unit
|
2
|
+
class String
|
3
|
+
def to_unit(other = nil)
|
4
|
+
other ? Unit.new(self).to(other) : Unit.new(self)
|
5
|
+
end
|
6
|
+
alias :unit :to_unit
|
7
|
+
alias :u :to_unit
|
8
|
+
alias :unit_format :%
|
9
|
+
|
10
|
+
# format unit output using formating codes '%0.2f' % '1 mm'.unit => '1.00 mm'
|
11
|
+
def %(*args)
|
12
|
+
case args[0]
|
13
|
+
when Unit: args[0].to_s(self)
|
14
|
+
when defined?(Uncertain) && Uncertain === args[0]: args[0].to_s(self)
|
15
|
+
when Complex: args[0].to_s
|
16
|
+
else
|
17
|
+
unit_format(*args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#needed for compatibility with Rails, which defines a String.from method
|
22
|
+
if self.public_instance_methods.include? 'from'
|
23
|
+
alias :old_from :from
|
24
|
+
end
|
25
|
+
|
26
|
+
def from(time_point = ::Time.now)
|
27
|
+
return old_from(time_point) if Integer === time_point
|
28
|
+
self.unit.from(time_point)
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :after :from
|
32
|
+
alias :from_now :from
|
33
|
+
|
34
|
+
def ago
|
35
|
+
self.unit.ago
|
36
|
+
end
|
37
|
+
|
38
|
+
def before(time_point = ::Time.now)
|
39
|
+
self.unit.before(time_point)
|
40
|
+
end
|
41
|
+
alias :before_now :before
|
42
|
+
|
43
|
+
def since(time_point = ::Time.now)
|
44
|
+
self.unit.since(time_point)
|
45
|
+
end
|
46
|
+
|
47
|
+
def until(time_point = ::Time.now)
|
48
|
+
self.unit.until(time_point)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to(other)
|
52
|
+
self.unit.to(other)
|
53
|
+
end
|
54
|
+
|
55
|
+
def time(options = {})
|
56
|
+
self.to_time(options) rescue self.to_datetime(options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_time(options = {})
|
60
|
+
begin
|
61
|
+
#raises exception when Chronic not defined or when it returns a nil (i.e., can't parse the input)
|
62
|
+
r = Chronic.parse(self,options)
|
63
|
+
raise(ArgumentError, 'Invalid Time String') unless r
|
64
|
+
return r
|
65
|
+
rescue
|
66
|
+
Time.local(*ParseDate.parsedate(self))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_datetime(options = {})
|
71
|
+
begin
|
72
|
+
# raises an exception if Chronic.parse = nil or if Chronic not defined
|
73
|
+
r = Chronic.parse(self,options).to_datetime
|
74
|
+
rescue
|
75
|
+
r=DateTime.civil(*ParseDate.parsedate(self)[0..5].compact)
|
76
|
+
end
|
77
|
+
raise RuntimeError, "Invalid Time String" if r == DateTime.new
|
78
|
+
return r
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_date(options={})
|
82
|
+
begin
|
83
|
+
r = Chronic.parse(self,options).to_date
|
84
|
+
rescue
|
85
|
+
r = Date.civil(*ParseDate.parsedate(self)[0..5].compact)
|
86
|
+
end
|
87
|
+
raise RuntimeError, 'Invalid Date String' if r == Date.new
|
88
|
+
return r
|
89
|
+
end
|
90
|
+
|
91
|
+
def datetime(options = {})
|
92
|
+
self.to_datetime(options) rescue self.to_time(options)
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Time math is handled slightly differently. The difference is considered to be an exact duration if
|
3
|
+
# the subtracted value is in hours, minutes, or seconds. It is rounded to the nearest day if the offset
|
4
|
+
# is in years, decades, or centuries. This leads to less precise values, but ones that match the
|
5
|
+
# calendar better.
|
6
|
+
class Time
|
7
|
+
|
8
|
+
class << self
|
9
|
+
alias unit_time_at at
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.at(*args)
|
13
|
+
if Unit === args[0]
|
14
|
+
unit_time_at(args[0].to("s").scalar)
|
15
|
+
else
|
16
|
+
unit_time_at(*args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_unit(other = nil)
|
21
|
+
other ? Unit.new(self).to(other) : Unit.new(self)
|
22
|
+
end
|
23
|
+
alias :unit :to_unit
|
24
|
+
alias :u :to_unit
|
25
|
+
alias :unit_add :+
|
26
|
+
|
27
|
+
def to_datetime
|
28
|
+
DateTime.civil(1970,1,1)+(self.to_f+self.gmt_offset)/86400
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_date
|
32
|
+
x=(Date.civil(1970,1,1)+((self.to_f+self.gmt_offset)/86400.0)-0.5)
|
33
|
+
Date.civil(x.year, x.month, x.day)
|
34
|
+
end
|
35
|
+
|
36
|
+
def +(other)
|
37
|
+
case other
|
38
|
+
when Unit:
|
39
|
+
other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
|
40
|
+
begin
|
41
|
+
unit_add(other.to('s').scalar)
|
42
|
+
rescue RangeError
|
43
|
+
self.to_datetime + other
|
44
|
+
end
|
45
|
+
when DateTime: unit_add(other.to_time)
|
46
|
+
else
|
47
|
+
unit_add(other)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# usage: Time.in '5 min'
|
52
|
+
def self.in(duration)
|
53
|
+
Time.now + duration.to_unit
|
54
|
+
end
|
55
|
+
|
56
|
+
alias :unit_sub :-
|
57
|
+
|
58
|
+
def -(other)
|
59
|
+
case other
|
60
|
+
when Unit:
|
61
|
+
other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
|
62
|
+
begin
|
63
|
+
unit_sub(other.to('s').scalar)
|
64
|
+
rescue RangeError
|
65
|
+
self.to_datetime - other
|
66
|
+
end
|
67
|
+
|
68
|
+
when DateTime: unit_sub(other.to_time)
|
69
|
+
else
|
70
|
+
unit_sub(other)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -86,7 +86,7 @@ UNIT_DEFINITIONS = {
|
|
86
86
|
#speed
|
87
87
|
'<kph>' => [%w{kph}, 0.277777778, :speed, %w{<meter>}, %w{<second>}],
|
88
88
|
'<mph>' => [%w{mph}, 0.44704, :speed, %w{<meter>}, %w{<second>}],
|
89
|
-
'<knot>' => [%w{kn knot knots}, 0.514444444, :speed, %w{<meter>}, %w{<second>}],
|
89
|
+
'<knot>' => [%w{kt kn kts knot knots}, 0.514444444, :speed, %w{<meter>}, %w{<second>}],
|
90
90
|
'<fps>' => [%w{fps}, 0.3048, :speed, %w{<meter>}, %w{<second>}],
|
91
91
|
|
92
92
|
#acceleration
|
@@ -117,12 +117,14 @@ UNIT_DEFINITIONS = {
|
|
117
117
|
'<pascal>' => [%w{Pa pascal Pascal}, 1.0, :pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
118
118
|
'<bar>' => [%w{bar bars}, 100000, :pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
119
119
|
'<mmHg>' => [%w{mmHg}, 133.322368,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
120
|
+
'<inHg>' => [%w{inHg}, 3386.3881472,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
120
121
|
'<torr>' => [%w{torr}, 133.322368,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
121
122
|
'<bar>' => [%w{bar}, 100000,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
122
123
|
'<atm>' => [%w{atm ATM atmosphere atmospheres}, 101325,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
123
124
|
'<psi>' => [%w{psi}, 6894.76,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
124
125
|
'<cmh2o>' => [%w{cmH2O}, 98.0638,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
125
|
-
|
126
|
+
'<inh2o>' => [%w{inH2O}, 249.082052,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}],
|
127
|
+
|
126
128
|
#viscosity
|
127
129
|
'<poise>' => [%w{P poise}, 0.1, :viscosity, %w{<kilogram>},%w{<meter> <second>} ],
|
128
130
|
'<stokes>' => [%w{St stokes}, 1e-4, :viscosity, %w{<meter> <meter>}, %w{<second>}],
|
@@ -221,6 +223,14 @@ UNIT_DEFINITIONS = {
|
|
221
223
|
'<dpm>' => [%w{dpm}, 1.0/60.0, :rate, %w{<count>},%w{<second>}],
|
222
224
|
'<bpm>' => [%w{bpm}, 1.0/60.0, :rate, %w{<count>},%w{<second>}],
|
223
225
|
|
226
|
+
#resolution / typography
|
227
|
+
'<dot>' => [%w{dot dots}, 1, :resolution, %w{<each>}],
|
228
|
+
'<pixel>' => [%w{pixel px}, 1, :resolution, %w{<each>}],
|
229
|
+
'<ppi>' => [%w{ppi}, 1, :resolution, %w{<pixel>}, %w{<inch>}],
|
230
|
+
'<dpi>' => [%w{dpi}, 1, :typography, %w{<dot>}, %w{<inch>}],
|
231
|
+
'<pica>' => [%w{pica}, 0.00423333333 , :typography, %w{<meter>}],
|
232
|
+
'<point>' => [%w{point pt}, 0.000352777778, :typography, %w{<meter>}],
|
233
|
+
|
224
234
|
#other
|
225
235
|
'<cell>' => [%w{cells cell}, 1, :counting, %w{<each>}],
|
226
236
|
'<each>' => [%w{each}, 1.0, :counting, %w{<each>}],
|
data/lib/ruby_units.rb
CHANGED
@@ -1 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
require 'ruby_units/array'
|
2
|
+
require 'ruby_units/date'
|
3
|
+
require 'ruby_units/time'
|
4
|
+
require 'ruby_units/math'
|
5
|
+
require 'ruby_units/numeric'
|
6
|
+
require 'ruby_units/object'
|
7
|
+
require 'ruby_units/string'
|
8
|
+
require 'ruby_units/complex'
|
9
|
+
require 'ruby_units/units'
|
10
|
+
require 'ruby_units/ruby-units'
|
11
|
+
|
data/test/test_ruby-units.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'ruby-units'
|
3
|
-
require 'uncertain'
|
4
3
|
require 'rubygems'
|
4
|
+
require 'uncertain'
|
5
5
|
require 'yaml'
|
6
6
|
require 'chronic'
|
7
7
|
|
8
|
+
|
9
|
+
|
8
10
|
class Unit < Numeric
|
9
11
|
@@USER_DEFINITIONS = {'<inchworm>' => [%w{inworm inchworm}, 0.0254, :length, %w{<meter>} ],
|
10
12
|
'<habenero>' => [%{degH}, 100, :temperature, %w{<celcius>}]}
|
@@ -261,14 +263,14 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
261
263
|
c = '1 in'.unit
|
262
264
|
d = '1 ml'.unit
|
263
265
|
|
264
|
-
assert_equal (a+b)
|
265
|
-
assert_equal (a+b).units,
|
266
|
-
assert_equal (b+a)
|
267
|
-
assert_equal (b+a).units,
|
266
|
+
assert_equal (a+b), b
|
267
|
+
assert_equal (a+b).units, b.units
|
268
|
+
assert_equal (b+a), b
|
269
|
+
assert_equal (b+a).units, b.units
|
268
270
|
assert_in_delta (b+c).scalar, 12.54, 0.01
|
269
271
|
assert_equal (b+c).units, 'cm'
|
270
272
|
assert_raises(ArgumentError) {
|
271
|
-
|
273
|
+
b + d
|
272
274
|
}
|
273
275
|
end
|
274
276
|
|
@@ -278,14 +280,14 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
278
280
|
c = '1 in'.unit
|
279
281
|
d = '1 ml'.unit
|
280
282
|
|
281
|
-
assert_equal (a-b)
|
282
|
-
assert_equal (a-b).units,
|
283
|
-
assert_equal (b-a)
|
284
|
-
assert_equal (b-a).units,
|
283
|
+
assert_equal (a-b), -b
|
284
|
+
assert_equal (a-b).units, b.units
|
285
|
+
assert_equal (b-a), b
|
286
|
+
assert_equal (b-a).units, b.units
|
285
287
|
assert_in_delta (b-c).scalar, 7.46, 0.01
|
286
288
|
assert_equal (b-c).units, 'cm'
|
287
289
|
assert_raises(ArgumentError) {
|
288
|
-
|
290
|
+
b - d
|
289
291
|
}
|
290
292
|
end
|
291
293
|
|
@@ -759,10 +761,9 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
759
761
|
end
|
760
762
|
|
761
763
|
def test_uncertain
|
762
|
-
if defined?
|
763
|
-
a =
|
764
|
-
|
765
|
-
assert_equal b.to_s, '1 +/- 1 mm'
|
764
|
+
if defined?(Uncertain)
|
765
|
+
a = '1 +/- 1 mm'.unit
|
766
|
+
assert_equal a.to_s, '1 +/- 1 mm'
|
766
767
|
else
|
767
768
|
fail "Can't test Uncertain Units unless 'Uncertain' gem is installed"
|
768
769
|
end
|
@@ -855,9 +856,11 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
855
856
|
end
|
856
857
|
|
857
858
|
def test_sqrt
|
858
|
-
|
859
|
-
|
860
|
-
|
859
|
+
a = '-9 mm^2'.unit
|
860
|
+
b = a**(0.5)
|
861
|
+
assert_in_delta Math.sqrt(a).to_unit.scalar.real, b.scalar.real, 0.00001
|
862
|
+
assert_in_delta Math.sqrt(a).to_unit.scalar.image, b.scalar.image, 0.00001
|
863
|
+
|
861
864
|
end
|
862
865
|
|
863
866
|
def test_hypot
|
@@ -867,9 +870,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
867
870
|
|
868
871
|
def test_complex
|
869
872
|
assert_equal '1+1i mm'.unit.scalar, Complex(1,1)
|
870
|
-
assert_equal '1+1i
|
871
|
-
assert_equal '1+1i mm'.unit.imag, '1i mm'.unit
|
872
|
-
assert_equal '1+1i'.unit, Complex(1,1)
|
873
|
+
assert_equal '1+1i'.unit.scalar, Complex(1,1)
|
873
874
|
assert_raises (RuntimeError) { '1+1i mm'.unit.to_c}
|
874
875
|
end
|
875
876
|
|
@@ -884,6 +885,10 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
884
885
|
assert_equal '1/4 in/s'.unit, '0.25 in/s'.unit
|
885
886
|
assert_equal '1/4'.unit, 0.25
|
886
887
|
end
|
887
|
-
|
888
|
-
|
888
|
+
|
889
|
+
def test_to_date
|
890
|
+
a = Time.now
|
891
|
+
assert_equal a.to_date, Date.today
|
892
|
+
end
|
889
893
|
end
|
894
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-units
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2007-01-
|
6
|
+
version: 1.0.2
|
7
|
+
date: 2007-01-24 00:00:00 -05:00
|
8
8
|
summary: A model that performs unit conversions and unit math
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -36,7 +36,16 @@ files:
|
|
36
36
|
- Rakefile
|
37
37
|
- lib/ruby-units.rb
|
38
38
|
- lib/ruby_units.rb
|
39
|
-
- lib/units.rb
|
39
|
+
- lib/ruby_units/units.rb
|
40
|
+
- lib/ruby_units/math.rb
|
41
|
+
- lib/ruby_units/date.rb
|
42
|
+
- lib/ruby_units/time.rb
|
43
|
+
- lib/ruby_units/string.rb
|
44
|
+
- lib/ruby_units/array.rb
|
45
|
+
- lib/ruby_units/numeric.rb
|
46
|
+
- lib/ruby_units/object.rb
|
47
|
+
- lib/ruby_units/complex.rb
|
48
|
+
- lib/ruby_units/ruby-units.rb
|
40
49
|
- test/test_ruby-units.rb
|
41
50
|
test_files:
|
42
51
|
- test/test_ruby-units.rb
|