# 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.

### Custom Conditional Values

By default, `1`

is the minimum number that triggers the formatting in a conditional segment.

A conditional segment is indicated by either:

`?`

within the token`|`

between mutually exclusive alternatives.

When a value is less than `1`

, the conditional segment is skipped, and the next segment is processed. To change the value that causes the conditional segment to be triggered, include a number before the unit name within a token. In this example, feet are only displayed when the length is at least 2 feet rather than the default of 1 foot.

`"[2 feet?] @ [inches] @"`

...results in

`27 inches —> 2 feet 3 inches`

23 inches —> 23 inches

In the following example, the first alternative format is only used when the numeric value is at least 1.1 GB. If the value is less than 1.1 GB, the next segment is tested.

`"[1.1GB 0.#] @|[1.1MB 0.#] @|[1.1KB 0.#] @|[Byte] @"`

### Escaping Special Characters

Unit formats use the following characters for special purposes: `|`

, `@`

, `[`

, `]`

, `\`

, `{`

, and `}`

. The final two characters are reserved for future use. To include any of these characters in the text of a unit format outside of a `[ ]`

token, enter a backslash (`\`

) before the character.