|
| 1 | +# Ranges |
| 2 | + |
| 3 | +Services often need to represent ranges of discrete or continuous values. These |
| 4 | +have wide differences in meaning, and come in many types: integers, floats, and |
| 5 | +timestamps, just to name a few, and the expected meaning of a range can vary in |
| 6 | +subtle ways depending on the type of range being discussed. |
| 7 | + |
| 8 | +## Guidance |
| 9 | + |
| 10 | +A resource or message representing a range **should** ordinarily use two |
| 11 | +separate fields of the same type, with prefixes `start_` and `end_`: |
| 12 | + |
| 13 | +```typescript |
| 14 | +// A representation of a chapter in a book. |
| 15 | +interface Chapter { |
| 16 | + title: string; |
| 17 | + |
| 18 | + // The page where this chapter begins. |
| 19 | + startPage: number; |
| 20 | + |
| 21 | + // The page where the next chapter or section begins. |
| 22 | + endPage: number; |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +### Inclusive or exclusive ranges |
| 27 | + |
| 28 | +Fields representing ranges **should** use inclusive start values and exclusive |
| 29 | +end values (half-closed intervals) in most situations; in interval notation: |
| 30 | +`[start_xxx, end_xxx)`. |
| 31 | + |
| 32 | +Exclusive end values are preferable for the following reasons: |
| 33 | + |
| 34 | +- It conforms to user expectations, particularly for continuous values such as |
| 35 | + timestamps, and avoids the need to express imprecise "limit values" (e.g. |
| 36 | + `2012-04-20T23:59:59`). |
| 37 | +- It is consistent with most common programming languages, including C++, Java, |
| 38 | + Python, and Go. |
| 39 | +- It is easier to reason about abutting ranges: `[0, x), [x, y), [y, z)`, where |
| 40 | + values are chainable from one range to the next. |
| 41 | + |
| 42 | +### Exceptions |
| 43 | + |
| 44 | +In some cases, there is significant colloquial precedent for inclusive start |
| 45 | +and end values (closed intervals), to the point that using an exclusive end |
| 46 | +value would be confusing even for people accustomed to them. |
| 47 | + |
| 48 | +For example, when discussing dates (not to be confused with timestamps), most |
| 49 | +people use inclusive end: a conference with dates "April 21-23" is expected to |
| 50 | +run for three days: April 21, April 22, and April 23. This is also true for |
| 51 | +days of the week: a business that is open "Monday through Friday" is open, not |
| 52 | +closed, on Fridays. |
| 53 | + |
| 54 | +In this situation, the prefixes `first` and `last` **should** be used instead: |
| 55 | + |
| 56 | +```typescript |
| 57 | +// A representation of a chapter in a book. |
| 58 | +interface Chapter { |
| 59 | + title: string; |
| 60 | + |
| 61 | + // The first page of the chapter. |
| 62 | + firstPage: number; |
| 63 | + |
| 64 | + // The last page of the chapter. |
| 65 | + lastPage: number; |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +Fields representing ranges with significant colloquial precedent for inclusive |
| 70 | +start and end values **should** use inclusive end values with `first_` and |
| 71 | +`last_` prefixes for those ranges only. The service **should** still use |
| 72 | +exclusive end values for other ranges where this does not apply, and **must** |
| 73 | +clearly document each range as inclusive or exclusive. |
0 commit comments