Unit Formats
Unit Formats control the display and formatting of units for numeric values, such as time intervals, length or distance, mass or weight.
Understanding Unit Formats
Without a unit format, the numeric value displays the full name of the unit type. For example:
put 1 mm --> 1 millimeter
put 3 kg --> 3 kilograms
In many cases, the default behavior is perfectly fine, but there are other times when you need more control of formatting. For example:
put 4425 mins --> 4425 minutes
put 4425 mins as hrs --> 73.75 hours
put 4425 mins as days --> 3.072917 days
Without using a unit format, you can only display 4425 minutes as minutes, or
as hours, or
as days. A better format might be 3 days 1 hour 45 minutes, which is much easier to understand. To achieve this, you can apply either of the following formats:
"[day] days [hr] hours [min] minutes"
"[days] @ [hours] @ [minutes] @"
Elements of Unit Formats
Unit formats can range from simple to rather complex. The easiest way to understand them is to begin with the basics and add in other options as required.
The Basics
The most basic unit formats are text strings where one or more unit tokens, or unit names, are replaced by a number in the final result. You can use a singular or plural unit name, or even an abbreviation, and capitalization doesn't matter. The name just needs to identify a unit type. For example:
put 5 kg -->5 kilograms
put 5 kg with format "[KG] kg" --> 5 kg
put 5 kg with format "[Kilogram] kg" --> 5 kg
put 5 kg with format "[kilograms] kg" --> 5 kg
The "@" token requires more precise syntax. For full details, see Unit Names (@ tokens).
If more than one unit name is included in the unit format, SenseTalk works from left to right, replacing each token in turn with the whole number of units of that type that add up to the numeric value. In the following example, SenseTalk:
- Determines that 483 seconds is equal to 8.05 minutes.
- Replaces the
[min]
token with the whole number 8. - Allocates the remainder, 0.05 minutes or 3 seconds, to the next token.
put 483 secs format "[min] minutes [s] seconds" --> 8 minutes 3 seconds
The allocation of values from left to right means that the unit formatting system is only able to produce formatted values beginning with larger units followed by progressively smaller units.
Unit Names in Tokens
As mentioned earlier, the syntax that you use for unit tokens, or unit names, is flexible. You can include singular, or plural names, or even abbreviations. For example, you can write the unit token that represents hours as [hours]
or [hour]
or [hrs]
or [hr]
. The following unit format strings look slightly differently but apply the same formatting.
"[hr]:[min]:[sec]"
"[hours]:[minutes]:[seconds]"
...and result in
3 seconds --> 0:0:3
521957 seconds --> 144:59:17
Number Formats
Number formats let you control whether whole numbers or fractions, including the number of digits and decimal places, are displayed. In the following example, the dot in [seconds .]
allows the display of any fractions of a second:
"[hours]:[minutes]:[seconds .]"
...results in
63.6487 seconds --> 0:1:3.6487
You can only use the dot in the final unit token of the format. This is the remainder of the value after the rest has been allocated to the larger unit tokens, or types. The "." is equivalent to using a number format of 0.######
.
The .###
in [seconds .###]
displays fractions of a second up to three decimal places:
"[hours]:[minutes]:[seconds .###]"
...results in
63.6487 seconds --> 0:1:3.649
The 00
in [minutes 00]
displays two digits for this unit type, even if there are zero minutes. The 00.000
in [seconds 00]
displays two digits before, and three digits after the decimal place, to display fractions of a second or zeros:
"[hours]:[minutes 00]:[seconds 00.000]"
...results in
63.6487 seconds —> 0:01:03.649
2.4 seconds —> 0:00:02.400
You can only apply formatting for fractions to the final unit token of the format. This is the remainder of the value after the rest has been allocated to the larger unit tokens, or types.
You can also use the unitFormats global property to set the number format for one or more unit types.
Default Number Format
If the unit token does not include a number format, it defaults to 0
. To override this default for the current token and all subsequent tokens, use an asterisk (*
):
"[hours 00*]:[minutes]:[seconds]"
...sets the default number format to 00 and is equivalent to:
"[hours 00]:[minutes 00]:[seconds 00]"
Unit Names (@tokens)
The (@
) sign is a special token which appears after the unit name token within the unit format. When the format is applied, this special token is automatically replaced by the correct singular or plural form of the unit name:
"[hours] @ and [minutes] @"
...results in
347 minutes --> 5 hours and 47 minutes
12 minutes --> 0 hours and 12 minutes
60 minutes --> 1 hour and 0 minutes
Additionally, the unit name of the token in front of the (@
) sign is applied to the value, including any abbreviation or changes in capitalization:
"[hr] @ and [Minutes] @"
...results in
347 minutes --> 5 hrs and 47 Minutes
12 minutes --> 0 hrs and 12 Minutes
61 minutes --> 1 hr and 1 Minute
Conditional Segments
A question mark in a unit token indicates a conditional unit. This lets you suppress a unit if the value is zero. For example:
"[hours ?] @ [minutes?] @"
...results in
347 minutes --> 5 hours 47 minutes
12 minutes --> 12 minutes
60 minutes --> 1 hour
If this format was applied to a numeric value of less than a minute, both units would be suppressed, and the result would be an empty string.
If the value for a conditional unit is zero, the text following that unit is also suppressed:
"[hours?] grueling @ and [minutes] @"
...results in
347 minutes --> 5 grueling hours and 47 minutes
75 minutes --> 1 grueling hour and 15 minutes
12 minutes --> 12 minutes
To apply this format, the system breaks it down into segments, with one segment for each unit token:
[hours?] grueling @
[minutes] @
.
The question mark after hours
makes this segment conditional. If the number of hours is zero, the entire segment is left out.
Mutually Exclusive Alternative Formats
A vertical bar (|
) separates mutually exclusive formats. If the first format results in zero, the next is tried, and so on until a format is applied to a single unit type. For example:
"[miles] @|[yards] @|[feet] @|[inches] @"
...results in
72 inches --> 2 yards
24 inches --> 2 feet
8 inches --> 8 inches
If the unit format string in the example was applied to a numeric value of 43 inches, the following formats would be checked in turn:
[miles]
- 43 inches is less than one mile, so this segment is skipped.[yards]
- 43 inches is more than one yard, so this segment is used and the remaining segments,[feet]
and[inches]
, are ignored.
The result is 1 yard
.
Mutually exclusive formats are useful for displaying byte sizes. For example, to show a file size in the most appropriate unit:
"[GB? 0.#] @|[MB? 0.#] @|[KB? 0.#] @|[Byte] @"
...results in
3774875 bytes --> 3.6 MB
In this case, question marks are needed because the number formats include a decimal place. Without question marks, every value would display as GB even when it is less than 1 GB. With question marks, the numeric value must be at least 1 GB for that format to be applied.
Subsegments in Alternative Formats
To allow the formatting of more than one unit type, each alternative format can include subsegments. For example, the following unit format string contains two alternative formats, for larger and smaller units of length, each with two unit subsegments:
"[mi?] @ [yd] @|[ft?] @ [in] @"
...results in
1.1 mile -->1 mi 176 yds
1 mile --> 1 mi 0 yds
44 yards --> 44 yds
27 inches --> 2 ft 3 in
9 inches --> 9 in
If the unit format string in the example was applied to a numeric value of one mile or more:
[mi?] @ [yd] @
is used.[ft?] @ [in] @
is ignored.
If the value is less than 1 mile but at least 1 yard:
[yd] @
is used.[mi?] @
is ignored.
If the value is less than 1 yard, the first alternative format [mi?] @ [yd] @
is skipped.
Simplified Formats
You can use a simplified format to display all units of a type, or family, in the same unit. For example, all lengths displayed in feet. In this case, use the format feet
, which is treated as [feet] @
.
When you're adding units of different types together, such as yards and inches, you might use the as feet
operator to display the result in feet. However, there are still advantages to using a format to control this, such as assigning a format to a variable.
You can also use a simplified format for mutually exclusive formats:
"GB|MB|KB|Byte"
instead of
"[GB] @|[MB] @|[KB] @|[Byte] @"
Introduce a number format into the first alternate format followed by an asterisk (*
) to make it the default for the rest of the format.
"[GB? 0.0*] @|MB?|KB?|Byte"
Question marks are needed in each of the GB, MB, and KB sections of this format because a number format with a decimal place is being used for each of those alternatives.