third_base 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -168,12 +168,29 @@ To add a parser to a parser type:
168
168
  t = Time.now
169
169
  {:civil=>[t.year, t.mon, t.day]}
170
170
  end
171
+
171
172
  DateTime.add_parser(:mine, /\Anow\z/i) do |m|
172
173
  t = Time.now
173
174
  {:civil=>[t.year, t.mon, t.day], :parts=>[t.hour, t.min, t.sec, t.usec] \
174
175
  :offset=>t.utc_offset}
175
176
  end
176
177
 
178
+ If you add a DateTime parser that may guess at certain values instead of
179
+ parsing them out of the string, you should include a :not_parsed entry which
180
+ is an array of symbols indicating items that were not parsed directly out
181
+ of the string. This is only necessary if you are using the compatibility
182
+ mode and want better compatibility for Date._parse (which ruby's Time.parse
183
+ method uses internally):
184
+
185
+ DateTime.add_parser(:mine, /\A(\d\d)_(\d\d)_(\d{4})\z/i) do |m|
186
+ {:civil=>[m[3].to_i, m[2].to_i, m[1].to_i], :parts=>[0,0,0,0], :offset=>0, \
187
+ :not_parsed=>[:hour, :min, :sec, :sec_fraction, :offset, :zone]}
188
+ end
189
+
190
+ The entries in :not_parsed should match keys that can be returned by
191
+ Date._parse, so in addition to the ones listed above, you can also use
192
+ :year, :mon, and :mday.
193
+
177
194
  Adding a parser to a parser type adds it to the front of the array of parsers
178
195
  for that type, so it will be tried before other parsers for that type. It is
179
196
  an error to add a parser to a parser type that doesn't exist.
@@ -42,7 +42,7 @@ module ThirdBase
42
42
  # * :zone : time zone offset as string
43
43
  def _parse(str, comp=false)
44
44
  d = DateTime.parse(str)
45
- {:mon=>d.mon, :zone=>d.zone, :sec=>d.sec, :year=>d.year, :hour=>d.hour, :offset=>d.offset, :mday=>d.day, :min=>d.min, :sec_fraction=>d.usec/1000000.0}
45
+ {:mon=>d.mon, :zone=>d.zone, :sec=>d.sec, :year=>d.year, :hour=>d.hour, :offset=>d.offset, :mday=>d.day, :min=>d.min, :sec_fraction=>d.usec/1000000.0}.reject{|k, v| d.not_parsed.include?(k)}
46
46
  end
47
47
 
48
48
  # Converts an Astronomical Julian Date to an Astronomical Modified Julian Date (substracts an integer from ajd)
