8.5. Type Casting Functions

8.5.1. CAST()

Converts a value from one data type to another

Result typeAs specified by target_type

Syntax

CAST (<expression> AS <target_type> [ FORMAT cast_template ])
 
<target_type> ::= <domain_or_non_array_type> | <array_datatype>
 
<domain_or_non_array_type> ::=
  !! See Scalar Data Types Syntax !!
 
<array_datatype> ::=
  !! See Array Data Types Syntax !!

Table 8.66. CAST Function Parameters
ParameterDescription

expression

SQL expression

sql_datatype

SQL data type

cast_template

datetime format string

CAST converts an expression to the desired data type or domain. If the conversion is not possible, an error is raised.

The FORMAT clause is only allowed when converting between datetime and string types.

8.5.1.1. Shorthand Syntax

Alternative syntax, supported only when casting a string literal to a DATE, TIME or TIMESTAMP:

datatype 'date/timestring'

This syntax was already available in InterBase, but was never properly documented. In the SQL standard, this feature is called datetime literals.

ⓘ
Note

Since Firebird 4.0, the use of 'NOW', 'YESTERDAY' and 'TOMORROW' in the shorthand cast is no longer allowed; only literals defining a fixed moment in time are supported.

8.5.1.2. Allowed Type Conversions

The following table shows the type conversions possible with CAST.

Table 8.67. Possible Type-castings with CAST
FromTo

Numeric types

Numeric types [VAR]CHAR BLOB

[VAR]CHAR BLOB

[VAR]CHAR BLOB Numeric types DATE TIME TIMESTAMP

DATE TIME

[VAR]CHAR BLOB TIMESTAMP

TIMESTAMP

[VAR]CHAR BLOB DATE TIME

Keep in mind that sometimes information is lost, for instance when you cast a TIMESTAMP to a DATE. Also, the fact that types are CAST-compatible is in itself no guarantee that a conversion will succeed. CAST(123456789 as SMALLINT) will definitely result in an error, as will CAST('Judgement Day' as DATE).

8.5.1.3. Casting Parameters

You can also cast statement parameters to a data type:

cast (? as integer)

This gives you control over the type of the parameter set up by the engine. Please notice that with statement parameters, you always need a full-syntax cast — shorthand casts are not supported.

8.5.1.4. Casting to a Domain or its Type

Casting to a domain or its base type are supported. When casting to a domain, any constraints (NOT NULL and/or CHECK) declared for the domain must be satisfied, or the cast will fail. Please be aware that a CHECK passes if it evaluates to TRUE or NULL! So, given the following statements:

create domain quint as int check (value >= 5000);
select cast (2000 as quint) from rdb$database;     ①
select cast (8000 as quint) from rdb$database;     ②
select cast (null as quint) from rdb$database;     ③

only cast number 1 will result in an error.

When the TYPE OF modifier is used, the expression is cast to the base type of the domain, ignoring any constraints. With domain quint defined as above, the following two casts are equivalent and will both succeed:

select cast (2000 as type of quint) from rdb$database;
select cast (2000 as int) from rdb$database;

If TYPE OF is used with a (VAR)CHAR type, its character set and collation are retained:

create domain iso20 varchar(20) character set iso8859_1;
create domain dunl20 varchar(20) character set iso8859_1 collate du_nl;
create table zinnen (zin varchar(20));
commit;
insert into zinnen values ('Deze');
insert into zinnen values ('Die');
insert into zinnen values ('die');
insert into zinnen values ('deze');
 
select cast(zin as type of iso20) from zinnen order by 1;
-- returns Deze -> Die -> deze -> die
 
select cast(zin as type of dunl20) from zinnen order by 1;
-- returns deze -> Deze -> die -> Die
🛑
Warning

If a domain’s definition is changed, existing CASTs to that domain or its type may become invalid. If these CASTs occur in PSQL modules, their invalidation may be detected. See the note The RDB$VALID_BLR field, in Appendix A.

8.5.1.5. Casting to a Column’s Type

It is also possible to cast expressions to the type of an existing table or view column. Only the type itself is used; in the case of string types, this includes the character set but not the collation. Constraints and default values of the source column are not applied.

create table ttt (
  s varchar(40) character set utf8 collate unicode_ci_ai
);
commit;
 
select cast ('Jag har många vänner' as type of column ttt.s)
from rdb$database;
🛑
Warning

If a column’s definition is altered, existing CASTs to that column’s type may become invalid. If these CASTs occur in PSQL modules, their invalidation may be detected. See the note The RDB$VALID_BLR field, in Appendix A.

8.5.1.6. Formatting and Parsing Datetime Values

The FORMAT clause serves two purposes:

  1. Converting a datetime value to a string

  2. Parsing a string value to a datetime value

The cast_template of the FORMAT clause specifies how the datetime should be converted to string, or how the string should be parsed to a datetime.

The cast_template must be a string literal, and has the following syntax:

Table 8.68. Cast Template Fields
Format PatternDescription

YEAR

Year (1 - 9999)

YYYY

Last 4 digits of year (0001 - 9999)

YYY

Last 3 digits of year (000 - 999)

YY

Last 2 digits of year (00 - 99)

Y

Last digit of year (0 - 9)

RR / RRRR

Round Year (further information below) Only string to datetime

Q

Quarter of the year (1 - 4) Only datetime to string

MM

Month (01 - 12)

MON

Short month name (e.g. Apr)

MONTH

Full month name (e.g. APRIL)

RM

Roman number of the month (I - XII)

WW

Week of the year (01 - 53) Only datetime to string

Exercise caution when combining with year. For example, 2023-01-01 is week 52 2022, but there is no week-based year template variable, and 'WW YYYY' renders 52 2023!

W

