Class: EasyTime
- Inherits:
-
Object
- Object
- EasyTime
- Includes:
- Comparable
- Defined in:
- lib/easy_time.rb,
lib/easy_time/convert.rb,
lib/easy_time/version.rb
Overview
These class methods are for converting most date or time formats to a Time
Constant Summary collapse
- DEFAULT_TIME_COMPARISON_TOLERANCE =
we define a default tolerance below. This causes time value differences less than this to be considered "equal". This allows for time comparisons between values from different systems where the clock sync might not be very accurate.
If this default tolerance is not desired, it can be overridden with an explicit tolerance setting in the singleton class instance:
EasyTime.comparison_tolerance = 0
1.second
- ISO_DATE_RE =
A regexp pattern to match the date part of an ISO8601 time string
/(?: \d{4}-\d\d-\d\d # yyyy-mm-dd | \d{4}-\d\d # yyyy-mm | \d{4}-\d{3} # yyyy-ddd | \d{7,8} # yyyymmdd or yyyyddd | --\d\d-?\d\d # --mm-dd or --mmdd ) /x.freeze
- ISO_TIME_RE =
A regexp pattern to match the time part of an ISO8601 time string
/(?: (?: (?: \d\d:\d\d:\d\d # hh:mm:ss | \d{6} # hhmmss ) (?: \.\d+ )? # optional .sss ) | \d\d:?\d\d # hh:mm or hhmm | \d{2} # hh ) /x.freeze
- ISO_ZONE_RE =
A regexp pattern to match the timezone part of an ISO8601 time string
/(?: Z # Z for zulu (GMT = 0) | [+-] \d\d:?\d\d # +-HH:MM or +-HHMM ) /x.freeze
- ISO8601_RE =
A regexp pattern to match an ISO8601 time string.
/ #{ISO_DATE_RE} T #{ISO_TIME_RE} #{ISO_ZONE_RE} /x.freeze
- RFC2822_RE =
A regexp pattern to match an RFC2822 time string (used in Email messages and systems)
/\w{3}, \s # Wed, \d{1,2} \s # 01 or 1 \w{3} \s # Oct \d{4} \s # 2020 \d\d:\d\d:\d\d \s # HH:MM:SS [+-]\d\d:?\d\d # +-HH:MM or +-HHHMM (zone) /x.freeze
- HTTPDATE_RE =
A regexp pattern to match an HTTPDate time string (used in web server transactions and logs)
/\w{3}, \s # Wed, \d{1,2} \s # 01 or 1 \w{3} \s # Oct \d{4} \s # 2020 \d\d:\d\d:\d\d \s # HH:MM:SS \w+ # GMT /x.freeze
- XMLSCHEMA_RE =
A regexp pattern to match an XMLSchema time string (used in XML documents)
/\d{4}-\d\d-\d\d # yyyy-mm-dd T \d\d:\d\d:\d\d # HH:MM:SS [+-] # +- \d\d:\d\d # HH:MM /x.freeze
- VERSION =
"0.2.2"
Class Attribute Summary collapse
-
.comparison_tolerance ⇒ Integer
The number of seconds of tolerance to use for "equality" tests.
Instance Attribute Summary collapse
-
#comparison_tolerance ⇒ Object
if there is no instance value, default to the class value.
-
#other_time ⇒ Object
readonly
Returns the value of attribute other_time.
-
#time ⇒ Object
Returns the value of attribute time.
Class Method Summary collapse
-
.add(time, duration) ⇒ EasyTime
The
time
with theduration
added. - .between?(time1, t_arg, t_max = nil, tolerance: nil) ⇒ Object
-
.compare(time1, time2, tolerance: nil) ⇒ Integer
One of [-1, 0, 1] if
time1
<, ==, or > thantime2
, or nil iftime2
cannot be converted to aTime
value. - .convert(arg, coerce = true) ⇒ Time
-
.is_a_time?(value) ⇒ Boolean
True if value is one the known Time classes, or responds to :acts_like_time?.
- .method_missing(symbol, *args, &block) ⇒ Object
-
.newer?(time1, time2, tolerance: nil) ⇒ Boolean
True if
time1
>time2
, using a tolerant comparison. -
.older?(time1, time2, tolerance: nil) ⇒ Boolean
True if
time1
>time2
, using a tolerant comparison. - .parse(time_string) ⇒ EasyTime
- .respond_to_missing?(symbol, include_all = false) ⇒ Boolean
-
.same?(time1, time2, tolerance: nil) ⇒ Boolean
True if
time1
>time2
, using a tolerant comparison. -
.subtract(time, time_or_duration) ⇒ EasyTime, Duration
An
EasyTime
value, when a duration is subtracted from a time, or a duration (Integer) value, when one time is subtracted from another time. -
.time_format_style(str) ⇒ Object
this method returns parser class methods in the Time class for corresponding time format patterns.
Instance Method Summary collapse
-
#+(duration) ⇒ EasyTime
Updated date and time value.
-
#-(other) ⇒ EasyTime, Integer
Subtract a value from an EasyTime.
-
#<=>(other) ⇒ Integer
compare with automatic type-conversion and tolerance.
- #acts_like_time? ⇒ Boolean
-
#between?(t_arg, t_max = nil) ⇒ Object
compare a time against a min and max date pair, or against a time Range value.
-
#compare(time2, tolerance: nil) ⇒ Integer
One of the values: [-1, 0, 1] if
self
[<, ==, >]time2
, or nil iftime2
cannot be converted to aTime
value. -
#different?(time2) ⇒ Boolean
True if
self
!=time2
. -
#initialize(*time, tolerance: nil) ⇒ EasyTime
constructor
A new instance of EasyTime.
-
#newer?(time2) ⇒ Boolean
True if
self
>time2
. -
#older?(time2) ⇒ Boolean
True if
self
<time2
. -
#same?(time2) ⇒ Boolean
(also: #eql?)
True if
self
==time2
. -
#with_tolerance(value) ⇒ EasyTime
returns a new EasyTime value with the tolerance set to value.
Constructor Details
#initialize(*time, tolerance: nil) ⇒ EasyTime
Returns a new instance of EasyTime.
248 249 250 251 |
# File 'lib/easy_time.rb', line 248 def initialize(*time, tolerance: nil) @time = time.size.nonzero? && convert(time.size == 1 ? time.first : time) @comparison_tolerance = tolerance end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args, &block) ⇒ Object (private)
intercept any time methods so they can wrap the time-like result in a new EasyTime object.
384 385 386 387 388 389 390 391 |
# File 'lib/easy_time.rb', line 384 def method_missing(symbol, *args, &block) if time.respond_to?(symbol) value = time.send(symbol, *args, &block) is_a_time?(value) ? dup.tap { |eztime| eztime.time = value } : value else super(symbol, *args, &block) end end |
Class Attribute Details
.comparison_tolerance ⇒ Integer
Returns the number of seconds of tolerance to use for "equality" tests.
205 206 207 |
# File 'lib/easy_time.rb', line 205 def comparison_tolerance @tolerance || DEFAULT_TIME_COMPARISON_TOLERANCE end |
Instance Attribute Details
#comparison_tolerance ⇒ Object
if there is no instance value, default to the class value
254 255 256 |
# File 'lib/easy_time.rb', line 254 def comparison_tolerance @comparison_tolerance || self.class.comparison_tolerance end |
#other_time ⇒ Object (readonly)
Returns the value of attribute other_time.
243 244 245 |
# File 'lib/easy_time.rb', line 243 def other_time @other_time end |
#time ⇒ Object
Returns the value of attribute time.
242 243 244 |
# File 'lib/easy_time.rb', line 242 def time @time end |
Class Method Details
.add(time, duration) ⇒ EasyTime
Returns the time
with the duration
added.
182 183 184 |
# File 'lib/easy_time.rb', line 182 def add(time, duration) EasyTime.new(time) + duration end |
.between?(time1, t_min, t_max, tolerance: nil) ⇒ Boolean .between?(time1, time_range, tolerance: nil) ⇒ Boolean
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/easy_time.rb', line 153 def between?(time1, t_arg, t_max=nil, tolerance: nil) if t_arg.is_a?(Range) t_min = t_arg.min t_max = t_arg.max else t_min = t_arg end compare(time1, t_min, tolerance: tolerance) >= 0 && compare(time1, t_max, tolerance: tolerance) <= 0 end |
.compare(time1, time2, tolerance: nil) ⇒ Integer
Returns one of [-1, 0, 1] if time1
<, ==, or > than time2
,
or nil if time2
cannot be converted to a Time
value.
170 171 172 |
# File 'lib/easy_time.rb', line 170 def compare(time1, time2, tolerance: nil) new(time1, tolerance: tolerance) <=> time2 end |
.convert(arg, coerce = true) ⇒ Time
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/easy_time/convert.rb', line 44 def convert(arg, coerce = true) case arg when String parse_string(arg) # parse the string value into an EasyTime object when Array ::Time.new(*arg) # convert Time arguments: [yyyy, mm, dd, hh, MM, SS] when ::EasyTime arg.time # extract the EasyTime value when ActiveSupport::TimeWithZone arg.to_time # convert the TimeWithZone value to a Time object when ActiveSupport::Duration coerce ? Time.now + arg : arg # coerced duration objects are relative to "now" when ::Time arg # accept Time objects as-as when ::Date, ::DateTime ::Time.iso8601(arg.iso8601) # convert Date and DateTime objects via ISO8601 formatting when NilClass ::Time.now # a nil object means "now" when Numeric coerce ? Time.at(arg) : arg # if coerced, treat as seconds-since-Epoch else raise ArgumentError, "EasyTime: unknown value: '#{arg.inspect}'" end end |
.is_a_time?(value) ⇒ Boolean
Returns true if value is one the known Time classes, or responds to :acts_like_time?.
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/easy_time.rb', line 230 def is_a_time?(value) case value when Integer, ActiveSupport::Duration false when Date, Time, DateTime, ActiveSupport::TimeWithZone, EasyTime true else value.respond_to?(:acts_like_time?) && value.acts_like_time? end end |
.method_missing(symbol, *args, &block) ⇒ Object
215 216 217 218 219 220 221 222 |
# File 'lib/easy_time.rb', line 215 def method_missing(symbol, *args, &block) if Time.respond_to?(symbol) value = Time.send(symbol, *args, &block) is_a_time?(value) ? new(value) : value else super(symbol, *args, &block) end end |
.newer?(time1, time2, tolerance: nil) ⇒ Boolean
Returns true if time1
> time2
, using a tolerant comparison.
119 120 121 |
# File 'lib/easy_time.rb', line 119 def newer?(time1, time2, tolerance: nil) compare(time1, time2, tolerance: tolerance).positive? end |
.older?(time1, time2, tolerance: nil) ⇒ Boolean
Returns true if time1
> time2
, using a tolerant comparison.
128 129 130 |
# File 'lib/easy_time.rb', line 128 def older?(time1, time2, tolerance: nil) compare(time1, time2, tolerance: tolerance).negative? end |
.parse(time_string) ⇒ EasyTime
211 212 213 |
# File 'lib/easy_time.rb', line 211 def parse(time_string) new(parse_string(time_string)) end |
.respond_to_missing?(symbol, include_all = false) ⇒ Boolean
224 225 226 |
# File 'lib/easy_time.rb', line 224 def respond_to_missing?(symbol, include_all=false) Time.respond_to?(symbol, include_all) end |
.same?(time1, time2, tolerance: nil) ⇒ Boolean
Returns true if time1
> time2
, using a tolerant comparison.
137 138 139 |
# File 'lib/easy_time.rb', line 137 def same?(time1, time2, tolerance: nil) compare(time1, time2, tolerance: tolerance).zero? end |
.subtract(time, time_or_duration) ⇒ EasyTime, Duration
Returns an EasyTime
value, when a duration is subtracted from a time, or
a duration (Integer) value, when one time is subtracted from another time.
191 192 193 |
# File 'lib/easy_time.rb', line 191 def subtract(time, time_or_duration) EasyTime.new(time) - time_or_duration end |
.time_format_style(str) ⇒ Object
this method returns parser class methods in the Time class for corresponding time format patterns
139 140 141 142 143 144 145 146 |
# File 'lib/easy_time/convert.rb', line 139 def time_format_style(str) case str when RFC2822_RE then :rfc2822 when HTTPDATE_RE then :httpdate when XMLSCHEMA_RE then :xmlschema when ISO8601_RE then :iso8601 end end |
Instance Method Details
#+(duration) ⇒ EasyTime
Returns updated date and time value.
353 354 355 |
# File 'lib/easy_time.rb', line 353 def +(duration) dup.tap { |eztime| eztime.time += duration } end |
#-(other) ⇒ EasyTime, Integer
Subtract a value from an EasyTime. If the value is an integer, it is treated as seconds. If the value is any of the Date, DateTime, Time, EasyTime, or a String- formatted date/time, it is subtracted from the EasyTime value resulting in an integer duration.
364 365 366 367 368 369 370 371 |
# File 'lib/easy_time.rb', line 364 def -(other) @other_time = convert(other, false) if is_a_time?(other_time) time - other_time elsif other_time dup.tap { |eztime| eztime.time -= other_time } end end |
#<=>(other) ⇒ Integer
compare with automatic type-conversion and tolerance
320 321 322 323 324 325 326 327 |
# File 'lib/easy_time.rb', line 320 def <=>(other) diff = self - other # note: this has a side-effect of setting @other_time if diff && diff.to_i.abs <= comparison_tolerance.to_i 0 elsif diff time <=> other_time end end |
#acts_like_time? ⇒ Boolean
373 374 375 |
# File 'lib/easy_time.rb', line 373 def acts_like_time? true end |
#between?(t_min, t_max, tolerance: nil) ⇒ Boolean #between?(time_range, tolerance: nil) ⇒ Boolean
compare a time against a min and max date pair, or against a time Range value.
341 342 343 344 345 346 347 348 349 |
# File 'lib/easy_time.rb', line 341 def between?(t_arg, t_max = nil) if t_arg.is_a?(Range) t_min = t_arg.min t_max = t_arg.max else t_min = t_arg end compare(t_min) >= 0 && compare(t_max) <= 0 end |
#compare(time2, tolerance: nil) ⇒ Integer
Returns one of the values: [-1, 0, 1] if self
[<, ==, >] time2
,
or nil if time2
cannot be converted to a Time
value.
312 313 314 315 |
# File 'lib/easy_time.rb', line 312 def compare(time2, tolerance: nil) self.comparison_tolerance = tolerance if tolerance self <=> time2 end |
#different?(time2) ⇒ Boolean
Returns true if self
!= time2
.
304 305 306 |
# File 'lib/easy_time.rb', line 304 def different?(time2) self != time2 end |
#newer?(time2) ⇒ Boolean
Returns true if self
> time2
.
282 283 284 |
# File 'lib/easy_time.rb', line 282 def newer?(time2) self > time2 end |
#older?(time2) ⇒ Boolean
Returns true if self
< time2
.
289 290 291 |
# File 'lib/easy_time.rb', line 289 def older?(time2) self < time2 end |
#same?(time2) ⇒ Boolean Also known as: eql?
Returns true if self
== time2
.
296 297 298 |
# File 'lib/easy_time.rb', line 296 def same?(time2) self == time2 end |
#with_tolerance(value) ⇒ EasyTime
returns a new EasyTime value with the tolerance set to value
268 269 270 |
# File 'lib/easy_time.rb', line 268 def with_tolerance(value) dup.tap { |time| time.comparison_tolerance = value } end |