Download

date/time field value out of range

A date or time string has a field that can’t be right: day 30 of February, month 13, hour 25, or the day and month the wrong way round for the DateStyle setting. Send ISO dates (2026-12-25), or parse with to_date and an explicit format.

PostgreSQL error 22008· Tested on PostgreSQL 18.6 (also 14.24)· Updated 11 October 2026

ERROR:  date/time field value out of range: "2026-02-30"

What it means

PostgreSQL read your string as a date or time, and one of its fields is outside what that field can be. The message quotes the whole string:

ERROR:  date/time field value out of range: "2026-02-30"

Either the date doesn’t exist (30 February, month 13, minute 61), or PostgreSQL read the fields in a different order than you meant. When it suspects the order, it adds a hint:

ERROR:  date/time field value out of range: "25/12/2026"
HINT:  Perhaps you need a different "DateStyle" setting.

The DateStyle setting decides how ambiguous dates like 03/04/2026 are read. Its default is ISO, MDY (month first, the US order), so 25/12/2026 means month 25. ISO dates (2026-12-25) are read the same way whatever the setting.

The same code, 22008, covers timestamp out of range (a value past the type’s limits, which run from 4713 BC to 294276 AD for timestamp) and date field value out of range from make_date().

Common causes

  1. Day-first dates (25/12/2026) from a European or British spreadsheet, a CSV or a form, read with the default month-first DateStyle.
  2. Impossible dates generated by code: adding a month to 31 January by changing the month number, 29 February in a non-leap year, a day computed as 0.
  3. MySQL “zero dates” (0000-00-00, 0000-00-00 00:00:00) in data moved from MySQL. PostgreSQL has no year 0 and no zero date.
  4. Times past midnight written as 24:30 or 25:00, from systems that count shifts past midnight.
  5. Epoch values used as strings, or milliseconds where seconds were expected, which land thousands of years out.

How to fix it

Send ISO 8601 dates

YYYY-MM-DD and YYYY-MM-DD HH:MM:SS are unambiguous under every DateStyle. Most drivers send dates this way when you bind a date object rather than a string.

Parse other formats explicitly

SELECT to_date('25/12/2026', 'DD/MM/YYYY');               -- 2026-12-25
SELECT to_timestamp('25/12/2026 14:30', 'DD/MM/YYYY HH24:MI');

Or change how this session reads ambiguous dates: SET datestyle = 'ISO, DMY';. For a role or a database, ALTER ROLE … SET datestyle = 'ISO, DMY'. Prefer to_date in imports, so the code says which format it expects.

Find the bad values first

In a staging table of text, on PostgreSQL 16 and later:

SELECT id, raw_date FROM staging WHERE NOT pg_input_is_valid(raw_date, 'date');

Turn zero dates into NULL

INSERT INTO orders (id, shipped_at)
SELECT id, NULLIF(shipped_at, '0000-00-00 00:00:00')::timestamp FROM staging;

Do date arithmetic with intervals

date '2026-01-31' + interval '1 month' gives 2026-02-28 00:00:00, the last day of February, instead of an impossible 31 February. make_date(y, m, d) fails loudly on a bad combination, which is better than storing the wrong day.

Convert epoch values with to_timestamp

to_timestamp(1790845200) for seconds, to_timestamp(ms / 1000.0) for milliseconds.

Reproduce it

On PostgreSQL 18.6, with the default DateStyle of ISO, MDY:

SELECT '2026-02-30'::date;
SELECT '13/25/2026'::date;
SELECT '25/12/2026'::date;
SELECT '2026-10-11 25:00'::timestamp;
SELECT '0000-00-00'::date;
ERROR:  date/time field value out of range: "2026-02-30"
LINE 1: SELECT '2026-02-30'::date;
               ^
ERROR:  date/time field value out of range: "13/25/2026"
LINE 1: SELECT '13/25/2026'::date;
               ^
HINT:  Perhaps you need a different "DateStyle" setting.
ERROR:  date/time field value out of range: "25/12/2026"
LINE 1: SELECT '25/12/2026'::date;
               ^
HINT:  Perhaps you need a different "DateStyle" setting.
ERROR:  date/time field value out of range: "2026-10-11 25:00"
LINE 1: SELECT '2026-10-11 25:00'::timestamp;
               ^
ERROR:  date/time field value out of range: "0000-00-00"
LINE 1: SELECT '0000-00-00'::date;
               ^

After SET datestyle = 'ISO, DMY', '25/12/2026'::date returned 2026-12-25, and so did to_date('25/12/2026', 'DD/MM/YYYY') under the default setting. to_date('2026-02-30', 'YYYY-MM-DD') failed with the same message, and make_date(2026, 2, 30) with date field value out of range: 2026-02-30. '294277-01-01'::timestamp gave timestamp out of range: "294277-01-01". to_timestamp(1790845200000) (milliseconds passed as seconds) didn’t fail: it returned the year 58719.

With \set VERBOSITY verbose, psql shows the code: ERROR: 22008: date/time field value out of range: "2026-02-30". PostgreSQL 14.24 gives the same messages, with the hint spelled "datestyle" in lower case.

In Inlet

When a statement fails, Inlet shows the error at the position the server reports, with PostgreSQL’s hint about DateStyle when it sends one. With your own Anthropic API key, Ask Claude (Pro, ⌘L) can fix the failed statement; it sends the schema, the SQL and the error, never rows.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel