API reference › @evolu/common › Type › PlainDateIso

const PlainDateIso: brand(
  "PlainDateIso",
  String,
  (value: string) => {
    const match = /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/u.exec(
      value,
    );

    if (match !== null) {
      const [, year, month, day] = match;

      if (
        globalThis.Number(day) <=
        daysInMonth(globalThis.Number(year), globalThis.Number(month))
      ) {
        return ok();
      }
    }

    return err<PlainDateIsoError>({ type: "PlainDateIso", value });
  },
  formatPlainDateIsoError,
);

Defined in: packages/common/src/Type.ts:6139

Calendar date String in the ISO 8601 YYYY-MM-DD format.

It is an RFC 3339 full-date in the proleptic Gregorian calendar, with years from 0000 through 9999 like DateIso. The date must exist, so 2023-02-29 and 2023-04-31 are rejected, while the leap day 2024-02-29 is accepted. Extended years, missing leading zeros, and times are rejected.

A plain date has no time zone, so it names a calendar day, such as a birthday or a due date, rather than a moment. Converting a DateIso to a plain date requires choosing a time zone, which is an application decision. The fixed-width form sorts chronologically as text.

Example

import { assertEqual, assertErr, assertOk, PlainDateIso } from "@evolu/common";

assertOk(PlainDateIso.fromUnknown("2024-02-29"), "2024-02-29");

const invalid = PlainDateIso.fromUnknown("2023-02-29");
assertErr(invalid, { type: "PlainDateIso", value: "2023-02-29" });
assertEqual(
  PlainDateIso.formatError(invalid.error),
  'The value "2023-02-29" is not a valid calendar date in the YYYY-MM-DD format.',
);