Class: CATime::Element
- Inherits:
-
Object
- Object
- CATime::Element
- Includes:
- Comparable
- Defined in:
- lib/carray/time.rb
Overview
Element-return class: a single time element carries both its int64 count and its resolution, so scalar access (ca[i,j]) round-trips through this rather than a bare Integer.
Constant Summary collapse
- EPOCH_JD =
storage + value/unit accessors + initialize are C-implemented in ext/ca_obj_datetime.c (= TypedData_Make_Struct fast path). Methods below are Ruby-side; they call value/unit which are C accessors.
Calendar breakdown is delegated to Ruby Date / Time (the scalar pays one object's cost, unlike the vectorized array accessors), but exactly: a :M / :Y value decodes through Date#next_month / #next_year (NOT the 30.5-day UNIT_TO_SECONDS approximation, which drifts), and a fixed-unit value through an exact Rational-second Time.at. All UTC.
2440588
Instance Method Summary collapse
-
#+(td) ⇒ CATime::Element
Returns this instant advanced by a CATimedelta::Element.
-
#-(other) ⇒ CATime::Element, CATimedelta::Element
Subtracting a CATimedelta::Element yields a Element (same rule as
+); subtracting another Element yields the elapsed duration as a CATimedelta::Element, in thediff_unitof the two (same group -> finer unit; cross-group -> the fixed unit). -
#<=>(other) ⇒ Object
Three-way compare by INSTANT, reconciling a different unit (both are brought to a common unit both reach exactly, via
diff_unit), so two datetimes are always ordered regardless of unit. -
#eql?(other) ⇒ Boolean
Hash-key identity is unit-strict (mirrors Ruby: 1 == 1.0 but not 1.eql?(1.0)), so a :s and a :ms scalar at the same instant compare
==yet key a Hash separately. -
#hash ⇒ Integer
A hash consistent with #eql? (unit-strict).
-
#inspect ⇒ String
The instant plus its storage unit.
-
#to_date ⇒ Date
The date this scalar denotes (UTC).
-
#to_datetime ⇒ DateTime
The instant this scalar denotes (UTC).
-
#to_s ⇒ String
Unit-aware string: coarse units print at their own granularity so the
(value, unit)pair stays recoverable (a :M scalar is "2024-03", not "2024-03-01T00:00:00Z", which is indistinguishable from a :D). -
#to_time ⇒ Time
The instant this scalar denotes (UTC).
Instance Method Details
#+(td) ⇒ CATime::Element
420 421 422 |
# File 'lib/carray/time.rb', line 420 def +(td) _combine(td, 1) end |
#-(other) ⇒ CATime::Element, CATimedelta::Element
431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/carray/time.rb', line 431 def -(other) case other when Element u = CATimeUnitAlgebra.diff_unit(unit, other.unit) CATimedelta::Element.new(_instant_in(u) - other.send(:_instant_in, u), u) when CATimedelta::Element _combine(other, -1) else raise TypeError, "CATime::Element - #{other.class} is not allowed" end end |
#<=>(other) ⇒ Object
Three-way compare by INSTANT, reconciling a different unit (both are
brought to a common unit both reach exactly, via diff_unit), so two
datetimes are always ordered regardless of unit. Returns nil for a
non-time operand (Time / DateTime are accepted); per the Comparable
contract that makes == false and < raise, so no explicit == is
defined (Comparable derives it: same instant -> equal, even cross-unit).
385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/carray/time.rb', line 385 def <=>(other) case other when Element u = CATimeUnitAlgebra.diff_unit(unit, other.unit) _instant_in(u) <=> other._instant_in(u) when Time to_time <=> other.getutc when (defined?(DateTime) ? DateTime : nil) to_time <=> other.to_time.getutc end rescue ArgumentError nil end |
#eql?(other) ⇒ Boolean
Hash-key identity is unit-strict (mirrors Ruby: 1 == 1.0 but not
1.eql?(1.0)), so a :s and a :ms scalar at the same instant compare ==
yet key a Hash separately.
402 403 404 |
# File 'lib/carray/time.rb', line 402 def eql?(other) other.is_a?(Element) && other.unit == unit && other.value == value end |
#hash ⇒ Integer
Returns a hash consistent with #eql? (unit-strict).
407 408 409 |
# File 'lib/carray/time.rb', line 407 def hash [value, unit].hash end |
#inspect ⇒ String
Returns the instant plus its storage unit.
374 375 376 377 |
# File 'lib/carray/time.rb', line 374 def inspect tag = unit.count == 1 ? "#{value}#{unit.base}" : "#{value} @ #{unit}" "#<CATime::Element #{to_s} (#{tag})>" end |
#to_date ⇒ Date
Returns the date this scalar denotes (UTC). A sub-day unit is floored to its day.
344 345 346 347 348 349 350 351 352 353 |
# File 'lib/carray/time.rb', line 344 def to_date require 'date' case unit.base when :Y then _epoch_date.next_year(value * unit.count) when :M then _epoch_date.next_month(value * unit.count) when :W then Date.jd(EPOCH_JD + value * unit.count * 7, Date::GREGORIAN) when :D then Date.jd(EPOCH_JD + value * unit.count, Date::GREGORIAN) else Date.jd(EPOCH_JD + _floor_days, Date::GREGORIAN) # sub-day: floor to day end end |
#to_datetime ⇒ DateTime
Returns the instant this scalar denotes (UTC).
356 357 358 |
# File 'lib/carray/time.rb', line 356 def to_datetime to_time.to_datetime end |
#to_s ⇒ String
Unit-aware string: coarse units print at their own granularity so the
(value, unit) pair stays recoverable (a :M scalar is "2024-03", not
"2024-03-01T00:00:00Z", which is indistinguishable from a :D).
364 365 366 367 368 369 370 371 |
# File 'lib/carray/time.rb', line 364 def to_s case unit.base when :Y then format("%04d", to_date.year) when :M then to_date.strftime("%Y-%m") when :W, :D then to_date.strftime("%Y-%m-%d") else to_time.iso8601(_precision_digits) # :h .. :as (time shown) end end |
#to_time ⇒ Time
Returns the instant this scalar denotes (UTC). For a calendar unit this is the first instant (midnight of day 1) of the granule.
331 332 333 334 335 336 337 338 339 340 |
# File 'lib/carray/time.rb', line 331 def to_time require 'time' require 'date' case unit.base when :Y then d = _epoch_date.next_year(value * unit.count); Time.utc(d.year, d.month, d.day) when :M then d = _epoch_date.next_month(value * unit.count); Time.utc(d.year, d.month, d.day) else Time.at(Rational(value) * unit.tick_ratio, in: 'UTC') # exact seconds end end |