# Date and time helpers

Date and time helpers transform content in Handlebars expressions.

## Formatting dates and times

You can format dates and times using helpers `dateFormat`, `timeFormat`, and `datetimeformat`. Each helper takes the arguments [`date-time`](#date-time), [`locale`](#locale), [`format`](#format), and [`pattern`](#pattern).

Following the helper, you must include a `date-time` and `locale`. For example, `{{dateFormat "1983-01-31T12:36:35" locale="en-US"}}`. The `format` and `pattern` arguments are optional.

Examples of each helper:

| Helper | Rendered as | Example | Output |
| --- | --- | --- | --- |
| dateFormat | Date | `{{dateFormat "1983-01-31T12:36:35" locale="en-US"}}` | Jan 31, 1983 |
| timeFormat | Time | `{{timeFormat "1983-01-31T12:36:35" locale="en-US"}}` | 12:36:35 PM |
| datetimeFormat | Date and time | `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US"}}` | Jan 31, 1983, 12:36:35 PM |

You can also provide date-times using Date [Attributes](https://www.airship.com/docs/reference/glossary/#attributes) instead of a date-time string. When using Attributes, do not enclose them in quotes.
 
These examples show how the `locale`, `format`, and `pattern` arguments can transform a date-time, using a Date [Attribute](https://www.airship.com/docs/reference/glossary/#attributes) `birthdate` with value January 31, 1983, for the date-time:

| Argument | Example | Output |
| --- | --- | --- |
| Format using the `locale` argument only. | `{{dateFormat birthdate locale="en-US"}}` | Jan 31, 1983 |
| Add the `format` argument to specify a shorter, numeric-only output. | `{{dateFormat birthdate locale="en-US" format="SHORT"}}` | 1/31/1983 |
| Change the `format` value to `FULL` to expand "Jan" to "January" and include the day of the week. | `{{dateFormat birthdate locale="en-US" format="FULL"}}` | Monday, January 31, 1983 |
| Use the `pattern` argument to specify custom formatting. | `{{dateFormat birthdate locale="en-US" pattern="d MMMM yyyy"}}` | 31 January 1983 |
| Change the `locale` value to change the language. The example here changes the output French. | `{{dateFormat birthdate locale="fr-FR" pattern="d MMMM yyyy"}}` | 31 janvier 1983 |

### Date-time

An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-formatted string — Required. In general, we recommend that you use uniform date-time values since they work for all three helpers, but the actual date-time string requirements vary per helper.

You can add `[Offset]` to specify the time zone offset from UTC. Use `Z` for UTC, or one of the following formats `±00:00`, `±0000`, `±00`. For example, `-08:00`, `-0800`, or `-08` for PST.

Date-time format per helper, with optional parts of the string in brackets:

| Helper | Optional data | Date-time format |
| --- | --- | --- |
| dateFormat | Time | `yyyy-MM-dd[' ']['T']HH:mm[:ss[.SSS][Offset]]` |
| timeFormat | Date | `[yyyy-MM-dd[' ']['T']]HH:mm[:ss[.SSS]][Offset]` |
| datetimeFormat | n/a | `yyyy-MM-dd[' ']['T']HH:mm[:ss[.SSS]][Offset]` |

### Locale

`locale` — Required. Date and time helper argument that renders the date and time according to the user's 2-letter language and country codes, joined by a dash. Format example: `locale="en-US"`. The language is an [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code. The country is an [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code.

| Example | Output |
| --- | --- |
| `{{dateFormat "1983-01-31T12:36:35" locale="en-US"}}` | Jan 31, 1983 |
| `{{dateFormat "1983-01-31T12:36:35" locale="fr-FR"}}` | 31 janv. 1983 |
| `{{dateFormat "1983-01-31T12:36:35" locale="de-DE"}}` | 31.01.1983 |
| `{{timeFormat "1983-01-31T12:36:35" locale="en-US"}}` | 12:36:35 PM |
| `{{timeFormat "1983-01-31T12:36:35" locale="fr-FR"}}` | 12:36:35 |
| `{{timeFormat "1983-01-31T12:36:35" locale="de-DE"}}` | 12:36:35 |
| `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US"}}` | Jan 31, 1983, 12:36:35 PM |
| `{{datetimeFormat "1983-01-31T12:36:35" locale="fr-FR"}}` | 31 janv. 1983 à 12:36:35 |
| `{{datetimeFormat "1983-01-31T12:36:35" locale="de-DE"}}` | 31.01.1983, 12:36:35 |

Locale values can also be provided using Date [Attributes](https://www.airship.com/docs/reference/glossary/#attributes) instead of an actual date-time string.


> **Tip:** The Airship SDK gathers `ua_language` and `ua_country` and stores them as Default [Attributes](https://www.airship.com/docs/reference/glossary/#attributes) for your app audience. You can use the Attributes as `locale` values.


### Format

`format` — Optional. Date and time helper argument that determines how to display the date-time value. One of `FULL`, `LONG`, `MEDIUM`, or `SHORT`.  Format example: `format="SHORT"`. `FULL` and `LONG` formats include time zone information. If you don't set a time zone value in your date-time string, Airship assumes `Z` (UTC/GMT). `format` cannot be used in combination with `pattern`.

The following tables show examples and output of `format` for each date and time helper.
   
`dateFormat` examples:

| Format | Example | Output |
| --- | --- | --- |
| SHORT | `{{dateFormat "1983-01-31T12:36:35" locale="en-US" format="SHORT"}}` | 1/31/1983 |
| MEDIUM | `{{dateFormat "1983-01-31T12:36:35" locale="en-US" format="MEDIUM"}}` | Jan 31, 1983 |
| LONG | `{{dateFormat "1983-01-31T12:36:35" locale="en-US" format="LONG"}}` | January 31, 1983 |
| FULL | `{{dateFormat "1983-01-31T12:36:35" locale="en-US" format="FULL"}}` | Tuesday, January 31, 1983 |

`timeFormat` examples:

| Format | Example | Output |
| --- | --- | --- |
| SHORT | `{{timeFormat "1983-01-31T12:36:35" locale="en-US" format="SHORT"}}` | 12:36 PM |
| MEDIUM | `{{timeFormat "1983-01-31T12:36:35" locale="en-US" format="MEDIUM"}}` | 12:36:35 PM |
| LONG | `{{timeFormat "1983-01-31T12:36:35" locale="en-US" format="LONG"}}` | 12:36:35 PM Z |
| FULL | `{{timeFormat "1983-01-31T12:36:35" locale="en-US" format="FULL"}}` | 12:36:35 PM Z |

`datetimeFormat` examples:

| Format | Example | Output |
| --- | --- | --- |
| SHORT | `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US" format="SHORT"}}` | 1/31/1983 12:36 PM |
| MEDIUM | `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US" format="MEDIUM"}}` | Jan 31, 1983 12:36:35 PM |
| LONG | `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US" format="LONG"}}` | January 31, 1983 12:36:35 PM Z |
| FULL | `{{datetimeFormat "1983-01-31T12:36:35" locale="en-US" format="FULL"}}` | Tuesday, January 31, 1983 12:36:35 PM Z |

### Pattern

`pattern` — Optional. Date and time helper argument that specifies a custom formatting pattern. Format example: `pattern="MMM d, yyyy"`. Only the parts that are relevant to the type of formatting are allowed. For example, date parts are not allowed within `timeFormat`. Cannot be used in combination with `format`.

The most common `pattern` specifiers:

| Specifier | Output                     | Example                             |
|-----------|----------------------------|-------------------------------------|
| y         | Year                       | `yyyy` for `2023`, `yy` for `23`    | 
| M         | Month                      | `M` for `4`, `MMMM` for `April`     |
| d         | Day of Month               | `d` for `5`, `dd` for `05`          |
| e         | Day of Week                | `e` for `2`, `eeee` for `Wednesday` |
| a         | AM/PM                      | `a` for `PM`                        |
| h         | Hour (1-12)                | `hh` for `12`                       |
| K         | Hour (0-11)                | `KK` for `11`                       |
| k         | Hour (1-24)                | `kk` for `12`                       |
| H         | Hour (0-23)                | `HH` for `11`                       |
| m         | Minute                     | `mm` for `30`                       |
| s         | Second                     | `ss` for `55`                       |
| V         | Time Zone ID               | `VV` for `America/Los_Angeles`      |
| z         | Time Zone Name             | `z` for `PDT`                       |
| O         | Localized Zone Offset      | `O` for `GMT+8`                     |
| X         | Offset 'Z' for zero        | `X` for `Z`, `XXX` for `-07:00`     |
| Z         | Offset                     | `Z` for `-0700`                     |

The above specifiers adhere to the following rules:

1. When specifying numbers that may include a leading zero, a single character will omit the leading zero and double characters will include the leading zero. For example, for the fourth hour:
   * `h` will output `4`
   * `hh` will output `04`
1. When specifying text output, 1 to 3 characters specify shortened forms, four characters specifies the full form, five characters specifies the narrow form. For example, for the month of April with `en-US` locale:
   * `M` will output `4`
   * `MM` will output `04`
   * `MMM` will output `Apr`
   * `MMMM` will output `April`
   * `MMMMM` will output `A`
1. Literal values may be specified in square brackets. For example, `['T']` will yield `T`.

Additional formatting options are available and follow the [Java `DateTimeFormatter` rules](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html).

Example use and output of `pattern` for each date and time helper:

| Helper | Example | Output |
| --- | --- | --- |
| dateFormat | `{{dateFormat "2023-03-29T13:30:10" locale="en-US" pattern="MMM d, yyyy"}}` | Mar 29, 2023 |
| dateFormat | `{{dateFormat "2023-03-29T13:30:10" locale="de-DE" pattern="d MMMM yyyy"}}` | 29 März 2023 |
| timeFormat | `{{timeFormat "13:30:10" locale="en-US" pattern="h:mma"}}` | 1:30PM |
| datetimeFormat | `{{datetimeFormat "2023-03-29T13:30:10" locale="en-US" pattern="yyyy-MM-dd['T']HH:mm:ss"}}` | 2023-03-29T13:30:10 |
   
## Determining today, yesterday, or tomorrow

Return `true` or `false` based on whether a given date is today, yesterday, or tomorrow relative to the current time in UTC:

* `{{$isToday "<date>"}}`
* `{{$isYesterday "<date>"}}`
* `{{$isTomorrow "<date>"}}`

Dates must be formatted as `yyyy-mm-dd` or as a [date-time](#date-time). These helpers are generally used within an evaluation only rather than displaying the result.

You can combine them with conditional operators to return true or false in a helper block. You can also use them with a preceding `#` and a closing `/` to create a separate block:

```text
{{#if ($isToday birthdate)}}
Happy birthday, {{name}}
{{/if}}
```


```text
{{#$isToday birthdate}}
Happy birthday, {{name}}
{{/$isToday}}
```


## Getting date and time

Return the current date, or date and time, in UTC:

* `{{$now}}` — Returns the current date and time in UTC in [datetimeFormat](#formatting-dates-and-times) (`yyyy-MM-ddTHH:mm:ssZ`).
* `{{$today}}` — Returns the current date in [dateFormat](#formatting-dates-and-times) (`yyyy-MM-dd`).

Example use in a purchase order:

```text
Purchase Date: {{$today}}

// Using `timeFormat` to remove the date to get only the time:
Your order was received at {{timeFormat ($now) format="SHORT" locale="en-US"}}.
```


## Calculating date and time

Return an age, future date, or time between dates:

| Helper and format | Description |
| --- | --- |
| `{{$age "<date>"}}` | Returns an age as of today for a given date. |
| `{{$addTo "<date>" <amount> timeUnit="<time_unit>"}}` | Returns a future date for a given date by adding an amount of time in `days`, `weeks`, `months`, or `years` to a given date-time. `timeUnit` is optional and defaults to days when omitted. Time units are not case-sensitive. |
| `{{$daysBetween "<date>" "<date>"}}` | Returns the number of days between two dates. |
| `{{$weekBetween "<date>" "<date>"}}` | Returns the number of weeks between two dates. |
| `{{$timeBetween "<date>" "<date>" timeUnit="<time_unit>}}` | Returns the number of `days`, `weeks`, `months`, or `years` between two dates. `timeUnit` is optional and defaults to days when omitted. Time units are not case-sensitive. |

Dates must be formatted as `yyyy-mm-dd` or as a [date-time](#date-time).

The following examples assume today's date is March 25, 2024, and some also use the [`$today`](#getting-date-and-time) and [`pattern`](#pattern) helpers:

| Example | Output |
| --- | --- |
| `{{$age "1970-06-01"}}` | 53 |
| `{{dateFormat ($addTo ($today) 7 timeUnit="days") locale="en-US"}}` | Apr 1, 2024 |
| `{{dateFormat ($addTo ($today) 7 timeUnit="days") locale="en-US" pattern="dd-MM-yy"}}` | 01-04-24 |
| `{{$daysBetween "2024-12-19" "2025-12-19"}}` | 365 |
| `{{$weeksBetween "2024-12-19" "2025-12-19"}}` | 52 |
| `{{$timeBetween "2024-12-19" "2025-12-19"}}` | 365 |
| `{{$timeBetween "2024-12-19" "2025-12-19" timeUnit="days"}}` | 365 |
| `{{$timeBetween "2024-12-19" "2025-12-19" timeUnit="weeks"}}` | 52 |
| `{{$timeBetween "2024-12-19" "2025-12-19" timeUnit="months"}}` | 12 |
| `{{$timeBetween "2024-12-19" "2025-12-19" timeUnit="years"}}` | 1 |

For `$daysBetween`, `$weekBetween`, and `$timeBetween`:
   * If the second date is earlier than the first date, the result will be a negative number.
   * The calculation returns a whole number, representing the number of complete time units between the two dates. For example, if the time unit is `days` and there are 30 hours between the two dates, then the output will be "1".

Example usage in messages:

| Example | Output |
| --- | --- |
| `Your membership expires in three days, on {{dateFormat ($addTo ($today) 3 timeUnit="days") format="SHORT" locale="en-US"}}.` | Your membership expires in three days, on 3/28/24. |
| `There are {{$daysBetween ($today) "2021-12-25"}} days left until Christmas!` | There are -821 days left until Christmas! |
| `There are {{$daysBetween ($today) "2035-12-25"}} days left until Christmas 2035!` | There are 4292 days left until Christmas 2035! |
| `There are {{$timeBetween "2024-01-29T12:36:35" "2024-01-31T12:36:35" springSaleEnds}} days left in our Spring Sale!` | There are 2 days left in our Spring Sale! |

## Transforming a date to another time zone

Transform a date to another time zone using `{{$toTimezone "<date>" "<timezone_id>"}}`.

Dates must be formatted as `yyyy-mm-dd` or as a [date-time](#date-time). The `timezone_id` is the text identifier for the time zone. For example, `America/Los_Angeles`. See the [TZ column](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) in the list of Time Zone abbreviations.

The first example in each pair uses standard formatting, and the second adds the [`datetimeFormat` helper](#formatting-dates-and-times) and [`format` argument](#format) to give a more localized time:

|  Example  |  Output  |
| --- | --- |
| `{{$toTimezone "2023-04-05T15:24:40Z" "America/Los_Angeles"}}` | 2023-04-05T08:24:40-07:00[America/Los_Angeles] |
| `{{datetimeFormat ($toTimezone "2023-04-05T15:24:40Z" "America/Los_Angeles") locale="en-US" format="LONG"}}` | April 5, 2023 at 8:24:40 AM PDT |
| `{{$toTimezone "2023-04-05T15:24:40Z" "America/Jamaica"}}` | 2023-04-05T10:24:40-05:00[America/Jamaica] |
| `{{datetimeFormat ($toTimezone "2023-04-05T15:24:40Z" "America/Jamaica") locale="en-US" format="LONG"}}` | April 5, 2023 at 10:24:40 AM EST |
