Problem – Quantitizing Values
An attribute's value may be assigned either as the result of a measurement, a calculation, or both. Performing addition, subtraction, multiplication, and division operations may yield meaningless results depending of the type of phenomenon being measured. This is particularly true for performing arithmetic operations involving space, time, or currency. Measuring the time between two dates results in a different unit of measure, such as days. Furthermore, calculations between two points in time may be subject to business rule driven approximation. For example, a business week may define the measurement between 9:00 AM on Monday, February 2, 1998 and 5:00 PM on Friday, February 7, 1998 as five days or forty hours. Measuring the distance between two points also results in a value represented by a different unit of measure that again may be an approximation. Consider the number posted on exit signs on the U.S. interstate highway system. This number represents an approximation of the number of miles from the origin point of the highway along the road's surface.
Arithmetic operation involving currency pose similar problems. Although currency may be added and subtracted to yield a value that is represented by the same unit of measure, division produces a result that does not. If a vending machine contains $.80 items and the patron has $2.00, the quantity of items purchased is 2, since the machine does not allow the purchase of half an item.
Solution
The basic strategy that can be applied to quantitizing values is to simply perform the arithmetic operation and then round the result according to a set of parameters. The first parameter specifies a method by applying the Domain rule pattern. For example, in most cases declaring a rounding method type to be the floor, ceiling, or nearest value. The other parameters specify the interval between values, the unit of measure, and the origin point. In many cases global default parameters may be specified and then overridden for the last two. For example, all time extents default to measurement in years and the origin point defaults to 0 for all extents.
When business rules dictate intermediate rounding rule because of a series of calculations, additional parameters may be required to fully specify the quantitizing process. For example, 1.4444444445 represents a number with ten digits of precision after the decimal point. Rounding this to the nearest integer seems straightforward, resulting in a value of 1. However, the result changes to a value of 2 if intermediate rounding rules progressively round the value to one less decimal point of precision.
Additional problems with intermediate rounding may result when operations are reversed. For example, dividing $ 1.00 by 3 results in a value of $ 0.33 rounded to two decimal points. Multiplying by three yields a $ 0.99 value rounded to two decimal points, which may not produce the desired result. Therefore, constraints on intermediate rounding may be required to avoid this situation. This represents dependency of one parameter on another. Specifically, an intermediate rounding must contain sufficient decimal precision to accommodate all multiplication operations within a valid domain range for the value. This can be accomplished by applying the Domain business rule pattern to establish a minimum and maximum value for the attribute and accommodating the decimal precision as a function of the differences in scale between the minimum value and the maximum value. However, this represents the worst case scenario. A more pragmatic approach is to only consider the minimum value for the attribute in its current state, but this represents additional parameterization that may be unnecessary.
Dates and calendars warrant special considerations. In additional to rounding rules that are applied to the values that between two points in time, the points in time themselves may need adjustment. The point may be adjusted to the beginning of the day, the first day of the month coincident with or in the following month, or the end of the year to address specific calculation needs.
Example – Employment Service
This example demonstrates how adjustment methods play a role in calculating the value for an interval. It also shows how the selection of one parameter carries with it the inclusion of another parameter and how a single parameter is used to abstract the usage and specification of a pair of complementary parameters.
The employment service calculation below assumes that an employee begins employment on the first work day of the calendar year and terminates on the last day of work in the same year. Company policy stipulates that an employee is entitled to one week of vacation after completing one year of service. Other benefits, such as insurance coverage eligibility, continue through the last day of the following calendar quarter.
This example involves defining a calendar that identifies the work days and nonwork days, including holidays. The calendar may be logically represented as a list of dates and associated Boolean value that is set to true for workdays. This calendar is used in an adjustment that calculates service for each year. A pair of datetime adjustment methods called earliestNonworkingDayInMonth and lastestNonworkingDayInMonth is used. They are complementary methods specified by a single parameter. The algorithm for the first is shown below.
The calendar most likely will be established as the default calendar, so it would not be necessary to specify it for each application of the Interval pattern which required referencing it. Without the adjustment method and related calendar, the result would be 0.997 years.
Algorithm:
Function datetime earliestNonworkingDayInMonth( datetime aDatetime, calendar aCalendar ) { while ( ! aCalendar.isWorkDay( getCalendarDate( dateAdd( aDatetime, 1 ) ) ) && dayOfMonth( aDatetime ) != 1 { aDatetime = dateAdd( aDatetime, 1 ) } return beginningOfDay( aDatetime ) }Parameters:
PeriodAdjustment  IncludeNonworkingDayInMonth  
UnitOfMeasure  Years  
Rounding  Floor  
DecimalPrecision  3  
Calendar 

Case:
Input  Start  2Jan1997 
End  31Dec1997  
After Adjustment  Start  1Jan1997 00:00:0000 
End  1Jan1998 00:00:0000  
Output  1.000 years 
The designation of (1/1/98 00:00:0000) as the end of the month of December has subtle implications regarding its treatment in other business rules, such as the insurance benefits. Points in time are dimensionless. Therefore, this representation does not imply any time worked in the subsequent year, which would change the cutoff of insurance coverage eligibility in this example from Mach 31 to June 30. The interpretation of (1/1/98 00:00:0000) depends on its context. In this context, it represents a point in time. In another context, it may represent shorthand notation for the 1/10000 of a second interval between (1/1/98 00:00:0000) and (1/1/98 00:00:0001).
Other period adjustment types would require their own collateral parameter. For example, a thirtyday month adjustment may apply, such that 2/7/97 to 3/6/97, 5/1/97 to 5/30/97, 1/21/97 to 2/19/97 and 2/1/97 to 2/28/97 all represent one month. This adjustment disregards the number of days in any month when the corresponding point in time in the following month is considered, but recognized as a full month from the first to the thirtieth for those months containing thirtyone days. Thus, although this example utilized an actual calendar basis, other basis types are possible and may be specified with a parameter if needed.
A gas station pump displays gallons dispensed to decimal places of precision. Mileage is recorded between fillups based on a digital odometer that registers miles traveled to one decimal place. Each of these three values already represents a rounding method of type floor, however the purpose of this example is to illustrate the origin and interval parameters. With the inclusion of an intermediate rounding method for mileage, this calculation chains together two approximations.
UnitOfMeasure  Miles 
Rounding  Nearest 
Interval  10 
Origin  0 
DecimalPrecision  0 
Case:
Input  Start  42134.3 miles 
End  42411.1 miles  
After Calculation  276.8  
Output  280 miles 
Parameters:
UnitOfMeasure  Miles per gallon 
Rounding  Floor 
DecimalPrecision  0 
Case:
Input  280 miles / 12.24 gallons 
After Calculation  22.875 
Output  22 miles per gallon 
The Interval business rule pattern is specialized based of the nature of the measurement. The two types described in the examples are shown as the NumericInterval and PeriodInterval model elements.
This pattern shares similar concepts to the Weisert's PointExtent Pattern [Weis97] and Fowler's Schedule pattern [Fowl97]. The PointExtent Pattern is an implementation level pattern that addresses operator overloading. The Schedule pattern addresses the handing of recurring events for calendars. The Domain business rule pattern may be integrated to define the domains for each enumerated attributed and for defining minimum and maximum values for decimal precision to avoid loss of precision that may occur when chaining this pattern for determining intermediate values.