Narrowing a years and months duration

Copy Markdown View Source

Narrowing › years and months duration. The names in the examples are those of section 2.

A years and months duration alternative is the bare kind or {:years_and_months_duration, set}: a Feel.Type.NumberSet of the image of the values, their number of months (Feel.Type.Image, D-109). The image is one-to-one and keeps the order, so a comparison is read as a number's is. A years and months duration is a different kind from a days and time duration: they are never compared, and there is no duration that holds both.

Comparisons

Conditionym when trueym when not true
ym < @"P1Y"years and months duration in [-max..P1Y)years and months duration in [P1Y..max] | Null
ym > @"P0M"years and months duration in (P0M..max]years and months duration in [-max..P0M] | Null
ym = @"P6M"years and months duration = P6Myears and months duration in [-max..P6M), (P6M..max] | Null
ym < dd—years and months duration | Null
ym = ddNullyears and months duration | Null
ym instance of years and months durationyears and months durationNull
ym instance of days and time duration—years and months duration | Null

ym < dd compares kinds with no order between them, so it is never true; ym = dd is true only when both are null. The null rules are those of every kind (the rule).

Properties

years and months (Table 67) are worked out from the magnitude of the amount, m months, and take its sign: years is m div 12 and months is m rem 12. value is the amount itself. A fact about a property is a fact about the duration: the amounts whose property is what the fact leaves (D-194).

The years leave one interval, in a row; the months come back every year and leave a piece for each. So a fact about years or value is exact, and one about months narrows only a bounded set:

Conditionym when trueym when not true
ym.years >= 2years and months duration in [P2Y..max]years and months duration in [-max..P1Y11M] | Null
ym.years = 0years and months duration in [-P11M..P11M]years and months duration in [-max..-P1Y], [P1Y..max] | Null
ym.years < 0years and months duration in [-max..-P1Y]years and months duration in [-P11M..max] | Null
ym.value > 12years and months duration in (P1Y..max]years and months duration in [-max..P1Y] | Null
ym.months = 3years and months durationyears and months duration | Null
ym.years = 1 and ym.months = 6years and months duration = P1Y6Myears and months duration | Null

ym.years = 0 is symmetric because the sign is put back: eleven months either way. ym.months = 3 on an unbounded value would need a piece for every year.

With allowed values the set is bounded, and the months have pieces to keep (yms is in [P0M..P5Y]):

Conditionyms when trueyms when not true
yms > @"P1Y"years and months duration in (P1Y..P5Y]years and months duration in [P0M..P1Y] | Null
yms.years >= 2years and months duration in [P2Y..P5Y]years and months duration in [P0M..P1Y11M] | Null
yms.value >= 24years and months duration in [P2Y..P5Y]years and months duration in [P0M..P2Y) | Null
yms.months = 3years and months duration in P3M, P1Y3M, P2Y3M, P3Y3M, P4Y3Myears and months duration in [P0M..P2M], [P4M..P1Y2M], [P1Y4M..P2Y2M], [P2Y4M..P3Y2M], [P3Y4M..P4Y2M], [P4Y4M..P5Y] | Null
yms.years = 1 and yms.months = 6years and months duration = P1Y6Myears and months duration in [P0M..P5Y] | Null

yms.months = 3 is five single months, one in each year of the set. The else of a conjunction is the whole set, since only one side's facts are certain there (and and or).

Arithmetic in a comparison

Two years and months durations add and subtract exactly, and the months do not overflow, so a sum or a difference in a comparison narrows the operand by the preimage of the images, as for numbers (number). A years and months duration multiplied or divided by a number is rounded (D-54), so its months are not a product of images: Feel.Analysis.MonthScaling (D-109) works out the set as the run rounds it.

Conditionym when trueym when not true
ym + @"P1M" > @"P1Y"years and months duration in [P1Y..max]years and months duration in [-max..P11M] | Null
ym - @"P1M" <= @"P2Y"years and months duration in [-max..P2Y1M]years and months duration in [P2Y2M..max] | Null
@"P5Y" - ym < @"P1Y"years and months duration in [P4Y1M..max]years and months duration in [-max..P4Y] | Null
-ym > @"P1Y"years and months duration in [-max..-P1Y)years and months duration in [-P1Y..max] | Null

As everywhere, the else branch of an operation is read where the operation cannot be null for the operand.

One value read twice

Full analysis recognizes repeated reads of a name or supported member (D-170, D-207). Subtraction gives zero months. Self-division gives one when the month count is nonzero and its magnitude is less than 10^34; zero and larger magnitudes give null, the latter because runtime numeric conversion fails. Null input also gives null. These failures are still possible even for a non-null duration.

ExpressionTypeWarnings
ym - ymyears and months duration = P0M | Null—
ym / ymnumber = 1 | Null—
yms / ymsnumber = 1 | Null—

The core analysis 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 (months of a range of 12 months or more has every value of a remainder).
  • A bound of more than 34 digits is the end of the range of numbers.
  • A multiplication or division by a number gives sets with large ends, because the amounts are as large as a number goes.
  • Repeated addition still sums independent intervals. If a duration is either one or six months, ym + ym has a type containing seven months, although only two or twelve months can be returned.

See also: days and time duration, date, number.