# Dates, times and numbers

Source: https://govform.com/resources/documentation/article/34-04-liquid-dates-times-and-number-filters
Topic: Liquid Templates

Use these filters for arithmetic, dates, time zones and numeric presentation. Test boundary cases around midnight, daylight-saving changes, month ends, blanks and values supplied as text.

## Standard Liquid filters

These filters are provided as standard by the Liquid language. They are available anywhere Govform accepts a Liquid template.

| Filter | What it does | Example |
| --- | --- | --- |
| `abs(number)` | **Returns absolute value of number**  
Converts negative numbers to positive. | `{{ -5 | abs }} → 5` |
| `at_least(minimum)` | **Ensures value is at least minimum**  
Returns input if >= minimum, otherwise returns minimum. | `{{ 3 | at_least: 5 }} → 5` |
| `at_most(maximum)` | **Ensures value is at most maximum**  
Returns input if <= maximum, otherwise returns maximum. | `{{ 10 | at_most: 5 }} → 5` |
| `ceil()` | **Rounds number up to nearest integer**  
Returns smallest integer >= input. | `{{ 4.2 | ceil }} → 5` |
| `date(format, time_zone)` | **Formats date string**  
Formats date using strftime format codes. | `{{ "now" | date: "%Y-%m-%d" }} → 2025-03-15` |
| `date_to_long_string(type, style)` | **Formats a date with the full month name**  
Returns a date such as 25 December 2026. Use "ordinal" and optionally "US" for an ordinal date. | `{{ "2026-12-25" | date_to_long_string }} → 25 December 2026` |
| `date_to_rfc822()` | **Formats a date as RFC 822**  
Returns a date and time suitable for feeds and email date headers. | `{{ "2026-07-23T12:30:00Z" | date_to_rfc822 }}` |
| `date_to_string(type, style)` | **Formats a date with an abbreviated month**  
Returns a date such as 25 Dec 2026. Use "ordinal" and optionally "US" for an ordinal date. | `{{ "2026-12-25" | date_to_string }} → 25 Dec 2026` |
| `date_to_xmlschema()` | **Formats a date as an XML Schema timestamp**  
Returns an ISO-style date and time including its time zone offset. | `{{ "2026-07-23T12:30:00Z" | date_to_xmlschema }}` |
| `divided_by(divisor)` | **Divides number by divisor**  
Performs division operation. | `{{ 10 | divided_by: 3 }} → 3.3333333333333335` |
| `floor()` | **Rounds number down to nearest integer**  
Returns largest integer <= input. | `{{ 4.8 | floor }} → 4` |
| `minus(subtrahend)` | **Subtracts number from input**  
Performs subtraction operation. | `{{ 10 | minus: 3 }} → 7` |
| `modulo(divisor)` | **Returns remainder after division**  
Performs modulo operation. | `{{ 10 | modulo: 3 }} → 1` |
| `plus(addend)` | **Adds number to input**  
Performs addition operation. | `{{ 5 | plus: 3 }} → 8` |
| `round(decimal_places)` | **Rounds number to specified decimal places**  
Rounds to nearest value with specified precision. | `{{ 3.14159 | round: 2 }} → 3.14` |
| `times(multiplier)` | **Multiplies number by multiplier**  
Performs multiplication operation. | `{{ 3 | times: 4 }} → 12` |

## Govform filters

These filters are added by Govform for service-building and data-handling tasks.