Week of the month (1 - 5) Only datetime to string

Week 1 starts at day 1, week 2 at day 8, week 3 at day 15, week 4 for at day 22 and week 5 at day 29.

D

Day of the week (1 - 7) Only datetime to string

1 is Sunday, 7 is Saturday

DAY

Full name of the day (e.g. MONDAY) Only datetime to string

DY

Short name of the day (e.g. Mon)

DD

Day of the month (01 - 31)

DDD

Day of the Year (001 - 366) Only datetime to string

J

Julian Day (number of days since January 1, 4712 BC)

HH / HH12

Hour of the day (01 - 12) without AM/PM period

When converting from string to datetime, specifying template-field A.M. or P.M. is required.

HH24

Hour of the day (00 - 23)

MI

Minutes (00 - 59)

SS

Seconds (00 - 59)

SSSSS

Seconds since midnight (0 - 86399)

FF1 - FF9

Fractional seconds with the specified accuracy. When converting from string to datetime, only FF1 - FF4 are supported.

For FF5 - FF9, digits 5 - 9 are always 0.

A.M. / P.M.

AM/PM period for 12 hours time. Either can be used, and will parse A.M. and P.M., or render A.M. or P.M. depending on the actual time.

TZH

Time zone in hours (-14 - 14)

TZM

Time zone in minutes (00 - 59)

TZR

Time zone name or time zone displacement (same as TZH:TZM)

Most of these template fields are defined by the SQL Standard, but some are non-standard extensions. The template fields are case-insensitive, so YYYY-MM is the same as yyyy-mm.

The template fields can be separated with the following delimiters:

Table 8.69. Cast Template Delimiters
Delimiter

-

.

/

,

;

:

'

<space>

It is possible to insert raw text into a format string with double quotes: …​ FORMAT '"Today is" DAY' → Today is MONDAY. To render ", escape it with \, i.e. use \", and to render \, use \\.

Example:

SELECT CAST(CURRENT_TIMESTAMP AS VARCHAR(45)
  FORMAT 'DD.MM.YEAR HH24:MI:SS "is" J "Julian day"')
FROM RDB$DATABASE;
=========================
14.6.2023 15:41:29 is 2460110 Julian day

Patterns can be used without any separators:

SELECT CAST(CURRENT_TIMESTAMP AS VARCHAR(50)
  FORMAT 'YEARMMDD HH24MISS')
FROM RDB$DATABASE;
=========================
20230719 161757

However, be careful with patterns with repeating characters, for example DDDDD will be interpreted as DDD + DD.

8.5.1.6.1. Converting from String to Datetime

When converting from string to datetime, additional rules and limitations apply:

  • If the target type has a date component, and year, month or day are not set by the pattern, the missing parts will get their values from the current date.

    This results in an error if the date is not valid. For example, cast('31' as date format 'DD') works in months with 31 days, but produces error conversion error from string "31" in February, or months with only 30 days.

  • If the target type has a time component, and hours, minutes, seconds, or fractions are not set by the pattern, the missing parts will be set to 0

  • Behaviour of RR (two-digit Round Year):

    • If the specified two-digit year is 00 to 49, then

      • If the last two digits of the current year are 00 to 49, then the returned year has the same first two digits as the current year.

      • If the last two digits of the current year are 50 to 99, then the first 2 digits of the returned year are 1 greater than the first 2 digits of the current year.

    • If the specified two-digit year is 50 to 99, then

      • If the last two digits of the current year are 00 to 49, then the first 2 digits of the returned year are 1 less than the first 2 digits of the current year.

      • If the last two digits of the current year are 50 to 99, then the returned year has the same first two digits as the current year.

  • Behaviour of RRRR (4-digit Round Year): Accepts either 4-digit or 2-digit input. If 2-digit, it provides the same result as RR. If you do not want this functionality, then enter a 4-digit year.

Example:

SELECT CAST('2000.12.08 12:35:30.5000' AS TIMESTAMP
  FORMAT 'YEAR.MM.DD HH24:MI:SS.FF4')
FROM RDB$DATABASE;
=====================
2000-12-08 12:35:30.5000

In datetime to string conversions, most template variables produce a fixed length (e.g. HH24 produces two digits). However, in string to datetime conversions, those template variable are lenient and will also accept shorter values. For example, HH24:MI produces a string like 01:05, but will consume both '01:05' and '1:5' (etc.) as the same value.

The FFn format strings produce a value of n digits, but will also consume shorter values. A shorter value is parsed as if the missing digits are trailing zeroes. For example, conversion with HH24:MI:SS.FF4 for strings '23:12:05.4000' and '23:12:05.4' produce the same value.

The pattern YEAR produces 1 - 4 digits, but can consume more digits (which then results in an out-of-range error).

For patterns without delimiters, this behaviour may introduce ambiguity in parsing values and limit roundtrip behaviour.

8.5.1.7. Cast Examples

A full-syntax cast:

select cast ('12-June-1959' as date) from rdb$database

A shorthand string-to-date cast (a.k.a. date literal):

update People set AgeCat = 'Old'
  where BirthDate < date '1-Jan-1943'

Notice that you can drop even the shorthand cast from the example above, as the engine will understand from the context (comparison to a DATE field) how to interpret the string:

update People set AgeCat = 'Old'
  where BirthDate < '1-Jan-1943'

However, this is not always possible. The cast below cannot be dropped, otherwise the engine would find itself with an integer to be subtracted from a string:

select cast('today' as date) - 7 from rdb$database

Render a timestamp in ISO 8601 format:

select cast(localtimestamp as char(24)
  format 'YYYY-MM-DD"T"HH24:MI:SS.FF4')
from rdb$database
-- 2025-07-24T11:18:56.9930