Date/time out of range in JavaScript (and the PostgreSQL pq error)

Tech reviewed: Deepak Prasad
Date/time out of range in JavaScript (and the PostgreSQL pq error)

Search traffic for “date/time field value out of range” splits into two topics:

  1. JavaScript — you have Date values (or strings you turn into dates) and want to know if they fall inside an allowed window.
  2. PostgreSQL (and similar databases) — the server returns pq: date/time field out of range: "…" when a bound parameter cannot be parsed as a valid timestamp (often locale date order vs ISO-8601).

This article covers both, in that order.

For formatting valid dates for display, prefer Intl.DateTimeFormat — see JavaScript date formatting with Intl.

Tested on: Node.js v22 on Linux for the JavaScript snippets. PostgreSQL messages depend on server version and datestyle settings.


How Date comparison works in JavaScript

Date objects compare by their underlying UTC millisecond value. You usually define a start and end boundary and test whether a candidate lies strictly inside, outside, or on the edge.

javascript
const userOneDOB = new Date("2001-04-30");
const userTwoDOB = new Date("2005-12-01");

const start = new Date("1960-01-01");
const end = new Date("2004-10-04");

const usersDOB = [userOneDOB, userTwoDOB];

for (const dob of usersDOB) {
  if (dob > start && dob < end) {
    console.log("in range");
  } else {
    console.log("out of range");
  }
}
Output

The loop prints in range for April 2001 (between the bounds) and out of range for December 2005 (after the end boundary).

Use >= / <= instead of > / < if the boundaries themselves should count as valid.


Building dates and reading parts

new Date() captures “now”. Calendar parts use 0-based months (getMonth() returns 0 for January — a frequent bug when you log day/month/year manually).

javascript
const date = new Date("2022-10-03T12:09:58.926Z");
console.log(date.toISOString());

const currentYear = date.getUTCFullYear();
const currentMonth = date.getUTCMonth(); // 0-based
const currentDay = date.getUTCDate();

console.log({ currentYear, currentMonth, currentDay });
Output

You should see an ISO timestamp string, then an object like { currentYear: 2022, currentMonth: 9, currentDay: 3 }—note getUTCMonth() is 0-based (October → 9).

Timestamps since the Unix epoch:

javascript
const todayDate = new Date();
console.log(todayDate.getTime(), Date.now());
Output

Both values are large positive integers (milliseconds since the Unix epoch); they are usually very close when logged back-to-back.

Values before 1970 produce negative millisecond counts; that is normal.


PostgreSQL: pq: date/time field out of range

If you see:

pq: date/time field out of range: "22/02/2022"

PostgreSQL is telling you the literal does not match the date style you passed in. Common causes:

  • Day-first vs month-first strings (DD/MM/YYYY vs MM/DD/YYYY) without an explicit SET datestyle or without using ISO-8601 (YYYY-MM-DD).
  • Passing a string with the wrong separator or ambiguous ordering.

Fix: send parameters in ISO 8601 (2022-02-22) or cast explicitly (to_date(..., 'DD/MM/YYYY')) so the server and client agree on the format. See also this Stack Overflow discussion.


Summary

  • In JavaScript, compare Date objects (or their milliseconds) to start/end boundaries for “in range” logic.
  • Remember getMonth() is 0-based when you format or validate calendar parts.
  • For PostgreSQL, treat date/time field out of range as a format / locale problem first—standardize on ISO-8601 strings or explicit to_date patterns.

References

Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital …

  • JavaScript
  • Web Design