@@ -12,13 +12,13 @@ module ThirdBase
12
12
  DEFAULT_PARSERS[:time] = [[%r{\A#{TIME_RE_STRING}\z}io, proc do |m|
13
13
  unless m[0] == ''
14
14
  t = Time.now
15
- add_parsed_time_parts(m, {:civil=>[t.year, t.mon, t.day]}, 1)
15
+ add_parsed_time_parts(m, {:civil=>[t.year, t.mon, t.day], :not_parsed=>[:year, :mon, :mday]}, 1)
16
16
  end
17
17
  end]]
18
18
  DEFAULT_PARSERS[:iso] = [[%r{\A(-?\d{4})[-./ ](\d\d)[-./ ](\d\d)#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[1].to_i, m[2].to_i, m[3].to_i])}]]
19
19
  DEFAULT_PARSERS[:us] = [[%r{\A(\d\d?)[-./ ](\d\d?)[-./ ](\d\d(?:\d\d)?)#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[two_digit_year(m[3]), m[1].to_i, m[2].to_i])}],
20
- [%r{\A(\d\d?)/(\d?\d)#{TIME_RE_STRING}\z}o, proc{|m| add_parsed_time_parts(m, {:civil=>[Time.now.year, m[1].to_i, m[2].to_i]}, 3)}],
21
- [%r{\A#{MONTHNAME_RE_PATTERN}[-./ ](\d\d?)(?:st|nd|rd|th)?,?(?:[-./ ](-?(?:\d\d(?:\d\d)?)))?#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[3] ? two_digit_year(m[3]) : Time.now.year, MONTH_NUM_MAP[m[1].downcase], m[2].to_i])}],
20
+ [%r{\A(\d\d?)/(\d?\d)#{TIME_RE_STRING}\z}o, proc{|m| add_parsed_time_parts(m, {:civil=>[Time.now.year, m[1].to_i, m[2].to_i], :not_parsed=>:year}, 3)}],
21
+ [%r{\A#{MONTHNAME_RE_PATTERN}[-./ ](\d\d?)(?:st|nd|rd|th)?,?(?:[-./ ](-?(?:\d\d(?:\d\d)?)))?#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[3] ? two_digit_year(m[3]) : Time.now.year, MONTH_NUM_MAP[m[1].downcase], m[2].to_i], :not_parsed=>m[3] ? [] : [:year])}],
22
22
  [%r{\A(\d\d?)(?:st|nd|rd|th)?[-./ ]#{MONTHNAME_RE_PATTERN}[-./ ](-?\d{4})#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[3].to_i, MONTH_NUM_MAP[m[2].downcase], m[1].to_i])}],
23
23
  [%r{\A(-?\d{4})[-./ ]#{MONTHNAME_RE_PATTERN}[-./ ](\d\d?)(?:st|nd|rd|th)?#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[1].to_i, MONTH_NUM_MAP[m[2].downcase], m[3].to_i])}],
24
24
  [%r{\A#{MONTHNAME_RE_PATTERN}[-./ ](-?\d{4})#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, {:civil=>[m[2].to_i, MONTH_NUM_MAP[m[1].downcase], 1]}, 3)}]]
@@ -30,11 +30,11 @@ module ThirdBase
30
30
  case m.length
31
31
  when 2
32
32
  t = Time.now
33
- {:civil=>[t.year, t.mon, m.to_i]}
33
+ {:civil=>[t.year, t.mon, m.to_i], :not_parsed=>[:year, :mon, :mday]}
34
34
  when 3
35
- {:ordinal=>[Time.now.year, m.to_i]}
35
+ {:ordinal=>[Time.now.year, m.to_i], :not_parsed=>[:year, :mon, :mday]}
36
36
  when 4
37
- {:civil=>[Time.now.year, m[0..1].to_i, m[2..3].to_i]}
37
+ {:civil=>[Time.now.year, m[0..1].to_i, m[2..3].to_i], :not_parsed=>[:year]}
38
38
  when 5
39
39
  {:ordinal=>[two_digit_year(m[0..1]), m[2..4].to_i]}
40
40
  when 6
@@ -128,16 +128,25 @@ module ThirdBase
128
128
  # * i + 4 : meridian indicator
129
129
  # * i + 5 : time zone
130
130
  def self.add_parsed_time_parts(m, h, i=4)
131
+ not_parsed = h[:not_parsed] || []
131
132
  hour = m[i].to_i
132
133
  meridian = m[i+4]
133
134
  hour = hour_with_meridian(hour, /a/io.match(meridian) ? :am : :pm) if meridian
134
- offset = if m[i+5]
135
- x = m[i+5].gsub(':','')
136
- x == 'Z' ? 0 : x[0..2].to_i*3600 + x[3..4].to_i*60
135
+ offset = if of = m[i+5]
136
+ x = of.gsub(':','')
137
+ offset = x == 'Z' ? 0 : x[0..2].to_i*3600 + x[3..4].to_i*60
137
138
  else
139
+ not_parsed.concat([:zone, :offset])
138
140
  Time.now.utc_offset
139
141
  end
140
- h.merge!(:parts=>[hour, m[i+1].to_i, m[i+2].to_i, (m[i+3].to_f/0.000001).to_i], :offset=>offset)
142
+ min = m[i+1].to_i
143
+ sec = m[i+2].to_i
144
+ sec_fraction = m[i+3].to_f
145
+ not_parsed << :hour unless m[i]
146
+ not_parsed << :min unless m[i+1]
147
+ not_parsed << :sec unless m[i+2]
148
+ not_parsed << :sec_fraction unless m[i+3]
149
+ h.merge!(:parts=>[hour, min, sec, (sec_fraction/0.000001).to_i], :offset=>offset, :not_parsed=>not_parsed)
141
150
  h
142
151
  end
143
152
 
@@ -212,6 +221,9 @@ module ThirdBase
212
221
  attr_reader :offset
213
222
  alias utc_offset offset
214
223
 
224
+ # Which parts of this datetime were guessed instead of being parsed from the input.
225
+ attr_reader :not_parsed
226
+
215
227
  # Called by DateTime.new!, should be a hash with the following possible keys:
216
228
  #
217
229
  # * :civil, :commericial, :jd, :ordinal : See ThirdBase::Date#initialize
@@ -221,6 +233,7 @@ module ThirdBase
221
233
  #
222
234
  # Raises an ArgumentError if an invalid date is used. DateTime objects are immutable once created.
223
235
  def initialize(opts)
236
+ @not_parsed = opts[:not_parsed] || []
224
237
  @offset = opts[:offset]
225
238
  raise(ArgumentError, 'invalid datetime') unless @offset.is_a?(Integer) and @offset <= 43200 and @offset >= -43200
226
239
  if opts[:parts]
@@ -22,8 +22,13 @@ describe ThirdBase::CompatClassMethods do
22
22
  end
23
23
 
24
24
  it "#_parse should parse the date string and return a hash" do
25
- Date._parse('2008-10-20 11:12:13-08:00').should == {:mon=>10, :zone=>'-08:00', :sec=>13, :sec_fraction=>0.0, :year=>2008, :hour=>11, :offset=>-28800, :mday=>20, :min=>12}
26
- Date._parse('2008-10-20 11:12:13-08:00', true).should == {:mon=>10, :zone=>'-08:00', :sec=>13, :sec_fraction=>0.0, :year=>2008, :hour=>11, :offset=>-28800, :mday=>20, :min=>12}
25
+ Date._parse('2008-10-20 11:12:13.0-08:00').should == {:mon=>10, :zone=>'-08:00', :sec=>13, :sec_fraction=>0.0, :year=>2008, :hour=>11, :offset=>-28800, :mday=>20, :min=>12}
26
+ Date._parse('2008-10-20 11:12:13.0-08:00', true).should == {:mon=>10, :zone=>'-08:00', :sec=>13, :sec_fraction=>0.0, :year=>2008, :hour=>11, :offset=>-28800, :mday=>20, :min=>12}
27
+ end
28
+
29
+ it "#_parse should not contain fields in the hash that were guessed" do
30
+ Date._parse('2008-10-20').should == {:year=>2008, :mday=>20, :mon=>10}
31
+ Date._parse('11:12:13').should == {:sec=>13, :hour=>11, :min=>12}
27
32
  end
28
33
 
29
34
  it "#ajd_to_amjd should convert a astronomical julian date to a astronomical modified julian date" do
@@ -33,4 +33,4 @@ describe "DateTime#+" do
33
33
  lambda { DateTime.civil(2007,2,27) + Object.new }.should raise_error(TypeError)
34
34
  end
35
35
 
36
- end
36
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: third_base
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-09 00:00:00 -08:00
12
+ date: 2009-06-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15