chronia

parse

Overview

The parse function converts a date string into a Date object according to a specified format pattern. It uses Unicode format tokens (matching those used in format()) to parse date strings with support for localization, reference dates for missing components, and comprehensive error handling that returns Invalid Date objects instead of throwing exceptions.

Signature

function parse(
  dateString: string,
  pattern: string,
  options?: {
    locale?: Locale;
    referenceDate?: Date;
  },
): Date;

Parameters

Parameter Type Description
dateString string The date string to parse
pattern string The format pattern using Unicode tokens (e.g., "yyyy-MM-dd HH:mm:ss")
options object (optional) Optional parsing configuration
options.locale Locale (optional) Localization object for parsing locale-specific text (month names, day periods, weekdays)
options.referenceDate Date (optional) Reference date for missing components (defaults to current date)

Return Value

Type Description
Date Returns a valid Date object if parsing succeeds, or an Invalid Date object (with NaN time value) if parsing fails

Description

The parse function parses date strings using flexible format patterns with Unicode tokens, providing the inverse operation to format(). It validates arguments before processing, supports localized parsing, and handles missing date components by using a reference date. The function never throws exceptions, instead returning an Invalid Date object when parsing fails, allowing developers to check validity using isValid().

Specification

Returns valid Date object when:

Returns Invalid Date object when:

Behavior Notes

Supported Parse Tokens

Year Tokens

Month Tokens

Day Tokens

Hour Tokens

Minute Tokens

Second Tokens

Millisecond Tokens

Day Period Tokens

Era Tokens

Weekday Tokens

Day of Year Tokens

Special Parsing Behaviors

Two-Digit Year (yy)

12-Hour Format Conversion

Millisecond Scaling

Day of Year Calculation

Weekday Parsing

Use Cases

Usage Examples

Basic Date Parsing

import { parse } from "chronia";

// ISO 8601-like format
const date1 = parse("2024-01-15", "yyyy-MM-dd");
// Returns: Date(2024, 0, 15, 0, 0, 0, 0)

// US format
const date2 = parse("01/15/2024", "MM/dd/yyyy");
// Returns: Date(2024, 0, 15, 0, 0, 0, 0)

// European format
const date3 = parse("15.01.2024", "dd.MM.yyyy");
// Returns: Date(2024, 0, 15, 0, 0, 0, 0)

// Variable padding
const date4 = parse("1/5/2024", "M/d/yyyy");
// Returns: Date(2024, 0, 5, 0, 0, 0, 0)

Date and Time Parsing

import { parse } from "chronia";

// Date with 24-hour time
const date1 = parse("15/01/2024 14:30", "dd/MM/yyyy HH:mm");
// Returns: Date(2024, 0, 15, 14, 30, 0, 0)

// Date with 12-hour time and AM/PM
const date2 = parse("01/15/2024 2:30 PM", "MM/dd/yyyy h:mm a");
// Returns: Date(2024, 0, 15, 14, 30, 0, 0)

// Time with seconds and milliseconds
const date3 = parse("2024-01-15T14:30:45.123", "yyyy-MM-dd'T'HH:mm:ss.SSS");
// Returns: Date(2024, 0, 15, 14, 30, 45, 123)

// Time only (uses current date)
const date4 = parse("14:30:00", "HH:mm:ss");
// Returns: Date with current date, time set to 14:30:00

Using Reference Date

import { parse } from "chronia";

// Parse time only with specific reference date
const refDate = new Date(2023, 5, 10); // June 10, 2023
const date1 = parse("14:30", "HH:mm", { referenceDate: refDate });
// Returns: Date(2023, 5, 10, 14, 30, 0, 0)

// Parse partial date (month and day only)
const date2 = parse("01-15", "MM-dd", { referenceDate: refDate });
// Returns: Date(2023, 0, 15, 0, 0, 0, 0) - Uses year from refDate

Localized Parsing

import { parse } from "chronia";
import { enUS } from "chronia/locale/en-US";
import { ja } from "chronia/locale/ja";

// English month names
const date1 = parse("January 15, 2024", "MMMM dd, yyyy", { locale: enUS });
// Returns: Date(2024, 0, 15)

// Japanese date format
const date2 = parse("2024年1月15日", "yyyy'年'M'月'd'日'", { locale: ja });
// Returns: Date(2024, 0, 15)

// Weekday with date (English)
const date3 = parse("Monday, 2024-01-15", "EEEE, yyyy-MM-dd", { locale: enUS });
// Returns: Date(2024, 0, 15)

