third_base 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/third_base/compat.rb +4 -393
- data/lib/third_base/date.rb +36 -33
- data/lib/third_base/datetime.rb +31 -26
- data/lib/third_base/make_compat.rb +411 -0
- metadata +32 -17
data/lib/third_base/compat.rb
CHANGED
@@ -1,402 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require 'third_base'
|
3
2
|
|
4
3
|
Object.send(:remove_const, :Date) if Object.const_get(:Date) rescue nil
|
5
4
|
Object.send(:remove_const, :DateTime) if Object.const_get(:DateTime) rescue nil
|
6
5
|
|
7
|
-
|
8
|
-
MJD_JD = 2400001
|
9
|
-
LD_JD = 2299160
|
10
|
-
ITALY = 2299161
|
11
|
-
ENGLAND = 2361222
|
12
|
-
JULIAN = -100000000000000000000000000000000000
|
13
|
-
GREGORIAN = 100000000000000000000000000000000000
|
14
|
-
|
15
|
-
# Compatibility class methods for Date and DateTime, necessary because ruby doesn't
|
16
|
-
# support multiple inheritance.
|
17
|
-
module CompatClassMethods
|
18
|
-
[ %w(os? julian?),
|
19
|
-
%w(ns? gregorian?),
|
20
|
-
%w(exist1? valid_jd?),
|
21
|
-
%w(exist2? valid_ordinal?),
|
22
|
-
%w(exist3? valid_date?),
|
23
|
-
%w(exist? valid_date?),
|
24
|
-
%w(existw? valid_commercial?),
|
25
|
-
%w(new0 new!),
|
26
|
-
%w(new1 jd),
|
27
|
-
%w(new2 ordinal),
|
28
|
-
%w(new3 new),
|
29
|
-
%w(neww commercial)
|
30
|
-
].each{|old, new| module_eval("def #{old}(*args, &block); #{new}(*args, &block); end")}
|
31
|
-
|
32
|
-
# Return the parts of the parsed date as a hash witht he following keys:
|
33
|
-
#
|
34
|
-
# * :hour : hour
|
35
|
-
# * :mday : day of month
|
36
|
-
# * :min : minute
|
37
|
-
# * :mon : month
|
38
|
-
# * :offset : time zone offset from UTC in seconds
|
39
|
-
# * :sec : second
|
40
|
-
# * :sec_fraction : fraction of a second
|
41
|
-
# * :year : year
|
42
|
-
# * :zone : time zone offset as string
|
43
|
-
def _parse(str, comp=false)
|
44
|
-
d = DateTime.parse(str)
|
45
|
-
{:mon=>d.mon, :zone=>d.zone, :sec=>d.sec, :year=>d.year, :hour=>d.hour, :offset=>d.utc_offset, :mday=>d.day, :min=>d.min, :sec_fraction=>d.usec/1000000.0}.reject{|k, v| d.not_parsed.include?(k)}
|
46
|
-
end
|
47
|
-
|
48
|
-
# Converts an Astronomical Julian Date to an Astronomical Modified Julian Date (substracts an integer from ajd)
|
49
|
-
def ajd_to_amjd(ajd)
|
50
|
-
ajd - MJD_JD
|
51
|
-
end
|
52
|
-
|
53
|
-
# Converts an Astronomical Julian Date to a Julian Date (returns ajd, ignores of)
|
54
|
-
def ajd_to_jd(ajd, of=0)
|
55
|
-
ajd
|
56
|
-
end
|
57
|
-
|
58
|
-
# Converts an Astronomical Modified Julian Date to an Astronomical Julian Date (adds an integer to amjd)
|
59
|
-
def amjd_to_ajd(amjd)
|
60
|
-
amjd + MJD_JD
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns the julian date for the given civil date arguments, ignores sg.
|
64
|
-
def civil_to_jd(year, mon, day, sg=nil)
|
65
|
-
civil(year, mon, day).jd
|
66
|
-
end
|
67
|
-
|
68
|
-
# Returns the julian date for the given commercial date arguments, ignores sg.
|
69
|
-
def commercial_to_jd(cwyear, cweek, cwday, sg=nil)
|
70
|
-
commercial(cwyear, cweek, cwday).jd
|
71
|
-
end
|
72
|
-
|
73
|
-
# Returns the fraction of the date as an array of hours, minutes, seconds, and fraction on a second.
|
74
|
-
def day_fraction_to_time(fr)
|
75
|
-
hours, fr = (fr * 24).divmod(1)
|
76
|
-
minutes, fr = (fr * 60).divmod(1)
|
77
|
-
seconds, sec_fract = (fr * 60).divmod(1)
|
78
|
-
[hours, minutes, seconds, sec_fract]
|
79
|
-
end
|
80
|
-
|
81
|
-
# True if jd is greater than sg, false otherwise.
|
82
|
-
def gregorian?(jd, sg)
|
83
|
-
jd > sg
|
84
|
-
end
|
85
|
-
|
86
|
-
# All years divisible by 4 are leap years in the Gregorian calendar,
|
87
|
-
# except for years divisible by 100 and not by 400.
|
88
|
-
def leap?(y)
|
89
|
-
y % 4 == 0 && y % 100 != 0 || y % 400 == 0
|
90
|
-
end
|
91
|
-
alias gregorian_leap? leap?
|
92
|
-
|
93
|
-
# Converts a Julian Date to an Astronomical Julian Date (returns j, ignores fr and of)
|
94
|
-
def jd_to_ajd(j, fr, of=0)
|
95
|
-
j
|
96
|
-
end
|
97
|
-
|
98
|
-
# Returns [year, month, day] for the given julian date, ignores sg.
|
99
|
-
def jd_to_civil(j, sg=nil)
|
100
|
-
jd(j).send(:civil)
|
101
|
-
end
|
102
|
-
|
103
|
-
# Returns [cwyear, cweek, cwday] for the given julian date, ignores sg.
|
104
|
-
def jd_to_commercial(j, sg=nil)
|
105
|
-
jd(j).send(:commercial)
|
106
|
-
end
|
107
|
-
|
108
|
-
# Converts a julian date to the number of days since the adoption of
|
109
|
-
# the gregorian calendar in Italy (subtracts an integer from j).
|
110
|
-
def jd_to_ld(j)
|
111
|
-
j - LD_JD
|
112
|
-
end
|
113
|
-
|
114
|
-
# Convert a Julian Date to a Modified Julian Date (subtracts an integer from j).
|
115
|
-
def jd_to_mjd(j)
|
116
|
-
j - MJD_JD
|
117
|
-
end
|
118
|
-
|
119
|
-
# Returns [year, yday] for the given julian date, ignores sg.
|
120
|
-
def jd_to_ordinal(j, sg=nil)
|
121
|
-
jd(j).send(:ordinal)
|
122
|
-
end
|
123
|
-
|
124
|
-
# Returns the day of week for the given julian date.
|
125
|
-
def jd_to_wday(j)
|
126
|
-
jd(j).wday
|
127
|
-
end
|
128
|
-
|
129
|
-
# Returns true if jd is less than sg, false otherwise.
|
130
|
-
def julian?(jd, sg)
|
131
|
-
jd < sg
|
132
|
-
end
|
133
|
-
|
134
|
-
# All years divisible by 4 are leap years in the Julian calendar.
|
135
|
-
def julian_leap?(y)
|
136
|
-
y % 4 == 0
|
137
|
-
end
|
138
|
-
|
139
|
-
# Converts a number of days since the adoption of the gregorian calendar in Italy
|
140
|
-
# to a julian date (adds an integer to ld).
|
141
|
-
def ld_to_jd(ld)
|
142
|
-
ld + LD_JD
|
143
|
-
end
|
144
|
-
|
145
|
-
# Converts a Modified Julian Date to a Julian Date (adds an integer to mjd).
|
146
|
-
def mjd_to_jd(mjd)
|
147
|
-
mjd + MJD_JD
|
148
|
-
end
|
149
|
-
|
150
|
-
# Converts the given year and day of year to a julian date, ignores sg.
|
151
|
-
def ordinal_to_jd(year, yday, sg=nil)
|
152
|
-
ordinal(year, yday).jd
|
153
|
-
end
|
154
|
-
|
155
|
-
# Converts the given hour, minute, and second to a fraction of a day as a Float.
|
156
|
-
def time_to_day_fraction(h, min, s)
|
157
|
-
(h*3600 + min*60 + s)/86400.0
|
158
|
-
end
|
159
|
-
|
160
|
-
# Return the julian date of the given year, month, and day if valid, or nil if not, ignores sg.
|
161
|
-
def valid_civil?(year, mon, day, sg=nil)
|
162
|
-
civil(year, mon, day).jd rescue nil
|
163
|
-
end
|
164
|
-
alias valid_date? valid_civil?
|
165
|
-
|
166
|
-
# Return the julian date of the given commercial week year, commercial week, and commercial
|
167
|
-
# week day if valid, or nil if not, ignores sg.
|
168
|
-
def valid_commercial?(cwyear, cweek, cwday, sg=nil)
|
169
|
-
commercial(cwyear, cweek, cwday).jd rescue nil
|
170
|
-
end
|
171
|
-
|
172
|
-
# Returns the julian date if valid (always returns jd, ignores sg).
|
173
|
-
def valid_jd?(jd, sg=nil)
|
174
|
-
jd
|
175
|
-
end
|
176
|
-
|
177
|
-
# Return the julian date of the given year and day of year if valid, or nil if not, ignores sg.
|
178
|
-
def valid_ordinal?(year, yday, sg=nil)
|
179
|
-
ordinal(year, yday).jd rescue nil
|
180
|
-
end
|
181
|
-
|
182
|
-
# Returns the fraction of the day if the time is valid, or nil if the time is not valid.
|
183
|
-
def valid_time?(h, min, s)
|
184
|
-
h += 24 if h < 0
|
185
|
-
min += 60 if min < 0
|
186
|
-
s += 60 if s < 0
|
187
|
-
return unless ((0..23) === h &&
|
188
|
-
(0..59) === min &&
|
189
|
-
(0..59) === s) ||
|
190
|
-
(24 == h &&
|
191
|
-
0 == min &&
|
192
|
-
0 == s)
|
193
|
-
time_to_day_fraction(h, min, s)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Converts a time zone string to a offset from UTC in seconds.
|
197
|
-
def zone_to_diff(zone)
|
198
|
-
if m = /\A([+-](?:\d{4}|\d\d:\d\d))\z/.match(zone)
|
199
|
-
x = m[1].gsub(':','')
|
200
|
-
x[0..2].to_i*3600 + x[3..4].to_i*60
|
201
|
-
else
|
202
|
-
0
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
# Compatibility instance methods for Date and DateTime, necessary because ruby doesn't
|
208
|
-
# support multiple inheritance.
|
209
|
-
module CompatInstanceMethods
|
210
|
-
# Returns the Astronomical Julian Date for this date (alias for jd)
|
211
|
-
def ajd
|
212
|
-
jd
|
213
|
-
end
|
214
|
-
|
215
|
-
# Returns the Astronomical Modified Julian Date for this date (jd plus an integer)
|
216
|
-
def amjd
|
217
|
-
jd - MJD_JD
|
218
|
-
end
|
219
|
-
alias mjd amjd
|
220
|
-
|
221
|
-
# Returns self.
|
222
|
-
def gregorian
|
223
|
-
self
|
224
|
-
end
|
225
|
-
alias england gregorian
|
226
|
-
alias julian gregorian
|
227
|
-
alias italy gregorian
|
228
|
-
|
229
|
-
# True, since the gregorian calendar is always used.
|
230
|
-
def gregorian?
|
231
|
-
true
|
232
|
-
end
|
233
|
-
alias ns? gregorian?
|
234
|
-
|
235
|
-
# False, since the gregorian calendar is never used.
|
236
|
-
def julian?
|
237
|
-
false
|
238
|
-
end
|
239
|
-
alias os? julian?
|
240
|
-
|
241
|
-
# Returns the days since the date of the adoption of the gregorian calendar in Italy
|
242
|
-
# (substracts an integer from jd).
|
243
|
-
def ld
|
244
|
-
jd - LD_JD
|
245
|
-
end
|
246
|
-
|
247
|
-
# Alias for day.
|
248
|
-
def mday
|
249
|
-
day
|
250
|
-
end
|
251
|
-
|
252
|
-
# Returns self, ignores sg.
|
253
|
-
def new_start(sg=nil)
|
254
|
-
self
|
255
|
-
end
|
256
|
-
alias newsg new_start
|
257
|
-
|
258
|
-
# Returns 0, since the gregorian calendar is always used.
|
259
|
-
def start
|
260
|
-
0
|
261
|
-
end
|
262
|
-
alias sg start
|
263
|
-
end
|
264
|
-
|
265
|
-
# ThirdBase's top level Date compatibility class, striving to be as close as possible
|
266
|
-
# to the standard Date class's API.
|
267
|
-
class ::Date < Date
|
268
|
-
extend CompatClassMethods
|
269
|
-
include CompatInstanceMethods
|
270
|
-
|
271
|
-
# Parse the date using strptime with the given format.
|
272
|
-
def self._strptime(str, fmt='%F')
|
273
|
-
strptime(str, fmt)
|
274
|
-
end
|
275
|
-
|
276
|
-
# Creates a new Date with the given year, month, and day of month, ignores sg.
|
277
|
-
def self.civil(year=-4712, mon=1, day=1, sg=nil)
|
278
|
-
super(year, mon, day)
|
279
|
-
end
|
280
|
-
|
281
|
-
# Creates a new Date with the given commercial week year, commercial week, and commercial week day, ignores sg.
|
282
|
-
def self.commercial(cwyear=1582, cweek=41, cwday=5, sg=nil)
|
283
|
-
super(cwyear, cweek, cwday)
|
284
|
-
end
|
285
|
-
|
286
|
-
# Creates a new Date with the given julian date, ignores sg.
|
287
|
-
def self.jd(j=0, sg=nil)
|
288
|
-
super(j)
|
289
|
-
end
|
290
|
-
|
291
|
-
# Creates a new Date with the given year and day of year, ignores sg.
|
292
|
-
def self.ordinal(year=-4712, yday=1, sg=nil)
|
293
|
-
super(year, yday)
|
294
|
-
end
|
295
|
-
|
296
|
-
# Parse given string using ThirdBase::Date's date parser, ignores comp and sg.
|
297
|
-
def self.parse(str="-4712-01-01", comp=false, sg=nil)
|
298
|
-
super(str)
|
299
|
-
end
|
300
|
-
|
301
|
-
# Parse given string using given format, ignores sg.
|
302
|
-
def self.strptime(str="-4712-01-01", fmt='%F', sg=nil)
|
303
|
-
super(str, fmt)
|
304
|
-
end
|
305
|
-
|
306
|
-
# Creates a new Date with today's date, ignores sg.
|
307
|
-
def self.today(sg=nil)
|
308
|
-
super()
|
309
|
-
end
|
310
|
-
|
311
|
-
# Returns a formatted string representing the date.
|
312
|
-
def asctime
|
313
|
-
strftime('%a %b %e 00:00:00 %Y')
|
314
|
-
end
|
315
|
-
alias ctime asctime
|
316
|
-
|
317
|
-
# Returns 0.0, since Date don't have fractional days.
|
318
|
-
def day_fraction
|
319
|
-
0.0
|
320
|
-
end
|
321
|
-
end
|
6
|
+
require 'third_base/make_compat'
|
322
7
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
extend CompatClassMethods
|
327
|
-
include CompatInstanceMethods
|
328
|
-
|
329
|
-
# Parse the datetime using strptime with the given format.
|
330
|
-
def self._strptime(str, fmt='%FT%T%z')
|
331
|
-
strptime(str, fmt)
|
332
|
-
end
|
333
|
-
|
334
|
-
# Creates a new DateTime with the given year, month, day of month, hour, minute, second, and offset, ignores sg.
|
335
|
-
def self.civil(year=-4712, mon=1, day=1, hour=0, min=0, sec=0, offset=0, sg=nil)
|
336
|
-
super(year, mon, day, hour, min, sec, 0, (offset*86400).to_i)
|
337
|
-
end
|
338
|
-
|
339
|
-
# Creates a new DateTime with the given commercial week year, commercial week, commercial week day,
|
340
|
-
# hour, minute, second, and offset, ignores sg.
|
341
|
-
def self.commercial(cwyear=1582, cweek=41, cwday=5, hour=0, min=0, sec=0, offset=0, sg=nil)
|
342
|
-
super(cwyear, cweek, cwday, hour, min, sec, 0, (offset*86400).to_i)
|
343
|
-
end
|
344
|
-
|
345
|
-
# Creates a new DateTime with the given julian date, hour, minute, second, and offset, ignores sg.
|
346
|
-
def self.jd(j=0, hour=0, min=0, sec=0, offset=0, sg=nil)
|
347
|
-
super(j, hour, min, sec, 0, (offset*86400).to_i)
|
348
|
-
end
|
349
|
-
|
350
|
-
# Creates a new DateTime with the given year, day of year, hour, minute, second, and offset, ignores sg.
|
351
|
-
def self.ordinal(year=-4712, yday=1, hour=0, min=0, sec=0, offset=0, sg=nil)
|
352
|
-
super(year, yday, hour, min, sec, 0, (offset*86400).to_i)
|
353
|
-
end
|
354
|
-
|
355
|
-
# Parse given string using ThirdBase::DateTime's date parser, ignores comp and sg.
|
356
|
-
def self.parse(str="-4712-01-01T00:00:00+00:00", comp=false, sg=nil)
|
357
|
-
super(str)
|
358
|
-
end
|
359
|
-
|
360
|
-
# Parse given string using given format, ignores sg.
|
361
|
-
def self.strptime(str="-4712-01-01T00:00:00+00:00", fmt='%FT%T%z', sg=nil)
|
362
|
-
super(str, fmt)
|
363
|
-
end
|
364
|
-
|
365
|
-
# Creates a new DateTime with the current date and time, ignores sg.
|
366
|
-
def self.now(sg=nil)
|
367
|
-
super()
|
368
|
-
end
|
369
|
-
|
370
|
-
# Returns a formatted string representing the date.
|
371
|
-
def asctime
|
372
|
-
strftime('%c')
|
373
|
-
end
|
374
|
-
alias ctime asctime
|
375
|
-
|
376
|
-
alias day_fraction fract
|
377
|
-
|
378
|
-
# Returns a new DateTime with the same date and time as this datetime, but with a new offset.
|
379
|
-
def new_offset(offset=0)
|
380
|
-
self.class.new!(:civil=>civil, :parts=>time_parts, :offset=>(offset*86400).to_i)
|
381
|
-
end
|
382
|
-
alias newof new_offset
|
383
|
-
|
384
|
-
# Return the offset as a Float representing the fraction of the day different from UTC.
|
385
|
-
def offset
|
386
|
-
@offset/86400.0
|
387
|
-
end
|
388
|
-
alias of offset
|
389
|
-
|
390
|
-
# Return the offset as a number of seconds from UTC.
|
391
|
-
def offset_sec
|
392
|
-
@offset
|
393
|
-
end
|
394
|
-
|
395
|
-
# The fraction of a second represented as a fraction of the entire day.
|
396
|
-
def sec_fraction
|
397
|
-
usec/86400000000.0
|
398
|
-
end
|
399
|
-
end
|
8
|
+
class Date < ThirdBase::Date
|
9
|
+
end
|
10
|
+
class DateTime < ThirdBase::DateTime
|
400
11
|
end
|
401
12
|
|
402
13
|
$:.unshift(File.join(File.dirname(__FILE__), 'compat'))
|
data/lib/third_base/date.rb
CHANGED
@@ -86,12 +86,11 @@ module ThirdBase
|
|
86
86
|
|
87
87
|
UNIXEPOCH = 2440588
|
88
88
|
|
89
|
-
# Public Class Methods
|
90
|
-
|
91
89
|
class << self
|
92
90
|
alias new! new
|
93
91
|
end
|
94
92
|
|
93
|
+
module ClassMethods
|
95
94
|
# Add a parser to the parser type. Arguments:
|
96
95
|
# * type - The parser type to which to add the parser, should be a Symbol.
|
97
96
|
# * pattern - Can be either a Regexp or String:
|
@@ -104,7 +103,7 @@ module ThirdBase
|
|
104
103
|
# The block, if provided, should take a single MatchData argument. It should return
|
105
104
|
# nil if it cannot successfully parse the string, an instance of this class, or a hash of
|
106
105
|
# values to be passed to new!.
|
107
|
-
def
|
106
|
+
def add_parser(type, pattern, &block)
|
108
107
|
if pattern.is_a?(String)
|
109
108
|
pattern, blk = strptime_pattern_and_block(pattern)
|
110
109
|
block ||= blk
|
@@ -117,33 +116,33 @@ module ThirdBase
|
|
117
116
|
# Add a parser type to the list of parser types.
|
118
117
|
# Should be used if you want to add your own parser
|
119
118
|
# types.
|
120
|
-
def
|
119
|
+
def add_parser_type(type)
|
121
120
|
parser_hash[type] ||= []
|
122
121
|
end
|
123
122
|
|
124
123
|
# Returns a new Date with the given year, month, and day.
|
125
|
-
def
|
124
|
+
def civil(year, mon, day)
|
126
125
|
new!(:civil=>[year, mon, day])
|
127
126
|
end
|
128
127
|
|
129
128
|
# Returns a new Date with the given commercial week year,
|
130
129
|
# commercial week, and commercial week day.
|
131
|
-
def
|
130
|
+
def commercial(cwyear, cweek, cwday=5)
|
132
131
|
new!(:commercial=>[cwyear, cweek, cwday])
|
133
132
|
end
|
134
133
|
|
135
134
|
# Returns a new Date with the given julian date.
|
136
|
-
def
|
135
|
+
def jd(j)
|
137
136
|
new!(:jd=>j)
|
138
137
|
end
|
139
138
|
|
140
139
|
# Calls civil with the given arguments.
|
141
|
-
def
|
140
|
+
def new(*args)
|
142
141
|
civil(*args)
|
143
142
|
end
|
144
143
|
|
145
144
|
# Returns a new Date with the given year and day of year.
|
146
|
-
def
|
145
|
+
def ordinal(year, yday)
|
147
146
|
new!(:ordinal=>[year, yday])
|
148
147
|
end
|
149
148
|
|
@@ -153,7 +152,7 @@ module ThirdBase
|
|
153
152
|
# * :parser_types : an array of parser types to use,
|
154
153
|
# overriding the default or the ones specified by
|
155
154
|
# use_parsers.
|
156
|
-
def
|
155
|
+
def parse(str, opts={})
|
157
156
|
s = str.strip
|
158
157
|
parsers(opts[:parser_types]) do |pattern, block|
|
159
158
|
if m = pattern.match(s)
|
@@ -166,7 +165,7 @@ module ThirdBase
|
|
166
165
|
end
|
167
166
|
|
168
167
|
# Reset the parsers, parser types, and order of parsers used to the default.
|
169
|
-
def
|
168
|
+
def reset_parsers!
|
170
169
|
parser_hash.clear
|
171
170
|
default_parser_hash.each do |type, parsers|
|
172
171
|
add_parser_type(type)
|
@@ -179,7 +178,7 @@ module ThirdBase
|
|
179
178
|
|
180
179
|
# Parse the string using the provided format (or the default format).
|
181
180
|
# Raises an ArgumentError if the format does not match the string.
|
182
|
-
def
|
181
|
+
def strptime(str, fmt=strptime_default)
|
183
182
|
pattern, block = strptime_pattern_and_block(fmt)
|
184
183
|
s = str.strip
|
185
184
|
if m = pattern.match(s)
|
@@ -190,19 +189,19 @@ module ThirdBase
|
|
190
189
|
end
|
191
190
|
|
192
191
|
# Returns a date with the current year, month, and date.
|
193
|
-
def
|
192
|
+
def today
|
194
193
|
t = Time.now
|
195
194
|
civil(t.year, t.mon, t.day)
|
196
195
|
end
|
197
196
|
|
198
197
|
# Set the order of parser types to use to the given parser types.
|
199
|
-
def
|
198
|
+
def use_parsers(*parsers)
|
200
199
|
parser_list.replace(parsers)
|
201
200
|
end
|
202
201
|
|
203
|
-
|
202
|
+
private
|
204
203
|
|
205
|
-
def
|
204
|
+
def _expand_strptime_format(v)
|
206
205
|
case v
|
207
206
|
when '%D', '%x' then '%m/%d/%y'
|
208
207
|
when '%F' then '%Y-%m-%d'
|
@@ -211,7 +210,7 @@ module ThirdBase
|
|
211
210
|
end
|
212
211
|
end
|
213
212
|
|
214
|
-
def
|
213
|
+
def _strptime_part(v)
|
215
214
|
case v
|
216
215
|
when 'A' then [FULL_DAYNAME_RE_PATTERN, STRPTIME_PROC_A]
|
217
216
|
when 'a' then [ABBR_DAYNAME_RE_PATTERN, STRPTIME_PROC_A]
|
@@ -235,19 +234,19 @@ module ThirdBase
|
|
235
234
|
end
|
236
235
|
end
|
237
236
|
|
238
|
-
def
|
237
|
+
def default_parser_hash
|
239
238
|
DEFAULT_PARSERS
|
240
239
|
end
|
241
240
|
|
242
|
-
def
|
241
|
+
def default_parser_list
|
243
242
|
DEFAULT_PARSER_LIST
|
244
243
|
end
|
245
244
|
|
246
|
-
def
|
245
|
+
def expand_strptime_format(fmt)
|
247
246
|
fmt.gsub(STRFTIME_RE){|x| _expand_strptime_format(x)}
|
248
247
|
end
|
249
248
|
|
250
|
-
def
|
249
|
+
def new_from_parts(date_hash)
|
251
250
|
d = today
|
252
251
|
if date_hash[:year] || date_hash[:yday] || date_hash[:month] || date_hash[:day]
|
253
252
|
if date_hash[:yday]
|
@@ -262,15 +261,15 @@ module ThirdBase
|
|
262
261
|
end
|
263
262
|
end
|
264
263
|
|
265
|
-
def
|
264
|
+
def parser_hash
|
266
265
|
PARSERS
|
267
266
|
end
|
268
267
|
|
269
|
-
def
|
268
|
+
def parser_list
|
270
269
|
PARSER_LIST
|
271
270
|
end
|
272
271
|
|
273
|
-
def
|
272
|
+
def parsers(parser_families=nil)
|
274
273
|
(parser_families||parser_list).each do |parser_family|
|
275
274
|
parsers_for_family(parser_family) do |pattern, block|
|
276
275
|
yield(pattern, block)
|
@@ -278,17 +277,17 @@ module ThirdBase
|
|
278
277
|
end
|
279
278
|
end
|
280
279
|
|
281
|
-
def
|
280
|
+
def parsers_for_family(parser_family)
|
282
281
|
parser_hash[parser_family].each do |pattern, block|
|
283
282
|
yield(pattern, block)
|
284
283
|
end
|
285
284
|
end
|
286
285
|
|
287
|
-
def
|
286
|
+
def strptime_default
|
288
287
|
'%Y-%m-%d'
|
289
288
|
end
|
290
289
|
|
291
|
-
def
|
290
|
+
def strptime_pattern_and_block(fmt)
|
292
291
|
blocks = []
|
293
292
|
pattern = Regexp.escape(expand_strptime_format(fmt)).gsub(STRFTIME_RE) do |x|
|
294
293
|
pat, *blks = _strptime_part(x[1..1])
|
@@ -305,7 +304,7 @@ module ThirdBase
|
|
305
304
|
[/\A#{pattern}\z/i, block]
|
306
305
|
end
|
307
306
|
|
308
|
-
def
|
307
|
+
def two_digit_year(y)
|
309
308
|
y = if y.length == 2
|
310
309
|
y = y.to_i
|
311
310
|
(y < 69 ? 2000 : 1900) + y
|
@@ -313,13 +312,12 @@ module ThirdBase
|
|
313
312
|
y.to_i
|
314
313
|
end
|
315
314
|
end
|
316
|
-
|
317
|
-
|
315
|
+
end
|
316
|
+
extend ClassMethods
|
318
317
|
|
319
318
|
reset_parsers!
|
320
319
|
|
321
|
-
|
322
|
-
|
320
|
+
module InstanceMethods
|
323
321
|
# Called by Date.new!, Takes a hash with one of the following keys:
|
324
322
|
#
|
325
323
|
# * :civil : should be an array with 3 elements, a year, month, and day
|
@@ -407,7 +405,10 @@ module ThirdBase
|
|
407
405
|
return false unless Date === date
|
408
406
|
year == date.year and mon == date.mon and day == date.day
|
409
407
|
end
|
410
|
-
|
408
|
+
|
409
|
+
def eql?(date)
|
410
|
+
self == date
|
411
|
+
end
|
411
412
|
|
412
413
|
# If d is a date, only true if it is equal to this date. If d is Numeric, only true if it equals this date's julian date.
|
413
414
|
def ===(d)
|
@@ -693,4 +694,6 @@ module ThirdBase
|
|
693
694
|
CUMMULATIVE_MONTH_DAYS[mon] + day + ((month > 2 and leap?) ? 1 : 0)
|
694
695
|
end
|
695
696
|
end
|
697
|
+
include InstanceMethods
|
698
|
+
end
|
696
699
|
end
|
data/lib/third_base/datetime.rb
CHANGED
@@ -4,6 +4,8 @@ module ThirdBase
|
|
4
4
|
# ThirdBase's DateTime class, which builds on the Date class and adds a time component of
|
5
5
|
# hours, minutes, seconds, microseconds, and an offset from UTC.
|
6
6
|
class DateTime < Date
|
7
|
+
PARSERS = {}
|
8
|
+
UNIXEPOCH = ThirdBase::Date::UNIXEPOCH
|
7
9
|
TIME_ZONE_SECOND_OFFSETS = {
|
8
10
|
'UTC'=>0, 'Z'=>0, 'UT'=>0, 'GMT'=>0,
|
9
11
|
'EST'=>-18000, 'EDT'=>-14400, 'CST'=>-21600, 'CDT'=>-18000, 'MST'=>-25200, 'MDT'=>-21600, 'PST'=>-28800, 'PDT'=>-25200,
|
@@ -27,7 +29,7 @@ module ThirdBase
|
|
27
29
|
[%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])}],
|
28
30
|
[%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])}],
|
29
31
|
[%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
|
-
[%r{\A#{ABBR_DAYNAME_RE_PATTERN} #{ABBR_MONTHNAME_RE_PATTERN} (\d\d?) #{TIME_RE_STRING} (-?\d{4})\z}io, proc{|m| add_parsed_time_parts(m, {:civil=>[m[10].to_i, MONTH_NUM_MAP[m[2].downcase], m[3].to_i]})}]]
|
32
|
+
[%r{\A#{ABBR_DAYNAME_RE_PATTERN} #{ABBR_MONTHNAME_RE_PATTERN} +(\d\d?) #{TIME_RE_STRING} (-?\d{4})\z}io, proc{|m| add_parsed_time_parts(m, {:civil=>[m[10].to_i, MONTH_NUM_MAP[m[2].downcase], m[3].to_i]})}]]
|
31
33
|
DEFAULT_PARSERS[:eu] = [[%r{\A(\d\d?)[-./ ](\d\d?)[-./ ](\d{4})#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[m[3].to_i, m[2].to_i, m[1].to_i])}],
|
32
34
|
[%r{\A(\d\d?)[-./ ](\d?\d)[-./ ](\d?\d)#{TIME_RE_STRING}\z}io, proc{|m| add_parsed_time_parts(m, :civil=>[two_digit_year(m[1]), m[2].to_i, m[3].to_i])}]]
|
33
35
|
DEFAULT_PARSERS[:num] = [[%r{\A(\d{2,8})#{TIME_RE_STRING}\z}io, proc do |n|
|
@@ -66,43 +68,42 @@ module ThirdBase
|
|
66
68
|
end
|
67
69
|
STRPTIME_PROC_z = proc{|h,x| h[:offset] = convert_parsed_offset(x)}
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
+
module ClassMethods
|
71
72
|
# Create a new DateTime with the given year, month, day of month, hour, minute, second, microsecond and offset.
|
72
|
-
def
|
73
|
+
def civil(year, mon, day, hour=0, min=0, sec=0, usec=0, offset=0)
|
73
74
|
new!(:civil=>[year, mon, day], :parts=>[hour, min, sec, usec], :offset=>offset)
|
74
75
|
end
|
75
76
|
|
76
77
|
# Create a new DateTime with the given commercial week year, commercial week, commercial week day, hour, minute
|
77
78
|
# second, microsecond, and offset.
|
78
|
-
def
|
79
|
+
def commercial(cwyear, cweek, cwday=5, hour=0, min=0, sec=0, usec=0, offset=0)
|
79
80
|
new!(:commercial=>[cwyear, cweek, cwday], :parts=>[hour, min, sec, usec], :offset=>offset)
|
80
81
|
end
|
81
82
|
|
82
83
|
# Create a new DateTime with the given julian date, hour, minute, second, microsecond, and offset.
|
83
|
-
def
|
84
|
+
def jd(jd, hour=0, min=0, sec=0, usec=0, offset=0)
|
84
85
|
new!(:jd=>jd, :parts=>[hour, min, sec, usec], :offset=>offset)
|
85
86
|
end
|
86
87
|
|
87
88
|
# Create a new DateTime with the given julian day, fraction of the day (0.5 is Noon), and offset.
|
88
|
-
def
|
89
|
+
def jd_fract(jd, fract=0.0, offset=0)
|
89
90
|
new!(:jd=>jd, :fract=>fract, :offset=>offset)
|
90
91
|
end
|
91
92
|
|
92
93
|
# Create a new DateTime with the current date and time.
|
93
|
-
def
|
94
|
+
def now
|
94
95
|
t = Time.now
|
95
96
|
new!(:civil=>[t.year, t.mon, t.day], :parts=>[t.hour, t.min, t.sec, t.usec], :offset=>t.utc_offset)
|
96
97
|
end
|
97
98
|
|
98
99
|
# Create a new DateTime with the given year, day of year, hour, minute, second, microsecond, and offset.
|
99
|
-
def
|
100
|
+
def ordinal(year, yday, hour=0, min=0, sec=0, usec=0, offset=0)
|
100
101
|
new!(:ordinal=>[year, yday], :parts=>[hour, min, sec, usec], :offset=>offset)
|
101
102
|
end
|
102
103
|
|
103
|
-
|
104
|
+
private
|
104
105
|
|
105
|
-
def
|
106
|
+
def _expand_strptime_format(v)
|
106
107
|
case v
|
107
108
|
when '%c' then '%a %b %e %H:%M:%S %Y'
|
108
109
|
when '%T', '%X' then '%H:%M:%S'
|
@@ -113,7 +114,7 @@ module ThirdBase
|
|
113
114
|
end
|
114
115
|
end
|
115
116
|
|
116
|
-
def
|
117
|
+
def _strptime_part(v)
|
117
118
|
case v
|
118
119
|
when 'H', 'I' then ['(\d\d)', STRPTIME_PROC_H]
|
119
120
|
when 'k', 'l' then ['(\d?\d)', STRPTIME_PROC_H]
|
@@ -133,7 +134,7 @@ module ThirdBase
|
|
133
134
|
# * i + 3 : sec fraction
|
134
135
|
# * i + 4 : meridian indicator
|
135
136
|
# * i + 5 : time zone
|
136
|
-
def
|
137
|
+
def add_parsed_time_parts(m, h, i=4)
|
137
138
|
not_parsed = h[:not_parsed] || []
|
138
139
|
hour = m[i].to_i
|
139
140
|
meridian = m[i+4]
|
@@ -155,15 +156,15 @@ module ThirdBase
|
|
155
156
|
h
|
156
157
|
end
|
157
158
|
|
158
|
-
def
|
159
|
+
def default_parser_hash
|
159
160
|
DEFAULT_PARSERS
|
160
161
|
end
|
161
162
|
|
162
|
-
def
|
163
|
+
def default_parser_list
|
163
164
|
DEFAULT_PARSER_LIST
|
164
165
|
end
|
165
166
|
|
166
|
-
def
|
167
|
+
def hour_with_meridian(hour, meridian)
|
167
168
|
raise(ArgumentError, 'invalid date') unless hour and hour >= 1 and hour <= 12
|
168
169
|
if meridian == :am
|
169
170
|
hour == 12 ? 0 : hour
|
@@ -172,7 +173,7 @@ module ThirdBase
|
|
172
173
|
end
|
173
174
|
end
|
174
175
|
|
175
|
-
def
|
176
|
+
def new_from_parts(date_hash)
|
176
177
|
not_parsed = [:hour, :min, :sec].reject{|x| date_hash.has_key?(x)}
|
177
178
|
not_parsed.concat([:zone, :offset]) unless date_hash.has_key?(:offset)
|
178
179
|
not_parsed << :year unless date_hash.has_key?(:year) || date_hash.has_key?(:cwyear)
|
@@ -212,7 +213,7 @@ module ThirdBase
|
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
215
|
-
def
|
216
|
+
def convert_parsed_offset(of)
|
216
217
|
if offset = TIME_ZONE_SECOND_OFFSETS[of.upcase]
|
217
218
|
offset
|
218
219
|
else
|
@@ -221,24 +222,23 @@ module ThirdBase
|
|
221
222
|
end
|
222
223
|
end
|
223
224
|
|
224
|
-
def
|
225
|
+
def parser_hash
|
225
226
|
PARSERS
|
226
227
|
end
|
227
228
|
|
228
|
-
def
|
229
|
+
def parser_list
|
229
230
|
PARSER_LIST
|
230
231
|
end
|
231
232
|
|
232
|
-
def
|
233
|
+
def strptime_default
|
233
234
|
'%Y-%m-%dT%H:%M:%S'
|
234
235
|
end
|
235
|
-
|
236
|
-
|
236
|
+
end
|
237
|
+
extend ClassMethods
|
237
238
|
|
238
239
|
reset_parsers!
|
239
240
|
|
240
|
-
|
241
|
-
|
241
|
+
module InstanceMethods
|
242
242
|
# This datetime's offset from UTC, in seconds.
|
243
243
|
attr_reader :offset
|
244
244
|
alias utc_offset offset
|
@@ -335,8 +335,11 @@ module ThirdBase
|
|
335
335
|
return false unless DateTime === datetime
|
336
336
|
super and hour == datetime.hour and min == datetime.min and sec == datetime.sec and usec == datetime.usec
|
337
337
|
end
|
338
|
-
alias_method :eql?, :==
|
339
338
|
|
339
|
+
def eql?(datetime)
|
340
|
+
self == datetime
|
341
|
+
end
|
342
|
+
|
340
343
|
# Returns the fraction of the day for this datetime (Noon is 0.5)
|
341
344
|
def fract
|
342
345
|
@fract ||= (@hour*3600+@min*60+@sec+@usec/1000000.0)/86400.0
|
@@ -417,4 +420,6 @@ module ThirdBase
|
|
417
420
|
[@hour, @min, @sec, @usec]
|
418
421
|
end
|
419
422
|
end
|
423
|
+
include InstanceMethods
|
424
|
+
end
|
420
425
|
end
|
@@ -0,0 +1,411 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'third_base'
|
3
|
+
|
4
|
+
module ThirdBase
|
5
|
+
MJD_JD = 2400001
|
6
|
+
LD_JD = 2299160
|
7
|
+
ITALY = 2299161
|
8
|
+
ENGLAND = 2361222
|
9
|
+
JULIAN = -100000000000000000000000000000000000
|
10
|
+
GREGORIAN = 100000000000000000000000000000000000
|
11
|
+
|
12
|
+
# Compatibility class methods for Date and DateTime, necessary because ruby doesn't
|
13
|
+
# support multiple inheritance.
|
14
|
+
module CompatClassMethods
|
15
|
+
[ %w(os? julian?),
|
16
|
+
%w(ns? gregorian?),
|
17
|
+
%w(exist1? valid_jd?),
|
18
|
+
%w(exist2? valid_ordinal?),
|
19
|
+
%w(exist3? valid_date?),
|
20
|
+
%w(exist? valid_date?),
|
21
|
+
%w(existw? valid_commercial?),
|
22
|
+
%w(new0 new!),
|
23
|
+
%w(new1 jd),
|
24
|
+
%w(new2 ordinal),
|
25
|
+
%w(new3 new),
|
26
|
+
%w(neww commercial)
|
27
|
+
].each{|old, new| module_eval("def #{old}(*args, &block); #{new}(*args, &block); end")}
|
28
|
+
|
29
|
+
# Return the parts of the parsed date as a hash witht he following keys:
|
30
|
+
#
|
31
|
+
# * :hour : hour
|
32
|
+
# * :mday : day of month
|
33
|
+
# * :min : minute
|
34
|
+
# * :mon : month
|
35
|
+
# * :offset : time zone offset from UTC in seconds
|
36
|
+
# * :sec : second
|
37
|
+
# * :sec_fraction : fraction of a second
|
38
|
+
# * :year : year
|
39
|
+
# * :zone : time zone offset as string
|
40
|
+
def _parse(str, comp=false)
|
41
|
+
d = DateTime.parse(str)
|
42
|
+
{:mon=>d.mon, :zone=>d.zone, :sec=>d.sec, :year=>d.year, :hour=>d.hour, :offset=>d.utc_offset, :mday=>d.day, :min=>d.min, :sec_fraction=>d.usec/1000000.0}.reject{|k, v| d.not_parsed.include?(k)}
|
43
|
+
end
|
44
|
+
|
45
|
+
# Converts an Astronomical Julian Date to an Astronomical Modified Julian Date (substracts an integer from ajd)
|
46
|
+
def ajd_to_amjd(ajd)
|
47
|
+
ajd - MJD_JD
|
48
|
+
end
|
49
|
+
|
50
|
+
# Converts an Astronomical Julian Date to a Julian Date (returns ajd, ignores of)
|
51
|
+
def ajd_to_jd(ajd, of=0)
|
52
|
+
ajd
|
53
|
+
end
|
54
|
+
|
55
|
+
# Converts an Astronomical Modified Julian Date to an Astronomical Julian Date (adds an integer to amjd)
|
56
|
+
def amjd_to_ajd(amjd)
|
57
|
+
amjd + MJD_JD
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the julian date for the given civil date arguments, ignores sg.
|
61
|
+
def civil_to_jd(year, mon, day, sg=nil)
|
62
|
+
civil(year, mon, day).jd
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the julian date for the given commercial date arguments, ignores sg.
|
66
|
+
def commercial_to_jd(cwyear, cweek, cwday, sg=nil)
|
67
|
+
commercial(cwyear, cweek, cwday).jd
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the fraction of the date as an array of hours, minutes, seconds, and fraction on a second.
|
71
|
+
def day_fraction_to_time(fr)
|
72
|
+
hours, fr = (fr * 24).divmod(1)
|
73
|
+
minutes, fr = (fr * 60).divmod(1)
|
74
|
+
seconds, sec_fract = (fr * 60).divmod(1)
|
75
|
+
[hours, minutes, seconds, sec_fract]
|
76
|
+
end
|
77
|
+
|
78
|
+
# True if jd is greater than sg, false otherwise.
|
79
|
+
def gregorian?(jd, sg)
|
80
|
+
jd > sg
|
81
|
+
end
|
82
|
+
|
83
|
+
# All years divisible by 4 are leap years in the Gregorian calendar,
|
84
|
+
# except for years divisible by 100 and not by 400.
|
85
|
+
def leap?(y)
|
86
|
+
y % 4 == 0 && y % 100 != 0 || y % 400 == 0
|
87
|
+
end
|
88
|
+
alias gregorian_leap? leap?
|
89
|
+
|
90
|
+
# Converts a Julian Date to an Astronomical Julian Date (returns j, ignores fr and of)
|
91
|
+
def jd_to_ajd(j, fr, of=0)
|
92
|
+
j
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns [year, month, day] for the given julian date, ignores sg.
|
96
|
+
def jd_to_civil(j, sg=nil)
|
97
|
+
jd(j).send(:civil)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns [cwyear, cweek, cwday] for the given julian date, ignores sg.
|
101
|
+
def jd_to_commercial(j, sg=nil)
|
102
|
+
jd(j).send(:commercial)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Converts a julian date to the number of days since the adoption of
|
106
|
+
# the gregorian calendar in Italy (subtracts an integer from j).
|
107
|
+
def jd_to_ld(j)
|
108
|
+
j - LD_JD
|
109
|
+
end
|
110
|
+
|
111
|
+
# Convert a Julian Date to a Modified Julian Date (subtracts an integer from j).
|
112
|
+
def jd_to_mjd(j)
|
113
|
+
j - MJD_JD
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns [year, yday] for the given julian date, ignores sg.
|
117
|
+
def jd_to_ordinal(j, sg=nil)
|
118
|
+
jd(j).send(:ordinal)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns the day of week for the given julian date.
|
122
|
+
def jd_to_wday(j)
|
123
|
+
jd(j).wday
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns true if jd is less than sg, false otherwise.
|
127
|
+
def julian?(jd, sg)
|
128
|
+
jd < sg
|
129
|
+
end
|
130
|
+
|
131
|
+
# All years divisible by 4 are leap years in the Julian calendar.
|
132
|
+
def julian_leap?(y)
|
133
|
+
y % 4 == 0
|
134
|
+
end
|
135
|
+
|
136
|
+
# Converts a number of days since the adoption of the gregorian calendar in Italy
|
137
|
+
# to a julian date (adds an integer to ld).
|
138
|
+
def ld_to_jd(ld)
|
139
|
+
ld + LD_JD
|
140
|
+
end
|
141
|
+
|
142
|
+
# Converts a Modified Julian Date to a Julian Date (adds an integer to mjd).
|
143
|
+
def mjd_to_jd(mjd)
|
144
|
+
mjd + MJD_JD
|
145
|
+
end
|
146
|
+
|
147
|
+
# Converts the given year and day of year to a julian date, ignores sg.
|
148
|
+
def ordinal_to_jd(year, yday, sg=nil)
|
149
|
+
ordinal(year, yday).jd
|
150
|
+
end
|
151
|
+
|
152
|
+
# Converts the given hour, minute, and second to a fraction of a day as a Float.
|
153
|
+
def time_to_day_fraction(h, min, s)
|
154
|
+
(h*3600 + min*60 + s)/86400.0
|
155
|
+
end
|
156
|
+
|
157
|
+
# Return the julian date of the given year, month, and day if valid, or nil if not, ignores sg.
|
158
|
+
def valid_civil?(year, mon, day, sg=nil)
|
159
|
+
civil(year, mon, day).jd rescue nil
|
160
|
+
end
|
161
|
+
alias valid_date? valid_civil?
|
162
|
+
|
163
|
+
# Return the julian date of the given commercial week year, commercial week, and commercial
|
164
|
+
# week day if valid, or nil if not, ignores sg.
|
165
|
+
def valid_commercial?(cwyear, cweek, cwday, sg=nil)
|
166
|
+
commercial(cwyear, cweek, cwday).jd rescue nil
|
167
|
+
end
|
168
|
+
|
169
|
+
# Returns the julian date if valid (always returns jd, ignores sg).
|
170
|
+
def valid_jd?(jd, sg=nil)
|
171
|
+
jd
|
172
|
+
end
|
173
|
+
|
174
|
+
# Return the julian date of the given year and day of year if valid, or nil if not, ignores sg.
|
175
|
+
def valid_ordinal?(year, yday, sg=nil)
|
176
|
+
ordinal(year, yday).jd rescue nil
|
177
|
+
end
|
178
|
+
|
179
|
+
# Returns the fraction of the day if the time is valid, or nil if the time is not valid.
|
180
|
+
def valid_time?(h, min, s)
|
181
|
+
h += 24 if h < 0
|
182
|
+
min += 60 if min < 0
|
183
|
+
s += 60 if s < 0
|
184
|
+
return unless ((0..23) === h &&
|
185
|
+
(0..59) === min &&
|
186
|
+
(0..59) === s) ||
|
187
|
+
(24 == h &&
|
188
|
+
0 == min &&
|
189
|
+
0 == s)
|
190
|
+
time_to_day_fraction(h, min, s)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Converts a time zone string to a offset from UTC in seconds.
|
194
|
+
def zone_to_diff(zone)
|
195
|
+
if m = /\A([+-](?:\d{4}|\d\d:\d\d))\z/.match(zone)
|
196
|
+
x = m[1].gsub(':','')
|
197
|
+
x[0..2].to_i*3600 + x[3..4].to_i*60
|
198
|
+
else
|
199
|
+
0
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Compatibility instance methods for Date and DateTime, necessary because ruby doesn't
|
205
|
+
# support multiple inheritance.
|
206
|
+
module CompatInstanceMethods
|
207
|
+
# Returns the Astronomical Julian Date for this date (alias for jd)
|
208
|
+
def ajd
|
209
|
+
jd
|
210
|
+
end
|
211
|
+
|
212
|
+
# Returns the Astronomical Modified Julian Date for this date (jd plus an integer)
|
213
|
+
def amjd
|
214
|
+
jd - MJD_JD
|
215
|
+
end
|
216
|
+
alias mjd amjd
|
217
|
+
|
218
|
+
# Returns self.
|
219
|
+
def gregorian
|
220
|
+
self
|
221
|
+
end
|
222
|
+
alias england gregorian
|
223
|
+
alias julian gregorian
|
224
|
+
alias italy gregorian
|
225
|
+
|
226
|
+
# True, since the gregorian calendar is always used.
|
227
|
+
def gregorian?
|
228
|
+
true
|
229
|
+
end
|
230
|
+
alias ns? gregorian?
|
231
|
+
|
232
|
+
# False, since the gregorian calendar is never used.
|
233
|
+
def julian?
|
234
|
+
false
|
235
|
+
end
|
236
|
+
alias os? julian?
|
237
|
+
|
238
|
+
# Returns the days since the date of the adoption of the gregorian calendar in Italy
|
239
|
+
# (substracts an integer from jd).
|
240
|
+
def ld
|
241
|
+
jd - LD_JD
|
242
|
+
end
|
243
|
+
|
244
|
+
# Alias for day.
|
245
|
+
def mday
|
246
|
+
day
|
247
|
+
end
|
248
|
+
|
249
|
+
# Returns self, ignores sg.
|
250
|
+
def new_start(sg=nil)
|
251
|
+
self
|
252
|
+
end
|
253
|
+
alias newsg new_start
|
254
|
+
|
255
|
+
# Returns 0, since the gregorian calendar is always used.
|
256
|
+
def start
|
257
|
+
0
|
258
|
+
end
|
259
|
+
alias sg start
|
260
|
+
end
|
261
|
+
|
262
|
+
# ThirdBase's top level Date compatibility class, striving to be as close as possible
|
263
|
+
# to the standard Date class's API.
|
264
|
+
module DateCompatClassMethods
|
265
|
+
# Parse the date using strptime with the given format.
|
266
|
+
def _strptime(str, fmt='%F')
|
267
|
+
strptime(str, fmt)
|
268
|
+
end
|
269
|
+
|
270
|
+
# Creates a new Date with the given year, month, and day of month, ignores sg.
|
271
|
+
def civil(year=-4712, mon=1, day=1, sg=nil)
|
272
|
+
super(year, mon, day)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Creates a new Date with the given commercial week year, commercial week, and commercial week day, ignores sg.
|
276
|
+
def commercial(cwyear=1582, cweek=41, cwday=5, sg=nil)
|
277
|
+
super(cwyear, cweek, cwday)
|
278
|
+
end
|
279
|
+
|
280
|
+
# Creates a new Date with the given julian date, ignores sg.
|
281
|
+
def jd(j=0, sg=nil)
|
282
|
+
super(j)
|
283
|
+
end
|
284
|
+
|
285
|
+
# Creates a new Date with the given year and day of year, ignores sg.
|
286
|
+
def ordinal(year=-4712, yday=1, sg=nil)
|
287
|
+
super(year, yday)
|
288
|
+
end
|
289
|
+
|
290
|
+
# Parse given string using ThirdBase::Date's date parser, ignores comp and sg.
|
291
|
+
def parse(str="-4712-01-01", comp=false, sg=nil)
|
292
|
+
super(str)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Parse given string using given format, ignores sg.
|
296
|
+
def strptime(str="-4712-01-01", fmt='%F', sg=nil)
|
297
|
+
super(str, fmt)
|
298
|
+
end
|
299
|
+
|
300
|
+
# Creates a new Date with today's date, ignores sg.
|
301
|
+
def today(sg=nil)
|
302
|
+
super()
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
module DateCompatInstanceMethods
|
307
|
+
# Returns a formatted string representing the date.
|
308
|
+
def asctime
|
309
|
+
strftime('%a %b %e 00:00:00 %Y')
|
310
|
+
end
|
311
|
+
alias ctime asctime
|
312
|
+
|
313
|
+
# Returns 0.0, since Date don't have fractional days.
|
314
|
+
def day_fraction
|
315
|
+
0.0
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# ThirdBase's top level DateTime compatibility class, striving to be as close as possible
|
320
|
+
# to the standard DateTime class's API.
|
321
|
+
module DateTimeCompatClassMethods
|
322
|
+
# Parse the datetime using strptime with the given format.
|
323
|
+
def _strptime(str, fmt='%FT%T%z')
|
324
|
+
strptime(str, fmt)
|
325
|
+
end
|
326
|
+
|
327
|
+
# Creates a new DateTime with the given year, month, day of month, hour, minute, second, and offset, ignores sg.
|
328
|
+
def civil(year=-4712, mon=1, day=1, hour=0, min=0, sec=0, offset=0, sg=nil)
|
329
|
+
super(year, mon, day, hour, min, sec, 0, (offset*86400).to_i)
|
330
|
+
end
|
331
|
+
|
332
|
+
# Creates a new DateTime with the given commercial week year, commercial week, commercial week day,
|
333
|
+
# hour, minute, second, and offset, ignores sg.
|
334
|
+
def commercial(cwyear=1582, cweek=41, cwday=5, hour=0, min=0, sec=0, offset=0, sg=nil)
|
335
|
+
super(cwyear, cweek, cwday, hour, min, sec, 0, (offset*86400).to_i)
|
336
|
+
end
|
337
|
+
|
338
|
+
# Creates a new DateTime with the given julian date, hour, minute, second, and offset, ignores sg.
|
339
|
+
def jd(j=0, hour=0, min=0, sec=0, offset=0, sg=nil)
|
340
|
+
super(j, hour, min, sec, 0, (offset*86400).to_i)
|
341
|
+
end
|
342
|
+
|
343
|
+
# Creates a new DateTime with the given year, day of year, hour, minute, second, and offset, ignores sg.
|
344
|
+
def ordinal(year=-4712, yday=1, hour=0, min=0, sec=0, offset=0, sg=nil)
|
345
|
+
super(year, yday, hour, min, sec, 0, (offset*86400).to_i)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Parse given string using ThirdBase::DateTime's date parser, ignores comp and sg.
|
349
|
+
def parse(str="-4712-01-01T00:00:00+00:00", comp=false, sg=nil)
|
350
|
+
super(str)
|
351
|
+
end
|
352
|
+
|
353
|
+
# Parse given string using given format, ignores sg.
|
354
|
+
def strptime(str="-4712-01-01T00:00:00+00:00", fmt='%FT%T%z', sg=nil)
|
355
|
+
super(str, fmt)
|
356
|
+
end
|
357
|
+
|
358
|
+
# Creates a new DateTime with the current date and time, ignores sg.
|
359
|
+
def now(sg=nil)
|
360
|
+
super()
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
module DateTimeCompatInstanceMethods
|
365
|
+
# Returns a formatted string representing the date.
|
366
|
+
def asctime
|
367
|
+
strftime('%c')
|
368
|
+
end
|
369
|
+
alias ctime asctime
|
370
|
+
|
371
|
+
def day_fraction
|
372
|
+
fract
|
373
|
+
end
|
374
|
+
|
375
|
+
# Returns a new DateTime with the same date and time as this datetime, but with a new offset.
|
376
|
+
def new_offset(offset=0)
|
377
|
+
self.class.new!(:civil=>civil, :parts=>time_parts, :offset=>(offset*86400).to_i)
|
378
|
+
end
|
379
|
+
alias newof new_offset
|
380
|
+
|
381
|
+
# Return the offset as a Float representing the fraction of the day different from UTC.
|
382
|
+
def offset
|
383
|
+
@offset/86400.0
|
384
|
+
end
|
385
|
+
alias of offset
|
386
|
+
|
387
|
+
# Return the offset as a number of seconds from UTC.
|
388
|
+
def offset_sec
|
389
|
+
@offset
|
390
|
+
end
|
391
|
+
|
392
|
+
# The fraction of a second represented as a fraction of the entire day.
|
393
|
+
def sec_fraction
|
394
|
+
usec/86400000000.0
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
class Date
|
399
|
+
extend CompatClassMethods
|
400
|
+
include CompatInstanceMethods
|
401
|
+
extend DateCompatClassMethods
|
402
|
+
include DateCompatInstanceMethods
|
403
|
+
end
|
404
|
+
|
405
|
+
class DateTime
|
406
|
+
extend CompatClassMethods
|
407
|
+
include CompatInstanceMethods
|
408
|
+
extend DateTimeCompatClassMethods
|
409
|
+
include DateTimeCompatInstanceMethods
|
410
|
+
end
|
411
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: third_base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 1.3.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Jeremy Evans
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-07-06 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -25,19 +31,16 @@ files:
|
|
25
31
|
- LICENSE
|
26
32
|
- README
|
27
33
|
- bin/third_base
|
28
|
-
- lib/third_base.rb
|
34
|
+
- lib/third_base/compat/date/format.rb
|
35
|
+
- lib/third_base/compat/date.rb
|
29
36
|
- lib/third_base/compat.rb
|
30
37
|
- lib/third_base/date.rb
|
31
38
|
- lib/third_base/datetime.rb
|
32
|
-
- lib/third_base/
|
33
|
-
- lib/third_base
|
39
|
+
- lib/third_base/make_compat.rb
|
40
|
+
- lib/third_base.rb
|
34
41
|
- benchmark/datetime.rb
|
35
42
|
- benchmark/date.rb
|
36
|
-
- spec/
|
37
|
-
- spec/date_spec_helper.rb
|
38
|
-
- spec/compat_spec_helper.rb
|
39
|
-
- spec/datetime_spec_helper.rb
|
40
|
-
- spec/date/add_month_spec.rb
|
43
|
+
- spec/date/accessor_spec.rb
|
41
44
|
- spec/date/add_spec.rb
|
42
45
|
- spec/date/boat_spec.rb
|
43
46
|
- spec/date/civil_spec.rb
|
@@ -58,8 +61,8 @@ files:
|
|
58
61
|
- spec/date/upto_spec.rb
|
59
62
|
- spec/date/strftime_spec.rb
|
60
63
|
- spec/date/strptime_spec.rb
|
61
|
-
- spec/date/
|
62
|
-
- spec/datetime/
|
64
|
+
- spec/date/add_month_spec.rb
|
65
|
+
- spec/datetime/strptime_spec.rb
|
63
66
|
- spec/datetime/minus_spec.rb
|
64
67
|
- spec/datetime/eql_spec.rb
|
65
68
|
- spec/datetime/boat_spec.rb
|
@@ -68,13 +71,19 @@ files:
|
|
68
71
|
- spec/datetime/constructor_spec.rb
|
69
72
|
- spec/datetime/accessor_spec.rb
|
70
73
|
- spec/datetime/strftime_spec.rb
|
71
|
-
- spec/datetime/
|
74
|
+
- spec/datetime/add_spec.rb
|
72
75
|
- spec/compat/date_spec.rb
|
73
76
|
- spec/compat/compat_class_methods_spec.rb
|
74
77
|
- spec/compat/compat_instance_methods_spec.rb
|
75
78
|
- spec/compat/datetime_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
- spec/datetime_spec_helper.rb
|
81
|
+
- spec/date_spec_helper.rb
|
82
|
+
- spec/compat_spec_helper.rb
|
76
83
|
has_rdoc: true
|
77
84
|
homepage: http://third-base.rubyforge.org
|
85
|
+
licenses: []
|
86
|
+
|
78
87
|
post_install_message:
|
79
88
|
rdoc_options:
|
80
89
|
- --inline-source
|
@@ -85,23 +94,29 @@ rdoc_options:
|
|
85
94
|
require_paths:
|
86
95
|
- lib
|
87
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
88
98
|
requirements:
|
89
99
|
- - ">="
|
90
100
|
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
102
|
+
segments:
|
103
|
+
- 0
|
91
104
|
version: "0"
|
92
|
-
version:
|
93
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
94
107
|
requirements:
|
95
108
|
- - ">="
|
96
109
|
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
97
113
|
version: "0"
|
98
|
-
version:
|
99
114
|
requirements: []
|
100
115
|
|
101
116
|
rubyforge_project: third-base
|
102
|
-
rubygems_version: 1.3.
|
117
|
+
rubygems_version: 1.3.7
|
103
118
|
signing_key:
|
104
|
-
specification_version:
|
119
|
+
specification_version: 3
|
105
120
|
summary: A Fast and Easy Date/DateTime Class
|
106
121
|
test_files: []
|
107
122
|
|