Module: CATimeCivil
- Defined in:
- lib/carray/time.rb
Overview
Internal: unit-conversion algebra shared by CATime / CATimedelta (used by to_comparable to align a search query to the reference unit).
The units split into two groups that are NOT inter-convertible by a fixed ratio: fixed-length (W/D/h/m/s/ms/.../as, ratios in seconds) and calendar (Y/M, ratio in months -- W and below are calendar-dependent in days). Within a group any pair is an exact integer ratio (coarse = fine * N), so a coarse->fine cast is lossless (multiply), and a fine->coarse cast is lossless only when every value is divisible by the divisor. Civil-date arithmetic on int64 CArrays: the calendar kernel every time grid is built on (Howard Hinnant's days<->civil algorithms, vectorized). Internal to the time surface: nothing here is part of the public API.
Class Method Summary collapse
-
.civil_from_days(z) ⇒ Object
Vectorized Howard Hinnant civil-date algebra (proleptic Gregorian, negative days supported).
-
.days_from_civil(y, m, d) ⇒ Object
[year, month, day] int64 CArrays -> days since the Unix epoch.
-
.days_from_civil_1(y, m, d) ⇒ Object
Same algebra for one date, on plain Integers.
Class Method Details
.civil_from_days(z) ⇒ Object
Vectorized Howard Hinnant civil-date algebra (proleptic Gregorian,
negative days supported). days since the Unix epoch -> [year, month,
day] int64 CArrays. The algorithm needs the era to floor toward the
past, which CArray / does; Hinnant's published form pre-biases the
negative operand instead because C truncates.
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/carray/time.rb', line 36 def civil_from_days(z) z = z + 719468 era = z / 146097 doe = z - era * 146097 yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 y = yoe + era * 400 doy = doe - (365 * yoe + yoe / 4 - yoe / 100) mp = (5 * doy + 2) / 153 d = doy - (153 * mp + 2) / 5 + 1 # day of month, 1..31 m = mp + (3 - 12 * mp.ge(10)) # mp<10 ? +3 : -9 [y + m.le(2), m, d] end |
.days_from_civil(y, m, d) ⇒ Object
[year, month, day] int64 CArrays -> days since the Unix epoch.
50 51 52 53 54 55 56 57 |
# File 'lib/carray/time.rb', line 50 def days_from_civil(y, m, d) y = y - m.le(2) era = y / 400 yoe = y - era * 400 doy = (153 * (m + (9 - 12 * m.gt(2))) + 2) / 5 + (d - 1) # m>2 ? -3 : +9 doe = yoe * 365 + yoe / 4 - yoe / 100 + doy era * 146097 + doe - 719468 end |
.days_from_civil_1(y, m, d) ⇒ Object
Same algebra for one date, on plain Integers. A literal is parsed one
at a time, and routing each one through the vectorized form costs a
one-cell CArray and a kernel call per literal -- which is where nearly
all the time in a bulk column parse used to go (170k rows: 3.5 s, of
which 3.1 s was this). Ruby's Integer / floors, as CArray's does,
so the two forms read alike and agree everywhere.
65 66 67 68 69 70 71 72 |
# File 'lib/carray/time.rb', line 65 def days_from_civil_1 (y, m, d) y -= 1 if m <= 2 era = y / 400 yoe = y - era * 400 doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + (d - 1) doe = yoe * 365 + yoe / 4 - yoe / 100 + doy era * 146097 + doe - 719468 end |