third_base 1.2.0 → 1.3.0
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/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
|
|