///|
fn locator_gcd(left : Int32, right : Int32) -> Int32 {
for a = left, b = right; b != 0; {
continue b, a % b
} nobreak {
a
}
}
///|
fn time_ticks(
locator : DateLocator,
first_ordinal : Double,
last_ordinal : Double,
first : DateTime,
last : DateTime,
anchor : DateTime,
unit : Int32,
fields : Int32,
) -> Array[Double] {
let unit64 = Int64::from_int(unit)
let step = Int64::from_int(locator.interval)
let first_unit = locator_floor_div64(locator_seconds(first), unit64)
let last_unit = locator_floor_div64(locator_seconds(last), unit64)
let anchor_unit = locator_floor_div64(locator_seconds(anchor), unit64)
let start = locator_align(first_unit, anchor_unit, step)
// A selector repeats after at most 24 or 60 recurrence steps. Precompute
// reachable fields so sparse or impossible filters never scan entire years
// second by second, and so the tick cap counts output, not skipped candidates.
let period = match locator.selection {
None => 1
Some(_) => fields / locator_gcd(locator.interval, fields)
}
let offsets : Array[Int64] = []
for index in 0.. last_unit || result.length() >= 100000 {
break
}
for
ordinal in locator.ordinals_for_date(
locator_datetime(current * unit64, locator.offset_minutes),
) {
locator_push_tick(result, ordinal, first_ordinal, last_ordinal)
}
}
}
result
}