Class: DtTools
- Inherits:
-
Object
- Object
- DtTools
- Defined in:
- lib/gloo/objs/dt/dt_tools.rb
Constant Summary collapse
- INCOMPATIBLE_DT_KINDS =
Kind pairings that can never be compared, even though both sides look like date/time values (eg. a time can't be compared to a date).
[ [ :date, :time ], [ :time, :date ], [ :time, :datetime ], [ :datetime, :time ] ].freeze
Class Method Summary collapse
-
.add(date, modifier = "1 day") ⇒ Object
Given a date, add the modifier to it.
-
.beginning_of_week ⇒ Object
Get the beginning of the week.
-
.compare_dt(left, right) ⇒ Object
Compare two raw values with date/time/datetime semantics.
-
.dt_kind(value) ⇒ Object
What kind of date/time value does this string look like? Returns :date, :time, :datetime, or nil if it doesn't match the exact format that gloo date/time/datetime objects use.
-
.in_next_ten_days?(dt) ⇒ Boolean
Is the date in the next 10 days?.
-
.is_dt_type?(obj) ⇒ Boolean
Is the given object a base Date Time object? True for DateTime and Time.
-
.is_future?(dt) ⇒ Boolean
Is the date in the future?.
-
.is_past?(dt) ⇒ Boolean
Is the date in the past?.
-
.is_this_week?(dt) ⇒ Boolean
Is the given date this week?.
-
.is_today?(dt) ⇒ Boolean
Is the given date today?.
-
.is_tomorrow?(dt) ⇒ Boolean
Is the given date tomorrow?.
-
.is_yesterday?(dt) ⇒ Boolean
Is the given date yesterday?.
-
.loose_dt_parse(kind, str) ⇒ Object
Loosely parse an arbitrary string (eg. "3 days from now") and reduce it to the granularity of the given kind for comparison.
-
.normalize_dt(kind, dt) ⇒ Object
Reduce a parsed value down to the granularity of the given kind, so a strictly-parsed value and a loosely-parsed value can be compared.
-
.strict_dt_parse(kind, str) ⇒ Object
Strictly parse a string using the exact format for the given kind.
-
.sub(dt, modifier = "1 day") ⇒ Object
Given a date, subtract the modifier from it.
Class Method Details
.add(date, modifier = "1 day") ⇒ Object
Given a date, add the modifier to it. The modifier takes the form of "1 day" or "2 weeks".
33 34 35 36 37 38 39 40 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 33 def self.add date, modifier="1 day" # Split out amount and unit amount, unit = modifier.split(' ') # converts "1 day" to 1.day duration = amount.to_i.send( unit ) return date + duration end |
.beginning_of_week ⇒ Object
Get the beginning of the week.
63 64 65 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 63 def self.beginning_of_week return Time.now.beginning_of_week( start_day = :sunday ) end |
.compare_dt(left, right) ⇒ Object
Compare two raw values with date/time/datetime semantics. Returns :not_dt if neither value looks like a date, time, or datetime, so the caller can fall back to its normal comparison logic. Otherwise returns -1, 0, or 1 (as with <=>), or nil if the two values can't be meaningfully compared.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 208 def self.compare_dt( left, right ) l_kind = dt_kind( left ) r_kind = dt_kind( right ) return :not_dt if l_kind.nil? && r_kind.nil? if l_kind && r_kind return nil if INCOMPATIBLE_DT_KINDS.include?( [ l_kind, r_kind ] ) l = strict_dt_parse( l_kind, left ) r = strict_dt_parse( r_kind, right ) return nil if l.nil? || r.nil? return l <=> r end # Only one side looks like a date/time/datetime value. Try to parse # the other side as that same kind (eg. a date compared to a string). kind = l_kind || r_kind known, other = l_kind ? [ left, right ] : [ right, left ] return nil unless other.is_a? String k = strict_dt_parse( kind, known ) return nil if k.nil? o = loose_dt_parse( kind, other ) return nil if o.nil? result = normalize_dt( kind, k ) <=> o return l_kind ? result : -result end |
.dt_kind(value) ⇒ Object
What kind of date/time value does this string look like? Returns :date, :time, :datetime, or nil if it doesn't match the exact format that gloo date/time/datetime objects use.
150 151 152 153 154 155 156 157 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 150 def self.dt_kind( value ) return nil unless value.is_a? String return :datetime if value =~ /\A\d{4}\.\d{2}\.\d{2}\s\d{2}:\d{2}:\d{2}\s(am|pm)\z/i return :date if value =~ /\A\d{4}\.\d{2}\.\d{2}\z/ return :time if value =~ /\A\d{2}:\d{2}:\d{2}\s(am|pm)\z/i return nil end |
.in_next_ten_days?(dt) ⇒ Boolean
Is the date in the next 10 days?
70 71 72 73 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 70 def self.in_next_ten_days?( dt ) return false if DtTools.is_past?( dt ) dt < 10.days.from_now.end_of_day end |
.is_dt_type?(obj) ⇒ Boolean
Is the given object a base Date Time object? True for DateTime and Time
18 19 20 21 22 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 18 def self.is_dt_type? obj return true if obj.is_a? ::DateTime return true if obj.is_a? ::Time return false end |
.is_future?(dt) ⇒ Boolean
Is the date in the future?
85 86 87 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 85 def self.is_future?( dt ) dt > Time.now.end_of_day end |
.is_past?(dt) ⇒ Boolean
Is the date in the past?
78 79 80 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 78 def self.is_past?( dt ) dt < Time.now.beginning_of_day end |
.is_this_week?(dt) ⇒ Boolean
Is the given date this week?
125 126 127 128 129 130 131 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 125 def self.is_this_week?( dt ) return false if dt.blank? dt = Chronic.parse( dt ) if dt.is_a?( String ) return false if dt <= ::Time.now.beginning_of_week( start_day = :sunday ) return false if dt >= ::Time.now.end_of_week( start_day = :sunday ) return true end |
.is_today?(dt) ⇒ Boolean
Is the given date today?
92 93 94 95 96 97 98 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 92 def self.is_today?( dt ) return false if dt.blank? dt = Chronic.parse( dt ) if dt.is_a? String return false if dt <= ::Time.now.beginning_of_day return false if dt >= ::Time.now.end_of_day return true end |
.is_tomorrow?(dt) ⇒ Boolean
Is the given date tomorrow?
103 104 105 106 107 108 109 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 103 def self.is_tomorrow?( dt ) return false if dt.blank? dt = Chronic.parse( dt ) if dt.is_a? String return false if dt <= ( ::Time.now.beginning_of_day + 1.day ) return false if dt >= ( ::Time.now.end_of_day + 1.day ) return true end |
.is_yesterday?(dt) ⇒ Boolean
Is the given date yesterday?
114 115 116 117 118 119 120 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 114 def self.is_yesterday?( dt ) return false if dt.blank? dt = Chronic.parse( dt ) if dt.is_a? String return false if dt <= ( ::Time.now.beginning_of_day - 1.day ) return false if dt >= ( ::Time.now.end_of_day - 1.day ) return true end |
.loose_dt_parse(kind, str) ⇒ Object
Loosely parse an arbitrary string (eg. "3 days from now") and reduce it to the granularity of the given kind for comparison.
Bare numbers (eg. "11", "2026") are rejected even though Chronic can parse them - it treats them as an hour or day-of-month relative to today, which is misleading rather than a genuine date/time value.
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 190 def self.loose_dt_parse( kind, str ) return nil if str =~ /\A\s*\d+\s*\z/ dt = Chronic.parse( str ) return nil if dt.nil? return normalize_dt( kind, dt.to_datetime ) rescue StandardError return nil end |
.normalize_dt(kind, dt) ⇒ Object
Reduce a parsed value down to the granularity of the given kind, so a strictly-parsed value and a loosely-parsed value can be compared.
175 176 177 178 179 180 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 175 def self.normalize_dt( kind, dt ) return dt.to_date if kind == :date return [ dt.hour, dt.min, dt.sec ] if kind == :time return dt end |
.strict_dt_parse(kind, str) ⇒ Object
Strictly parse a string using the exact format for the given kind.
162 163 164 165 166 167 168 169 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 162 def self.strict_dt_parse( kind, str ) format = { date: Gloo::Objs::Date::DEFAULT_FORMAT, time: Gloo::Objs::Time::DEFAULT_FORMAT, datetime: Gloo::Objs::Datetime::DEFAULT_FORMAT }[ kind ] return ::DateTime.strptime( str, format ) rescue StandardError return nil end |
.sub(dt, modifier = "1 day") ⇒ Object
Given a date, subtract the modifier from it. The modifier takes the form of "1 day" or "2 weeks".
46 47 48 49 50 51 52 53 |
# File 'lib/gloo/objs/dt/dt_tools.rb', line 46 def self.sub dt, modifier="1 day" # Split out amount and unit amount, unit = modifier.split(' ') # converts "1 day" to 1.day duration = amount.to_i.send( unit ) return dt - duration end |