Narrowing a days and time duration

Copy Markdown View Source

Narrowing › days and time duration. The names in the examples are those of section 2.

A days and time duration alternative is the bare kind or {:days_and_time_duration, set}: a Feel.Type.NumberSet of the image of the values, their number of seconds, with a fraction (Feel.Type.Image, D-109). The image is one-to-one and keeps the order, and for a duration it keeps the operations too: the image of a + b is the sum of the images, and of a * n the image of a times n. A days and time duration is a different kind from a years and months duration, and they are never compared.

Comparisons

Conditiondd when truedd when not true
dd < @"PT1H"days and time duration in [-max..PT1H)days and time duration in [PT1H..max] | Null
dd >= @"P1D"days and time duration in [P1D..max]days and time duration in [-max..P1D) | Null
dd > @"PT0S"days and time duration in (PT0S..max]days and time duration in [-max..PT0S] | Null
dd = @"PT0S"days and time duration = PT0Sdays and time duration in [-max..PT0S), (PT0S..max] | Null
dd between @"PT1H" and @"PT2H"days and time duration in [PT1H..PT2H]days and time duration in [-max..PT1H), (PT2H..max] | Null
dd < ym—days and time duration | Null
dd instance of days and time durationdays and time durationNull
dd instance of years and months duration—days and time duration | Null

The null rules are those of every kind (the rule). dd < ym is never true: the kinds have no order between them.

Properties

The components (Table 67) are worked out from the magnitude of the amount and take its sign, as Feel.Runtime.Path does:

PropertyOf a magnitude m seconds
daysthe whole days: w div 86400, where w is the whole seconds of m
hoursthe whole hours of what is left in a day: (w rem 86400) div 3600
minutesthe whole minutes of what is left in an hour: (w rem 3600) div 60
secondsm modulo 60, with the fraction
valuethe amount itself

A fact about a property is a fact about the duration (D-194): the amounts whose component is what the fact leaves. The days and the value are in a row and leave one interval; the hours, minutes and seconds come back every day, hour or minute, and leave a piece for each. So days and value are exact on any set, and the others need a bounded one:

Conditiondd when truedd when not true
dd.days = 0days and time duration in (-P1D..P1D)days and time duration in [-max..-P1D], [P1D..max] | Null
dd.days > 1days and time duration in [P2D..max]days and time duration in [-max..P2D) | Null
dd.days < 0days and time duration in [-max..-P1D]days and time duration in (-P1D..max] | Null
dd.value > 3600days and time duration in (PT1H..max]days and time duration in [-max..PT1H] | Null
dd.days >= 1 and dd.hours = 0days and time duration in [P1D..max]days and time duration | Null
dd.hours >= 18days and time durationdays and time duration | Null
dd.seconds = 30days and time durationdays and time duration | Null

dd.days = 0 is symmetric around zero because the sign is put back. dd.days >= 1 and dd.hours = 0 keeps the days and drops the hours: the hours would need a piece for each day of an unbounded set.

With allowed values the set is bounded and the components have pieces to keep (dds is in [PT0S..P3D]):

Conditiondds when truedds when not true
dds > @"PT1H"days and time duration in (PT1H..P3D]days and time duration in [PT0S..PT1H] | Null
dds >= @"P1D" and dds < @"P2D"days and time duration in [P1D..P2D)days and time duration in [PT0S..P1D), [P2D..P3D] | Null
dds.days = 1days and time duration in [P1D..P2D)days and time duration in [PT0S..P1D), [P2D..P3D] | Null
dds.hours >= 18days and time duration in [PT18H..P1D), [P1DT18H..P2D), [P2DT18H..P3D)days and time duration in [PT0S..PT18H), [P1D..P1DT18H), [P2D..P2DT18H), P3D | Null
dds.hours = 5days and time duration in [PT5H..PT6H), [P1DT5H..P1DT6H), [P2DT5H..P2DT6H)days and time duration in [PT0S..PT5H), [PT6H..P1DT5H), [P1DT6H..P2DT5H), [P2DT6H..P3D] | Null
dds.days >= 1 and dds.hours < 6days and time duration in [P1D..P1DT6H), [P2D..P2DT6H), P3Ddays and time duration in [PT0S..P3D] | Null
dds.minutes = 30days and time duration in [PT30M..P3D]days and time duration in [PT0S..P3D] | Null
  • A piece for each day is what dds.hours >= 18 leaves, and the exact set is a union of three intervals. P3D on its own is the one amount of the last day that is not below the end.
  • dds.minutes = 30 has a piece for each hour, which is more than 16 for three days: the set is the hull, from the first half hour to the end, a superset.
  • The second row of the table is the and of two comparisons of the value, which meet exactly.