Literal Text in Patterns

import { parse } from "chronia";

// Literal text in pattern
const date1 = parse("Year 2024, Month 01", "'Year' yyyy', Month' MM");
// Returns: Date(2024, 0, 1, 0, 0, 0, 0)

// Escaped single quote
const date2 = parse("It's 2024", "'It''s' yyyy");
// Returns: Date(2024, current month, current day)

// ISO 8601 with T separator
const date3 = parse("2024-01-15T14:30:00", "yyyy-MM-dd'T'HH:mm:ss");
// Returns: Date(2024, 0, 15, 14, 30, 0, 0)

Special Format Parsing

import { parse } from "chronia";

// Two-digit year parsing
const date1 = parse("99-12-31", "yy-MM-dd");
// Returns: Date(1999, 11, 31) - 99 maps to 1999

const date2 = parse("00-01-01", "yy-MM-dd");
// Returns: Date(2000, 0, 1) - 00 maps to 2000

// Day of year
const date3 = parse("2024-032", "yyyy-DDD");
// Returns: Date(2024, 1, 1) - February 1st (32nd day of 2024)

// Era parsing (BC dates)
const date4 = parse("100 BC", "yyyy G");
// Returns: Date(-99, 0, 1) - Year 100 BC

Error Handling and Validation

import { parse, isValid } from "chronia";

// Invalid input returns Invalid Date
const invalid1 = parse("invalid-text", "yyyy-MM-dd");
// Returns: Invalid Date (isNaN(invalid1.getTime()) === true)

// Mismatched pattern
const invalid2 = parse("2024-01-15", "dd/MM/yyyy");
// Returns: Invalid Date

// Out of range values
const invalid3 = parse("2024-13-01", "yyyy-MM-dd");
// Returns: Invalid Date (month 13 is invalid)

// Extra characters
const invalid4 = parse("2024-01-15extra", "yyyy-MM-dd");
// Returns: Invalid Date

// Proper validation pattern
function parseUserDate(input: string): Date | null {
  const parsed = parse(input, "yyyy-MM-dd");
  return isValid(parsed) ? parsed : null;
}

const result = parseUserDate("2024-01-15");
if (result) {
  console.log("Parsed successfully:", result);
} else {
  console.log("Parsing failed");
}

Form Validation

import { parse, isValid, format } from "chronia";

function validateAndFormatDate(input: string, inputFormat: string): string {
  const parsed = parse(input, inputFormat);

  if (!isValid(parsed)) {
    return "Invalid date";
  }

  return format(parsed, "yyyy-MM-dd");
}

// Various input formats normalized to ISO format
validateAndFormatDate("01/15/2024", "MM/dd/yyyy");
// Returns: '2024-01-15'

validateAndFormatDate("15.01.2024", "dd.MM.yyyy");
// Returns: '2024-01-15'

validateAndFormatDate("not-a-date", "yyyy-MM-dd");
// Returns: 'Invalid date'

API Data Processing

import { parse, isValid } from "chronia";

interface ApiResponse {
  id: string;
  createdAt: string; // Format: "dd/MM/yyyy HH:mm:ss"
  updatedAt: string; // Format: "dd/MM/yyyy HH:mm:ss"
}

function processApiResponse(response: ApiResponse) {
  const created = parse(response.createdAt, "dd/MM/yyyy HH:mm:ss");
  const updated = parse(response.updatedAt, "dd/MM/yyyy HH:mm:ss");

  if (!isValid(created) || !isValid(updated)) {
    throw new Error("Invalid date format in API response");
  }

  return {
    id: response.id,
    createdAt: created,
    updatedAt: updated,
  };
}

// Process API data
const apiData = {
  id: "123",
  createdAt: "15/01/2024 14:30:00",
  updatedAt: "15/01/2024 16:45:00",
};

const processed = processApiResponse(apiData);
// Returns: { id: "123", createdAt: Date(...), updatedAt: Date(...) }

Round-Trip Conversion

import { parse, format } from "chronia";

const pattern = "yyyy-MM-dd HH:mm:ss";
const original = new Date(2024, 0, 15, 14, 30, 45);

// Convert to string and back to Date
const formatted = format(original, pattern);
// Returns: "2024-01-15 14:30:45"

const parsed = parse(formatted, pattern);
// Returns: Date(2024, 0, 15, 14, 30, 45)

// Verify round-trip equality
original.getTime() === parsed.getTime();
// Returns: true