| Filter | What it does | Example |
| --- | --- | --- |
| `as_number(string)` | **Converts string to number, removing currency symbols**  
Parses numeric value from string, removing £, $, €, and commas. | `{{ "£1,234.56" | as_number }} → 1234.56` |
| `date_to_gfdate(date, time_zone)` | **Converts JavaScript Date to Govform date object**  
Transforms Date to {day, month, year} object format. Optionally extracts the date in the supplied IANA time zone. | `{{ my_date | date_to_gfdate: "Europe/London" }}` |
| `day_end(date, offset, time_zone)` | **Gets end of day (23:59:59)**  
Returns date at end of day, optionally offset by days. Optionally uses the supplied IANA time zone for the day boundary. | `{{ submittedDate | day_end: 0, "Europe/London" }} → end of that London date` |
| `day_offset(date, offset, time_zone)` | **Adds days to date**  
Returns new date with specified number of days added. Optionally applies the offset in the supplied IANA time zone. | `{{ "now" | day_offset: 7, "Europe/London" }} → date 7 days from now` |
| `day_start(date, offset, time_zone)` | **Gets start of day (00:00:00)**  
Returns date at beginning of day, optionally offset by days. Optionally uses the supplied IANA time zone for the day boundary. | `{{ submittedDate | day_start: 0, "Europe/London" }} → midnight at the start of that London date` |
| `excel_date(serial_date, offset, time_zone)` | **Converts Excel serial date to Date**  
Converts Excel numeric date format to JavaScript Date. Optionally interprets the Excel date at midnight in the supplied IANA time zone. | `{{ 44927 | excel_date: 0, "Europe/London" }} → converts Excel date number` |
| `format_currency(number, include_pence, round_even, locale, currency)` | **Formats number as currency**  
Formats number as currency with locale and rounding options. | `{{ 1234.56 | format_currency: true, false, "en-GB", "GBP" }}` |
| `format_date(date, format, time_zone)` | **Formats date using specified format string**  
Uses date-fns formatting with custom format patterns. Optionally formats in the supplied IANA time zone. | `{{ submittedDate | format_date: "dd/MM/yyyy HH:mm zzz", "Europe/London" }}` |
| `format_number(number, min_digits, max_digits, locale)` | **Formats number with specified decimal places**  
Formats a number using the library regional locale, or an explicit locale, with decimal control. | `{{ 1234.5 | format_number: 2, 2 }} → 1,234.50` |
| `gfdate(gf_date_object, time_zone)` | **Converts Govform date object to JavaScript Date**  
Transforms {day, month, year} object to Date instance. Optionally interprets the date at midnight in the supplied IANA time zone. | `{{ my_gf_date | gfdate: "Europe/London" }}` |
| `gfdate_to_date(gf_date_object, time_zone)` | **Converts Govform date to JavaScript Date**  
Same as gfdate filter - converts {day, month, year} to Date. Optionally interprets the date at midnight in the supplied IANA time zone. | `{{ my_gf_date | gfdate_to_date: "Europe/London" }}` |
| `gfdate_to_string(gf_date_object, separator)` | **Converts Govform date to formatted string**  
Formats {day, month, year} as string with custom separator (default: "-"). | `{{ my_gf_date | gfdate_to_string: "/" }}` |
| `gftime_to_string(gf_time_object)` | **Converts Govform time object to string**  
Formats time object to HH:mm string format. | `{{ my_gf_time | gftime_to_string }}` |
| `is_decimal(value)` | **Checks if value is decimal number**  
Returns true if value is numeric and not an integer. | `{{ 123.45 | is_decimal }} → true` |
| `is_number(value)` | **Checks if value is numeric**  
Returns true if value can be parsed as a number. | `{{ "123.45" | is_number }} → true` |
| `math(expression, ...variables)` | **Evaluates mathematical expressions with variable substitution**  
Uses MathJS to evaluate expressions. Variables are mapped to a-z based on order. | `{{ "((a-b) * 2 + 3) / c" | math: 5, myVar1, myVar2 }}` |
| `month_offset(date, offset, time_zone)` | **Adds months to date**  
Returns new date with specified number of months added. Optionally applies the offset in the supplied IANA time zone. | `{{ "now" | month_offset: 3, "Europe/London" }} → date 3 months from now` |
| `number(value)` | **Converts value to number**  
Parses numeric value, returns empty string if not numeric. | `{{ "123.45" | number }} → 123.45` |
| `parse_date(date_string, format, time_zone)` | **Parses date string using specified format**  
Uses date-fns to parse date with custom format string. If an IANA time zone is supplied and the format does not include an offset/time zone token, the parsed local time is interpreted in that time zone. | `{{ "2023-12-25 09:30" | parse_date: "yyyy-MM-dd HH:mm", "Europe/London" }}` |
| `random(min, max)` | **Generates random integer in range**  
Returns random integer between min and max (inclusive). | `{{ 1 | random: 10 }} → random number 1-10` |
| `round_fixed(value, decimal_places)` | **Rounds number to fixed decimal places**  
Returns string representation with exact number of decimal places. | `{{ 123.456 | round_fixed: 2 }} → "123.46"` |
| `timestamp(date, offset, time_zone)` | **Gets timestamp from date**  
Returns Unix timestamp (milliseconds). Use "now" for current time. Optionally interprets date-only values in the supplied IANA time zone. | `{{ my_gf_date | timestamp: 0, "Europe/London" }}` |
| `to_iso_string(date, time_zone)` | **Converts date to ISO 8601 string (UTC)**  
Returns a UTC ISO 8601 string (e.g. 2025-07-02T21:01:31.000Z). Accepts "now", a Govform date object {day,month,year}, or a JavaScript Date. Optionally interprets date-only values in the supplied IANA time zone. | `{{ my_gf_date | to_iso_string: "Europe/London" }} → 2025-07-01T23:00:00.000Z` |

## Display zones and machine timestamp contracts

The no-format `date`/`format_date` display uses the viewer's browser zone, then the deployed Service time zone, then Europe/London. Custom time formats need a zone token. Unzoned input/calendar arithmetic uses the Service time zone; explicit arguments override it. `to_iso_string` emits UTC ISO text and `timestamp` emits epoch milliseconds. See [Regional formatting and API timestamp examples](<https://govform.com/resources/documentation/article/34-07-liquid-regional-dates-currencies>) before changing a live integration.

## Related guidance

-   [Write Liquid templates](<https://govform.com/resources/documentation/article/11-write-liquid-templates>)
-   [Use Markdown and HTML](<https://govform.com/resources/documentation/article/12-use-markdown-and-html>)
