chronic-davispuh 0.10.2.v0.1da32066b3f46f2506b3471e39557497e34afa27
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/HISTORY.md +243 -0
- data/LICENSE +21 -0
- data/README.md +185 -0
- data/Rakefile +68 -0
- data/chronic.gemspec +27 -0
- data/lib/chronic.rb +122 -0
- data/lib/chronic/arrow.rb +270 -0
- data/lib/chronic/date.rb +272 -0
- data/lib/chronic/definition.rb +208 -0
- data/lib/chronic/dictionary.rb +36 -0
- data/lib/chronic/handler.rb +44 -0
- data/lib/chronic/handlers/anchor.rb +65 -0
- data/lib/chronic/handlers/arrow.rb +84 -0
- data/lib/chronic/handlers/date.rb +270 -0
- data/lib/chronic/handlers/date_time.rb +72 -0
- data/lib/chronic/handlers/general.rb +130 -0
- data/lib/chronic/handlers/narrow.rb +54 -0
- data/lib/chronic/handlers/time.rb +167 -0
- data/lib/chronic/handlers/time_zone.rb +50 -0
- data/lib/chronic/objects/anchor_object.rb +263 -0
- data/lib/chronic/objects/arrow_object.rb +27 -0
- data/lib/chronic/objects/date_object.rb +164 -0
- data/lib/chronic/objects/date_time_object.rb +64 -0
- data/lib/chronic/objects/handler_object.rb +81 -0
- data/lib/chronic/objects/narrow_object.rb +85 -0
- data/lib/chronic/objects/time_object.rb +96 -0
- data/lib/chronic/objects/time_zone_object.rb +27 -0
- data/lib/chronic/parser.rb +154 -0
- data/lib/chronic/span.rb +32 -0
- data/lib/chronic/tag.rb +84 -0
- data/lib/chronic/tags/day_name.rb +34 -0
- data/lib/chronic/tags/day_portion.rb +33 -0
- data/lib/chronic/tags/day_special.rb +30 -0
- data/lib/chronic/tags/grabber.rb +29 -0
- data/lib/chronic/tags/keyword.rb +63 -0
- data/lib/chronic/tags/month_name.rb +39 -0
- data/lib/chronic/tags/ordinal.rb +52 -0
- data/lib/chronic/tags/pointer.rb +28 -0
- data/lib/chronic/tags/rational.rb +35 -0
- data/lib/chronic/tags/scalar.rb +101 -0
- data/lib/chronic/tags/season_name.rb +31 -0
- data/lib/chronic/tags/separator.rb +130 -0
- data/lib/chronic/tags/sign.rb +35 -0
- data/lib/chronic/tags/time_special.rb +34 -0
- data/lib/chronic/tags/time_zone.rb +56 -0
- data/lib/chronic/tags/unit.rb +174 -0
- data/lib/chronic/time.rb +141 -0
- data/lib/chronic/time_zone.rb +80 -0
- data/lib/chronic/token.rb +61 -0
- data/lib/chronic/token_group.rb +271 -0
- data/lib/chronic/tokenizer.rb +42 -0
- data/lib/chronic/version.rb +3 -0
- data/test/helper.rb +12 -0
- data/test/test_chronic.rb +190 -0
- data/test/test_daylight_savings.rb +98 -0
- data/test/test_handler.rb +113 -0
- data/test/test_parsing.rb +1520 -0
- data/test/test_span.rb +23 -0
- data/test/test_token.rb +31 -0
- metadata +218 -0
data/lib/chronic/date.rb
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
module Chronic
|
2
|
+
class Date
|
3
|
+
YEAR_QUARTERS = 4
|
4
|
+
YEAR_MONTHS = 12
|
5
|
+
SEASON_MONTHS = 3
|
6
|
+
QUARTER_MONTHS = 3
|
7
|
+
MONTH_DAYS = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
8
|
+
MONTH_DAYS_LEAP = [nil, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
9
|
+
FORTNIGHT_DAYS = 14
|
10
|
+
WEEK_DAYS = 7
|
11
|
+
DAY_HOURS = 24
|
12
|
+
YEAR_SECONDS = 31_536_000 # 365 * 24 * 60 * 60
|
13
|
+
SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
|
14
|
+
QUARTER_SECONDS = 7_776_000 # 90 * 24 * 60 * 60
|
15
|
+
MONTH_SECONDS = 2_592_000 # 30 * 24 * 60 * 60
|
16
|
+
FORTNIGHT_SECONDS = 1_209_600 # 14 * 24 * 60 * 60
|
17
|
+
WEEK_SECONDS = 604_800 # 7 * 24 * 60 * 60
|
18
|
+
WEEKEND_SECONDS = 172_800 # 2 * 24 * 60 * 60
|
19
|
+
DAY_SECONDS = 86_400 # 24 * 60 * 60
|
20
|
+
SEASONS = [
|
21
|
+
:spring,
|
22
|
+
:summer,
|
23
|
+
:autumn,
|
24
|
+
:winter
|
25
|
+
]
|
26
|
+
SEASON_DATES = {
|
27
|
+
:spring => [3, 20],
|
28
|
+
:summer => [6, 21],
|
29
|
+
:autumn => [9, 23],
|
30
|
+
:winter => [12, 22]
|
31
|
+
}
|
32
|
+
QUARTERS = [nil, 1, 4, 7, 10]
|
33
|
+
MONTHS = {
|
34
|
+
:january => 1,
|
35
|
+
:february => 2,
|
36
|
+
:march => 3,
|
37
|
+
:april => 4,
|
38
|
+
:may => 5,
|
39
|
+
:june => 6,
|
40
|
+
:july => 7,
|
41
|
+
:august => 8,
|
42
|
+
:september => 9,
|
43
|
+
:october => 10,
|
44
|
+
:november => 11,
|
45
|
+
:december => 12
|
46
|
+
}
|
47
|
+
DAYS = {
|
48
|
+
:sunday => 0,
|
49
|
+
:monday => 1,
|
50
|
+
:tuesday => 2,
|
51
|
+
:wednesday => 3,
|
52
|
+
:thursday => 4,
|
53
|
+
:friday => 5,
|
54
|
+
:saturday => 6
|
55
|
+
}
|
56
|
+
|
57
|
+
# Checks if given number could be day
|
58
|
+
def self.could_be_day?(day, width = nil)
|
59
|
+
day >= 1 && day <= 31 && (width.nil? || width <= 2)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Checks if given number could be month
|
63
|
+
def self.could_be_month?(month, width = nil)
|
64
|
+
month >= 1 && month <= 12 && (width.nil? || width <= 2)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Checks if given number could be year
|
68
|
+
def self.could_be_year?(year, width = nil)
|
69
|
+
year >= 0 && year <= 9999 && (width.nil? || width == 2 || width == 4)
|
70
|
+
end
|
71
|
+
# Build a year from a 2 digit suffix.
|
72
|
+
#
|
73
|
+
# year - The two digit Integer year to build from.
|
74
|
+
# bias - The Integer amount of future years to bias.
|
75
|
+
#
|
76
|
+
# Examples:
|
77
|
+
#
|
78
|
+
# make_year(96, 50) #=> 1996
|
79
|
+
# make_year(79, 20) #=> 2079
|
80
|
+
# make_year(00, 50) #=> 2000
|
81
|
+
#
|
82
|
+
# Returns The Integer 4 digit year.
|
83
|
+
def self.make_year(year, bias)
|
84
|
+
return year if year.to_s.size > 2
|
85
|
+
start_year = Chronic.time_class.now.year - bias
|
86
|
+
century = (start_year / 100) * 100
|
87
|
+
full_year = century + year
|
88
|
+
full_year += 100 if full_year < start_year
|
89
|
+
full_year
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.days_month(year, month)
|
93
|
+
days_month = ::Date.leap?(year) ? Date::MONTH_DAYS_LEAP[month] : Date::MONTH_DAYS[month]
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.month_overflow?(year, month, day)
|
97
|
+
day > days_month(year, month)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.add_season(year, season, modifier = 1)
|
101
|
+
index = SEASONS.index(season) + modifier
|
102
|
+
year += index / SEASONS.count
|
103
|
+
season = SEASONS[index % SEASONS.count]
|
104
|
+
[year, season]
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.add_quarter(year, quarter, amount = 1)
|
108
|
+
quarter += amount
|
109
|
+
if quarter > YEAR_QUARTERS or quarter < 1
|
110
|
+
year += (quarter - 1) / YEAR_QUARTERS
|
111
|
+
quarter = (quarter - 1) % YEAR_QUARTERS + 1
|
112
|
+
end
|
113
|
+
[year, quarter]
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.add_month(year, month, amount = 1)
|
117
|
+
month += amount
|
118
|
+
if month > YEAR_MONTHS or month < 1
|
119
|
+
year += (month - 1) / YEAR_MONTHS
|
120
|
+
month = (month - 1) % YEAR_MONTHS + 1
|
121
|
+
end
|
122
|
+
[year, month]
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.add_day(year, month, day, amount = 1)
|
126
|
+
day += amount
|
127
|
+
days_month = self.days_month(year, month)
|
128
|
+
while day > days_month
|
129
|
+
day -= days_month
|
130
|
+
year, month = add_month(year, month, 1)
|
131
|
+
days_month = self.days_month(year, month)
|
132
|
+
end
|
133
|
+
days_prev_month = self.days_month(year, (month - 2) % YEAR_MONTHS + 1)
|
134
|
+
while day < 1
|
135
|
+
day += days_prev_month
|
136
|
+
year, month = add_month(year, month, -1)
|
137
|
+
days_prev_month = self.days_month(year, month)
|
138
|
+
end
|
139
|
+
[year, month, day]
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.get_quarter_index(month)
|
143
|
+
(month - 1) / QUARTER_MONTHS + 1
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.get_quarter_month(month)
|
147
|
+
(get_quarter_index(month) - 1) * QUARTER_MONTHS + 1
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.get_quarter_end(quarter)
|
151
|
+
QUARTERS[(quarter - 1) % YEAR_QUARTERS + 1]
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.normalize(year, month, day)
|
155
|
+
year, month = add_month(year, month, 0)
|
156
|
+
year, month, day = add_day(year, month, day, 0)
|
157
|
+
[year, month, day]
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.split(date)
|
161
|
+
[date.year, date.month, date.day]
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.calculate_difference(diff, limit, modifier = 1, context = 0)
|
165
|
+
state = diff <=> 0
|
166
|
+
unless modifier.zero?
|
167
|
+
skew = modifier
|
168
|
+
skew += (modifier <=> 0) * -1 if diff * modifier > 0
|
169
|
+
diff += limit * skew
|
170
|
+
end
|
171
|
+
unless context.zero?
|
172
|
+
if modifier.zero?
|
173
|
+
diff += limit * context if state * context <= 0
|
174
|
+
elsif state.zero?
|
175
|
+
diff += limit * context if modifier * context < 0
|
176
|
+
end
|
177
|
+
end
|
178
|
+
diff
|
179
|
+
end
|
180
|
+
|
181
|
+
# Calculate difference in days between given week day and date day
|
182
|
+
def self.wday_diff(date, wday, modifier = 1, context = 0)
|
183
|
+
self.calculate_difference(wday - date.wday, WEEK_DAYS, modifier, context)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Get day difference for weekday
|
187
|
+
def self.wd_diff(date, modifier = 1)
|
188
|
+
diff = modifier
|
189
|
+
wday = date.wday
|
190
|
+
if modifier == 0 and wday == DAYS[:sunday]
|
191
|
+
diff = 1
|
192
|
+
elsif modifier == 0 and wday == DAYS[:saturday]
|
193
|
+
diff = 2
|
194
|
+
elsif modifier == 1 and wday == DAYS[:friday]
|
195
|
+
diff = 3
|
196
|
+
elsif modifier == 1 and wday == DAYS[:saturday]
|
197
|
+
diff = 2
|
198
|
+
elsif modifier == -1 and wday == DAYS[:sunday]
|
199
|
+
diff = -2
|
200
|
+
elsif modifier == -1 and wday == DAYS[:monday]
|
201
|
+
diff = -3
|
202
|
+
end
|
203
|
+
diff
|
204
|
+
end
|
205
|
+
|
206
|
+
# Calculate difference in months between given month and date month
|
207
|
+
def self.month_diff(date_month, month, modifier = 1, context = 0)
|
208
|
+
self.calculate_difference(month - date_month, YEAR_MONTHS, modifier, context)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Calculate difference in quarters between given quarter and date quarter
|
212
|
+
def self.quarter_diff(date_quarter, quarter, modifier = 1, context = 0)
|
213
|
+
self.calculate_difference(quarter - date_quarter, YEAR_QUARTERS, modifier, context)
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
module DateStructure
|
219
|
+
attr_accessor :year
|
220
|
+
attr_accessor :month
|
221
|
+
attr_accessor :day
|
222
|
+
attr_accessor :have_year
|
223
|
+
attr_accessor :have_month
|
224
|
+
attr_accessor :have_day
|
225
|
+
attr_reader :precision
|
226
|
+
def update(date)
|
227
|
+
@year = date.year
|
228
|
+
@month = date.month
|
229
|
+
@day = date.day
|
230
|
+
self
|
231
|
+
end
|
232
|
+
|
233
|
+
def is_equal?(date)
|
234
|
+
@year == date.year &&
|
235
|
+
@month == date.month &&
|
236
|
+
@day == date.day
|
237
|
+
end
|
238
|
+
|
239
|
+
def add_day(amount = 1)
|
240
|
+
@year, @month, @day = Date::add_day(@year, @month, @day, amount)
|
241
|
+
end
|
242
|
+
|
243
|
+
def to_a
|
244
|
+
[@year, @month, @day]
|
245
|
+
end
|
246
|
+
|
247
|
+
def get_end
|
248
|
+
[@year, @month, @day]
|
249
|
+
end
|
250
|
+
|
251
|
+
def to_span(time = nil, timezone = nil)
|
252
|
+
hour = minute = second = 0
|
253
|
+
hour, minute, second = time.to_a if time
|
254
|
+
span_start = Chronic.construct(@year, @month, @day, hour, minute, second, timezone)
|
255
|
+
end_year, end_month, end_day = get_end
|
256
|
+
span_end = Chronic.construct(end_year, end_month, end_day, 0, 0, 0, timezone)
|
257
|
+
span = Span.new(span_start, span_end, true)
|
258
|
+
span.precision = @precision
|
259
|
+
span.precision = time.precision if time and time.precision
|
260
|
+
span
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
class DateInfo
|
265
|
+
include DateStructure
|
266
|
+
def initialize(now = nil)
|
267
|
+
@now = now ? now : Chronic.time_class.now
|
268
|
+
update(@now)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module Chronic
|
2
|
+
# SpanDefinitions subclasses return definitions constructed by Handler instances (see handler.rb)
|
3
|
+
# SpanDefinitions subclasses follow a <Type> + Definitions naming pattern
|
4
|
+
# Types of Definitions are collected in Dictionaries (see dictionary.rb)
|
5
|
+
class Definitions
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def definitions
|
13
|
+
raise "definitions are set in subclasses of #{self.class}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SpanDefinitions < Definitions
|
18
|
+
end
|
19
|
+
|
20
|
+
# Match only Time
|
21
|
+
class TimeDefinitions < SpanDefinitions
|
22
|
+
def definitions
|
23
|
+
[
|
24
|
+
[[SeparatorSpace, TimeSpecial, SeparatorSpace, [KeywordAt, :optional], [SeparatorSpace, :optional], ScalarHour, SeparatorColon, ScalarMinute], :handle_ts_h_m],
|
25
|
+
[[SeparatorSpace, TimeSpecial, SeparatorSpace, [KeywordAt, :optional], [SeparatorSpace, :optional], ScalarHour], :handle_ts_h],
|
26
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, [SeparatorDot, SeparatorColon], ScalarSubsecond], :handle_h_m_s_ss],
|
27
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorColon, ScalarMinute, [SeparatorColon, SeparatorDot], ScalarSecond, [SeparatorSpace, :optional], DayPortion], :handle_h_m_s_dp],
|
28
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorColon, ScalarMinute, [SeparatorColon, SeparatorDot], ScalarSecond], :handle_h_m_s],
|
29
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, [SeparatorColon, SeparatorDot], ScalarMinute, SeparatorSpace, [KeywordIn, KeywordAt], SeparatorSpace, TimeSpecial], :handle_h_m_ts],
|
30
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, [SeparatorColon, SeparatorDot], ScalarMinute, [SeparatorSpace, :optional], DayPortion], :handle_h_m_dp],
|
31
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, [SeparatorColon, SeparatorDot], ScalarMinute], :handle_h_m],
|
32
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarWide, [SeparatorSpace, :optional], DayPortion], :handle_hhmm_dp],
|
33
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorSpace, KeywordIn, SeparatorSpace, TimeSpecial], :handle_h_ts],
|
34
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorSpace, [KeywordAt, :optional], [SeparatorSpace, :optional], TimeSpecial], :handle_h_ts],
|
35
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, [SeparatorSpace, :optional], DayPortion], :handle_h_dp],
|
36
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarWide, SeparatorSpace], :handle_hhmm],
|
37
|
+
[[[KeywordAt, :optional], SeparatorSpace, TimeSpecial], :handle_ts],
|
38
|
+
[[[KeywordAt, :optional], SeparatorSpace, ScalarHour, SeparatorSpace], :handle_h]
|
39
|
+
]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Match only Date
|
44
|
+
class DateDefinitions < SpanDefinitions
|
45
|
+
def definitions
|
46
|
+
[
|
47
|
+
[[DayName, SeparatorSpace, MonthName, SeparatorSpace, OrdinalDay, SeparatorSpace, ScalarYear], :handle_dn_mn_od_sy],
|
48
|
+
[[DayName, SeparatorSpace, MonthName, SeparatorSpace, ScalarDay, SeparatorSpace, ScalarYear], :handle_dn_mn_sd_sy],
|
49
|
+
[[DayName, SeparatorSpace, MonthName, SeparatorSpace, OrdinalDay], :handle_dn_mn_od],
|
50
|
+
[[DayName, SeparatorSpace, MonthName, SeparatorSpace, ScalarDay], :handle_dn_mn_sd],
|
51
|
+
[[MonthName, SeparatorSpace, OrdinalDay, [SeparatorComma, SeparatorSpace], [SeparatorSpace, :optional], ScalarYear], :handle_mn_od_sy],
|
52
|
+
[[MonthName, SeparatorSpace, ScalarDay, [SeparatorComma, :optional], [SeparatorSpace, :optional], ScalarYear], :handle_mn_sd_sy],
|
53
|
+
[[ScalarYear, SeparatorSpace, MonthName, SeparatorSpace, OrdinalDay], :handle_sy_mn_od],
|
54
|
+
[[ScalarYear, SeparatorSpace, MonthName, SeparatorSpace, ScalarDay], :handle_sy_mn_sd],
|
55
|
+
[[ScalarYear, SeparatorSlash, ScalarMonth, SeparatorSlash, ScalarDay], :handle_sy_sm_sd],
|
56
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay], :handle_sy_sm_sd],
|
57
|
+
[[ScalarYear, SeparatorDot, ScalarMonth, SeparatorDot, ScalarDay], :handle_sy_sm_sd],
|
58
|
+
[[ScalarYear, SeparatorColon, ScalarMonth, SeparatorColon, ScalarDay], :handle_sy_sm_sd],
|
59
|
+
[[OrdinalDay, SeparatorSpace, MonthName, SeparatorSpace, ScalarYear], :handle_od_mn_sy],
|
60
|
+
[[ScalarDay, SeparatorDash, MonthName, SeparatorDash, ScalarYear], :handle_sd_mn_sy],
|
61
|
+
[[ScalarDay, SeparatorSpace, MonthName, SeparatorSpace, ScalarYear], :handle_sd_mn_sy],
|
62
|
+
[[ScalarDay, SeparatorDot, ScalarMonth, SeparatorDot, ScalarYear], :handle_sd_sm_sy]
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Match only Date in short form
|
68
|
+
class ShortDateDefinitions < SpanDefinitions
|
69
|
+
def definitions
|
70
|
+
[
|
71
|
+
[[DayName, SeparatorSpace, OrdinalDay], :handle_dn_od],
|
72
|
+
[[MonthName, SeparatorSpace, OrdinalDay], :handle_mn_od],
|
73
|
+
[[MonthName, [SeparatorSpace, SeparatorDash], ScalarDay, [SeparatorSpace, Unit, :none]], :handle_mn_sd],
|
74
|
+
[[MonthName, SeparatorSpace, SeparatorApostrophe, ScalarYear], :handle_mn_sy],
|
75
|
+
[[MonthName, SeparatorSpace, ScalarYear], :handle_mn_sy],
|
76
|
+
[[ScalarFullYear, [SeparatorDash, SeparatorSlash], ScalarMonth], :handle_sy_sm],
|
77
|
+
[[ScalarFullYear, SeparatorSpace, MonthName], :handle_sy_mn],
|
78
|
+
[[OrdinalDay, SeparatorSpace, MonthName], :handle_od_mn],
|
79
|
+
[[ScalarDay, [SeparatorSpace, SeparatorDash, :optional], MonthName], :handle_sd_mn],
|
80
|
+
[[KeywordIn, SeparatorSpace, MonthName], :handle_mn],
|
81
|
+
[[DaySpecial], :handle_ds],
|
82
|
+
[[MonthName], :handle_mn],
|
83
|
+
[[DayName], :handle_dn],
|
84
|
+
[[SeparatorSpace, ScalarYear, SeparatorSpace], :handle_sy],
|
85
|
+
[[OrdinalDay], :handle_od],
|
86
|
+
[[ScalarFullYear], :handle_sy]
|
87
|
+
]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Match only TimeZone
|
92
|
+
class TimezoneDefinitions < SpanDefinitions
|
93
|
+
def definitions
|
94
|
+
[
|
95
|
+
[[[Sign, :optional], ScalarHour, SeparatorColon, ScalarMinute], :handle_hh_mm],
|
96
|
+
[[Sign, ScalarWide], :handle_hhmm],
|
97
|
+
[[TimeZoneAbbreviation], :handle_abbr],
|
98
|
+
[[TimeZoneGeneric], :handle_generic]
|
99
|
+
]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Match full Date+Time, can be with TimeZone
|
104
|
+
class DateTimeDefinitions < SpanDefinitions
|
105
|
+
def definitions
|
106
|
+
[
|
107
|
+
[[DayName, SeparatorSpace, MonthName, SeparatorSpace, ScalarDay, SeparatorSpace, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, SeparatorSpace, TimeZoneAbbreviation, SeparatorSpace, ScalarYear], :handle_dn_mn_sd_h_m_s_abbr_sy],
|
108
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, [SeparatorDot, SeparatorColon], ScalarSubsecond, Sign, ScalarHour, SeparatorColon, ScalarMinute], :handle_sy_sm_sd_h_m_s_ss_hh_mm],
|
109
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, Sign, ScalarHour, SeparatorColon, ScalarMinute], :handle_sy_sm_sd_h_m_s_hh_mm],
|
110
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, [SeparatorDot, SeparatorColon], ScalarSubsecond, TimeZoneGeneric], :handle_sy_sm_sd_h_m_s_ss_tz],
|
111
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, [SeparatorDot, SeparatorColon], ScalarSubsecond], :handle_sy_sm_sd_h_m_s_ss],
|
112
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond, TimeZoneGeneric], :handle_sy_sm_sd_h_m_s_tz],
|
113
|
+
[[ScalarYear, SeparatorDash, ScalarMonth, SeparatorDash, ScalarDay, SeparatorT, ScalarHour, SeparatorColon, ScalarMinute, SeparatorColon, ScalarSecond], :handle_sy_sm_sd_h_m_s]
|
114
|
+
]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class AnchorDefinitions < SpanDefinitions
|
119
|
+
def definitions
|
120
|
+
[
|
121
|
+
[[Grabber, SeparatorSpace, DayName], :handle_gr_dn],
|
122
|
+
[[Grabber, SeparatorSpace, MonthName], :handle_gr_mn],
|
123
|
+
[[Grabber, SeparatorSpace, SeasonName], :handle_gr_sn],
|
124
|
+
[[Grabber, SeparatorSpace, TimeSpecial], :handle_gr_ts],
|
125
|
+
[[Grabber, SeparatorSpace, KeywordQ, Scalar], :handle_gr_q_s],
|
126
|
+
[[Grabber, SeparatorSpace, Unit], :handle_gr_u],
|
127
|
+
[[KeywordIn, SeparatorSpace, Scalar, SeparatorSpace, Unit], :handle_in_s_u],
|
128
|
+
[[DaySpecial], :handle_ds],
|
129
|
+
[[KeywordQ, Scalar], :handle_q_s],
|
130
|
+
[[Unit], :handle_u]
|
131
|
+
]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class ArrowDefinitions < SpanDefinitions
|
136
|
+
def definitions
|
137
|
+
[
|
138
|
+
[[Pointer, [SeparatorSpace, :optional], Scalar, [SeparatorSpace, :optional], Unit], :handle_p_s_u],
|
139
|
+
[[Scalar, [SeparatorSpace, :optional], Unit, SeparatorSpace, Pointer], :handle_s_u_p],
|
140
|
+
[[Scalar, [SeparatorSpace, :optional], DayName, SeparatorSpace, Pointer], :handle_s_dn_p],
|
141
|
+
[[Rational, SeparatorSpace, Pointer], :handle_r_p],
|
142
|
+
[[Unit, SeparatorSpace, Pointer], :handle_u_p],
|
143
|
+
[[Scalar, [SeparatorSpace, :optional], Unit], :handle_s_u],
|
144
|
+
[[Scalar, [SeparatorSpace, :optional], Pointer], :handle_s_p],
|
145
|
+
]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class NarrowDefinitions < SpanDefinitions
|
150
|
+
def definitions
|
151
|
+
[
|
152
|
+
[[Grabber, SeparatorSpace, Ordinal, SeparatorSpace, Unit], :handle_gr_o_u],
|
153
|
+
[[Ordinal, SeparatorSpace, Unit], :handle_o_u],
|
154
|
+
[[Ordinal, SeparatorSpace, DayName], :handle_o_dn],
|
155
|
+
[[KeywordQ, Scalar], :handle_q_s]
|
156
|
+
]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Date depending on endianess
|
161
|
+
class EndianDefinitions < SpanDefinitions
|
162
|
+
def definitions
|
163
|
+
prefered_endian
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.middle
|
167
|
+
[
|
168
|
+
[[ScalarMonth, SeparatorSlash, ScalarDay, SeparatorSlash, ScalarYear, [SeparatorDot, Scalar, :none]], :handle_sm_sd_sy],
|
169
|
+
[[ScalarMonth, SeparatorDash, ScalarDay, SeparatorDash, ScalarYear, [SeparatorDot, Scalar, :none]], :handle_sm_sd_sy],
|
170
|
+
[[ScalarMonth, [SeparatorSlash, SeparatorDash, SeparatorDot], ScalarDay, [SeparatorSlash, :none]], :handle_sm_sd]
|
171
|
+
]
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.little
|
175
|
+
[
|
176
|
+
[[ScalarDay, SeparatorDash, ScalarMonth, SeparatorDash, ScalarYear, [SeparatorDot, Scalar, :none]], :handle_sd_sm_sy],
|
177
|
+
[[ScalarDay, SeparatorSlash, ScalarMonth, SeparatorSlash, ScalarYear, [SeparatorDot, Scalar, :none]], :handle_sd_sm_sy],
|
178
|
+
[[ScalarDay, [SeparatorSlash, SeparatorDash, SeparatorDot], ScalarMonth, [SeparatorSlash, :none]], :handle_sd_sm]
|
179
|
+
]
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.month_year
|
183
|
+
[
|
184
|
+
[[ScalarMonth, SeparatorSlash, ScalarYear], :handle_sm_sy]
|
185
|
+
]
|
186
|
+
end
|
187
|
+
|
188
|
+
def prefered_endian
|
189
|
+
options[:endian_precedence] ||= [:middle, :little]
|
190
|
+
options[:endian_precedence] = [options[:endian_precedence]] unless options[:endian_precedence].is_a?(Array)
|
191
|
+
definition_list = []
|
192
|
+
options[:endian_precedence].each do |endian|
|
193
|
+
case endian
|
194
|
+
when :little
|
195
|
+
definition_list += self.class.little
|
196
|
+
when :middle
|
197
|
+
definition_list += self.class.middle
|
198
|
+
when :month_year
|
199
|
+
definition_list += self.class.month_year
|
200
|
+
else
|
201
|
+
raise ArgumentError, "Unknown endian option '#{endian}'"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
definition_list
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|