Module: Daru::DateTimeIndexHelper
- Defined in:
- lib/daru/date_time/index.rb
Overview
Private module for storing helper functions for DateTimeIndex.
Constant Summary collapse
- OFFSETS_HASH =
{ 'S' => Daru::Offsets::Second, 'M' => Daru::Offsets::Minute, 'H' => Daru::Offsets::Hour, 'D' => Daru::Offsets::Day, 'W' => Daru::Offsets::Week, 'MONTH' => Daru::Offsets::Month, 'MB' => Daru::Offsets::MonthBegin, 'ME' => Daru::Offsets::MonthEnd, 'YEAR' => Daru::Offsets::Year, 'YB' => Daru::Offsets::YearBegin, 'YE' => Daru::Offsets::YearEnd }.freeze
- TIME_INTERVALS =
{ Rational(1,1) => Daru::Offsets::Day, Rational(1,24) => Daru::Offsets::Hour, Rational(1,1440) => Daru::Offsets::Minute, Rational(1,86_400) => Daru::Offsets::Second }.freeze
- DOW_REGEXP =
Regexp.new(Daru::DAYS_OF_WEEK.keys.join('|'))
- FREQUENCY_PATTERN =
/^ (?<multiplier>[0-9]+)? ( (?<offset>MONTH|YEAR|S|H|MB|ME|M|D|YB|YE) | (?<offset>W)(-(?<weekday>#{DOW_REGEXP}))? )$/x
- DATE_PRECISION_REGEXP =
/^(\d\d\d\d)(-\d{1,2}(-\d{1,2}( \d{1,2}(:\d{1,2}(:\d{1,2})?)?)?)?)?$/
- DATE_PRECISIONS =
[nil, :year, :month, :day, :hour, :min, :sec].freeze
Class Method Summary collapse
- .begin_from_offset?(offset, start) ⇒ Boolean
- .coerce_date(date) ⇒ Object
- .date_time_from(date_string, date_precision) ⇒ Object
- .determine_date_precision_of(date_string) ⇒ Object
- .find_date_string_bounds(date_string) ⇒ Object
- .find_index_of_date(data, date_time) ⇒ Object
-
.generate_bounds(date_time, date_precision) ⇒ Object
rubocop:disable Metrics/AbcSize,Metrics/MethodLength.
- .generate_data(start, en, offset, periods) ⇒ Object
- .infer_offset(data) ⇒ Object
- .key_out_of_bounds?(key, data) ⇒ Boolean
- .last_date(data) ⇒ Object
-
.offset_from_frequency(frequency) ⇒ Object
Generates a Daru::DateOffset object for generic offsets or one of the specialized classed within Daru::Offsets depending on the ‘frequency’ string.
- .possibly_convert_to_date_time(data) ⇒ Object
- .verify_start_and_end(start, en) ⇒ Object
Class Method Details
.begin_from_offset?(offset, start) ⇒ Boolean
62 63 64 65 |
# File 'lib/daru/date_time/index.rb', line 62 def begin_from_offset? offset, start offset.is_a?(Daru::Offsets::Tick) || offset.respond_to?(:on_offset?) && offset.on_offset?(start) end |
.coerce_date(date) ⇒ Object
57 58 59 60 |
# File 'lib/daru/date_time/index.rb', line 57 def coerce_date date return date unless date.is_a?(String) date_time_from(date, determine_date_precision_of(date)) end |
.date_time_from(date_string, date_precision) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/daru/date_time/index.rb', line 116 def date_time_from date_string, date_precision case date_precision when :year DateTime.new(date_string.gsub(/[^0-9]/, '').to_i) when :month DateTime.new( date_string.match(/\d\d\d\d/).to_s.to_i, date_string.match(/\-\d?\d/).to_s.delete('-').to_i ) else DateTime.parse date_string end end |
.determine_date_precision_of(date_string) ⇒ Object
133 134 135 136 137 |
# File 'lib/daru/date_time/index.rb', line 133 def determine_date_precision_of date_string components = date_string.scan(DATE_PRECISION_REGEXP).flatten.compact DATE_PRECISIONS[components.count] or raise ArgumentError, "Unacceptable date string #{date_string}" end |
.find_date_string_bounds(date_string) ⇒ Object
110 111 112 113 114 |
# File 'lib/daru/date_time/index.rb', line 110 def find_date_string_bounds date_string date_precision = determine_date_precision_of date_string date_time = date_time_from date_string, date_precision generate_bounds date_time, date_precision end |
.find_index_of_date(data, date_time) ⇒ Object
103 104 105 106 107 108 |
# File 'lib/daru/date_time/index.rb', line 103 def find_index_of_date data, date_time searched = data.bsearch { |d| d[0] >= date_time } raise(ArgumentError, "Cannot find #{date_time}") if searched.nil? || searched[0] != date_time searched[1] end |
.generate_bounds(date_time, date_precision) ⇒ Object
rubocop:disable Metrics/AbcSize,Metrics/MethodLength
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/daru/date_time/index.rb', line 139 def generate_bounds date_time, date_precision # rubocop:disable Metrics/AbcSize,Metrics/MethodLength # FIXME: about that ^ disable: I'd like to use my zverok/time_boots here, which will simplify things case date_precision when :year [ date_time, DateTime.new(date_time.year,12,31,23,59,59) ] when :month [ date_time, DateTime.new(date_time.year, date_time.month, ((date_time >> 1) - 1).day, 23,59,59) ] when :day [ date_time, DateTime.new(date_time.year, date_time.month, date_time.day,23,59,59) ] when :hour [ date_time, DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour,59,59) ] when :min [ date_time, DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.min, 59) ] else # second or when precision is same as offset [date_time, date_time] end end |
.generate_data(start, en, offset, periods) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/daru/date_time/index.rb', line 67 def generate_data start, en, offset, periods data = [] new_date = begin_from_offset?(offset, start) ? start : offset + start if periods.nil? # use end loop do break if new_date > en data << new_date new_date = offset + new_date end else periods.times do data << new_date new_date = offset + new_date end end data end |
.infer_offset(data) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/daru/date_time/index.rb', line 93 def infer_offset data diffs = data.each_cons(2).map { |d1, d2| d2 - d1 } if diffs.uniq.count == 1 TIME_INTERVALS[diffs.first].new else nil end end |
.key_out_of_bounds?(key, data) ⇒ Boolean
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/daru/date_time/index.rb', line 183 def key_out_of_bounds? key, data dates = data.transpose.first precision = determine_date_precision_of key date_time = date_time_from key, precision # FIXME: I'm pretty suspicious about logic here: # why only year & month? - zverok 2016-05-16 case precision when :year year_out_of_bounds?(date_time, dates) when :month year_month_out_of_bounds?(date_time, dates) end end |
.last_date(data) ⇒ Object
179 180 181 |
# File 'lib/daru/date_time/index.rb', line 179 def last_date data data.sort_by { |d| d[1] }.last end |
.offset_from_frequency(frequency) ⇒ Object
Generates a Daru::DateOffset object for generic offsets or one of the specialized classed within Daru::Offsets depending on the ‘frequency’ string.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/daru/date_time/index.rb', line 38 def offset_from_frequency frequency return frequency if frequency.is_a?(Daru::DateOffset) frequency ||= 'D' matched = FREQUENCY_PATTERN.match(frequency) or raise ArgumentError, "Invalid frequency string #{frequency}" n = (matched[:multiplier] || 1).to_i offset_string = matched[:offset] offset_klass = OFFSETS_HASH[offset_string] or raise ArgumentError, "Cannont interpret offset #{offset_string}" if offset_string == 'W' offset_klass.new(n, weekday: Daru::DAYS_OF_WEEK[matched[:weekday]]) else offset_klass.new(n) end end |
.possibly_convert_to_date_time(data) ⇒ Object
175 176 177 |
# File 'lib/daru/date_time/index.rb', line 175 def possibly_convert_to_date_time data data[0].is_a?(String) ? data.map! { |e| DateTime.parse(e) } : data end |
.verify_start_and_end(start, en) ⇒ Object
87 88 89 90 91 |
# File 'lib/daru/date_time/index.rb', line 87 def verify_start_and_end start, en raise ArgumentError, 'Start and end cannot be the same' if start == en raise ArgumentError, 'Start must be lesser than end' if start > en raise ArgumentError, 'Only same time zones are allowed' if start.zone != en.zone end |