Arithmetic in a comparison

A days and time duration is added, subtracted, multiplied and divided by a number as a number is, so an operation in a comparison narrows the operand by the preimage (number):

Conditiondd when truedd when not true
dd + @"PT1H" > @"PT3H"days and time duration in (PT2H..max]days and time duration in [-max..PT2H0.000000000000000000000000000005S] | Null
dd + @"PT1H" = @"PT2H"days and time duration = PT1Hdays and time duration in [-max..PT1H), (PT1H..max] | Null
dd - @"PT1H" >= @"PT0S"days and time duration in [PT1H..max]days and time duration in [-max..PT1H) | Null
@"P1D" - dd > @"PT1H"days and time duration in [-max..PT23H)days and time duration in [PT23H..max] | Null
dd * 2 < @"PT1H"days and time duration in [-max..PT30M)days and time duration in [-max..-PT4.999999999999999999999999999999999E+6144S], [PT30M..max] | Null
dd / 2 > @"PT1H"days and time duration in (PT2H..max]days and time duration in [-max..PT2H0.000000000000000000000000000001S] | Null
-dd < @"PT1H"days and time duration in (-PT1H..max]days and time duration in [-max..-PT1H] | Null
dd * x > @"PT1H"days and time duration in [-max..PT0S), (PT0S..max]days and time duration | Null
Conditionx when truex when not true
@"PT1H" * x > @"PT2H"number in (2..max]number in [-max..2], [2.777777777777777777777777777777777E+6141..max] | Null
dd * x > @"PT1H"number in [-max..0), (0..max]number | Null

The number that multiplies is narrowed too (@"PT1H" * x > @"PT2H" needs x above 2). dd * x > @"PT1H" cannot be true for a zero in either operand, so both lose it.

The else is read as it is for numbers (number): the durations the comparison is false for, and those for which the operation is null (Feel.Analysis.Failure, the seconds being a number). A sum with a constant cannot be (dd + @"PT1H" > … has no more than the first), a product or a quotient can: dd * 2 < @"PT1H" is not true of a duration of more than half of the largest number of seconds, for which the product is null. A duration of 10^30 seconds or more is written as its seconds, in scientific notation (PT4.999999999999999999999999999999999E+6144S), and not as thousands of digits of days. A duration next to a duration or a number that is not known is null for some (and every) duration, and the else says nothing of it.

The types of the arithmetic itself are Feel.Analysis.Inference's:

ExpressionTypeWarnings
dd + @"PT1H"days and time duration | Null—
dds + @"PT1H"days and time duration in [PT1H..P3DT1H] | Null—
dds * 2days and time duration in [PT0S..P6D] | Null—
dd - dddays and time duration = PT0S | Null—
dd / ddnumber = 1 | Null—

Full analysis recognizes the repeated read in the last two rows (D-170, D-207). A non-null duration subtracts from itself to zero; it divides by itself to one unless it is zero, which gives null. The core tier keeps independent-operand types for repeated reads.

Limits

  • A set of more than 16 pieces is replaced by the one interval that holds them all.
  • A property of an unbounded set (dd.hours, dd.minutes, dd.seconds) says nothing: every value of the remainder is in a long enough interval (hours in a day, minutes in an hour).
  • The amounts are as fine as a number goes, so the ends of a duration have up to 34 digits.
  • Repeated addition still sums independent intervals. If a duration is either one or six seconds, dd + dd has a type containing seven seconds, although only two or twelve seconds can be returned.

See also: years and months duration, date and time, number.