A format style that displays the time offset between a
comparison date and an anchor date that you provide.
`DateOffset` formats the difference between the input date and
the specified anchor into a human-readable string. It
automatically chooses between a compact time representation
(like `5:32`) and a units representation (like
`2 days, 3 hours`) based on what values you set in
`allowedFields`.
When you use this with ``Text``, the value the style displays
updates automatically as time progresses:
```swift
let startDate = Date.now
// Shows elapsed time since startDate.
Text(.currentDate, format: .offset(to: startDate))
// Output: "3 minutes, 42 seconds"
```
### Controlling which units appear
By default, the style may show year, month, day, hour, minute,
and second fields. You can restrict this with `allowedFields`:
```swift
// Only show hours, minutes, and seconds in time format.
Text(.currentDate, format: .offset(
to: startDate,
allowedFields: [.hour, .minute, .second],
maxFieldCount: 3))
// Output: "1:23:45"
```
When you limit the allowed fields to `[.minute, .second]`
(with `maxFieldCount: 2`) or `[.hour, .minute, .second]`
(with `maxFieldCount: 3`), the style uses a time-pattern
format:
| Allowed fields | Max fields | Example output |
|---------------|------------|---------------|
| `[.minute, .second]` | 2 | `5:32` |
| `[.hour, .minute, .second]` | 3 | `1:05:32` |
| `[.hour, .minute]` | 2 | `1 hour, 5 minutes` |
| `[.year, .month, .day, ...]` | 2 | `2 days, 3 hours` |
### Controlling the sign
The `sign` parameter determines how the style indicates
whether the offset is in the past or future:
```swift
// .automatic (default): sign only when date is before anchor
Text(.currentDate, format: .offset(to: anchor))
// 5 seconds after anchor: "5 seconds"
// 5 seconds before anchor: "−5 seconds"
// .never: no sign regardless of direction
Text(.currentDate, format: .offset(to: anchor, sign: .never))
// 5 seconds before anchor: "5 seconds"
// .always(includingZero: false): sign for both directions
Text(.currentDate, format:
.offset(to: anchor, sign: .always(includingZero: false)))
// 5 seconds after anchor: "+5 seconds"
// 5 seconds before anchor: "−5 seconds"
// 0 seconds from anchor: "0 seconds"
```
### Limiting the number of fields
The `maxFieldCount` parameter controls how many units appear
in the output. For an offset of 1 hour, 34 minutes, and 23
seconds from the anchor:
| `maxFieldCount` | Output |
|-----------------|--------|
| 2 (default) | `1 hour, 34 minutes` |
| 1 | `1 hour` |
| 3 | `1 hour, 34 minutes, 23 seconds` |
The next discretization boundary after the given input.
Use this function to determine the next "greater" input that warrants updating the formatted output.
The following example prints all possible outputs the format style can produce upwards starting
from the `startInput`:
```swift
var previousInput = startInput
while let nextInput = style.discreteInput(after: previousInput) {
print(style.format(nextInput))
previousInput = nextInput
}
```
- Returns: For most `input`s, the method returns the "smallest" value "greater" than
`input` for which the style produces a different ``FormatStyle/FormatOutput``, or `nil`
if no such value exists. For some input values, the function may also return a value "greater" than
`input` for which the style still produces the same ``FormatStyle/FormatOutput`` as for
`input`.
The next discretization boundary before the given input.
Use this function to determine the next "smaller" input that warrants updating the formatted output.
The following example prints all possible outputs the format style can produce downwards starting
from the `startInput`:
```swift
var previousInput = startInput
while let nextInput = style.discreteInput(before: previousInput) {
print(style.format(nextInput))
previousInput = nextInput
}
```
- Returns: For most `input`s, the method returns the "greatest" value "smaller" than
`input` for which the style produces a different ``FormatStyle/FormatOutput``, or `nil`
if no such value exists. For some input values, the function may also return a value "smaller" than
`input` for which the style still produces the same ``FormatStyle/FormatOutput`` as for
`input`.
Creates a format style that displays the offset between a
comparison date and an anchor date that you provide.
The style uses a time-pattern representation (`3:46`) when
`allowedFields` contains only `.minute` and `.second`, or
contains `.hour`, `.minute`, and `.second`. For any other
combination of fields, it uses calendar units like
`3 months, 11 days`.
- Parameters:
- anchor: The date the style uses to calculate the offset from
the format input date.
- allowedFields: The units of time that may appear in the
formatted output.
- maxFieldCount: The maximum number of units shown at
once. For example, 1 hour, 34 minutes, and 23 seconds
is shown as `1 hour, 34 minutes` by default, but as
`1 hour` if `maxFieldCount` is set to 1.
- sign: The strategy for displaying a sign to signal
whether the offset points toward the future or past.
The next input value after the given input.
Use this function to determine if the return value provided by ``discreteInput(before:)`` is
precise enough for your use case for any input `y`:
```swift
guard let x = style.discreteInput(before: y) else {
return
}
let z = style.input(after: x) ?? y
```
If the distance between `x` and `z` is too large for the precision you require, you may want
to manually probe ``FormatStyle/format(_:)`` at a higher rate in that interval, as there is
no guarantee for what the output will be in that interval.
- Returns: The next "greater" input value that can be represented by
``FormatStyle/FormatInput`` or an underlying representation the format style uses
internally.
The next input value before the given input.
Use this function to determine if the return value provided by ``discreteInput(after:)`` is
precise enough for your use case for any input `y`:
```swift
guard let x = style.discreteInput(after: y) else {
return
}
let z = style.input(before: x) ?? y
```
If the distance between `z` and `x` is too large for the precision you require, you may want
to manually probe ``FormatStyle/format(_:)`` at a higher rate in that interval, as there is
no guarantee for what the output will be in that interval.
- Returns: The next "smalller" input value that can be represented by
``FormatStyle/FormatInput`` or an underlying representation the format style uses
internally.
Formats a value, using this style.
Use this method when you want to create a single style instance, and then use it to format
multiple values.
- Parameter value: The value to format.
- Returns: A representation of `value`, in the ``FormatOutput`` type, formatted according to
the style's configuration.
Modifies the format style to use the specified locale.
Use this format style to change the locale used by an existing format style.
- Parameter locale: The locale to apply to the format style.
- Returns: A format style modified to use the provided locale.