or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-fecha

Lightweight date formatting and parsing library designed as a modern replacement for moment.js

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/fecha@4.2.x

To install, run

npx @tessl/cli install tessl/npm-fecha@4.2.0

index.mddocs/

Fecha

Fecha is a lightweight TypeScript date formatting and parsing library (~2KB minified and gzipped) designed as a modern replacement for the parsing and formatting functionality of moment.js. It provides comprehensive date formatting and parsing capabilities with support for custom format tokens, named masks, and internationalization (i18n).

Package Information

  • Package Name: fecha
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install fecha

Core Imports

import { format, parse, setGlobalDateI18n, setGlobalDateMasks, defaultI18n } from "fecha";

For CommonJS:

const { format, parse, setGlobalDateI18n, setGlobalDateMasks, defaultI18n } = require("fecha");

Default import (contains all functions):

import fecha from "fecha";
// fecha.format, fecha.parse, fecha.defaultI18n, etc.

Basic Usage

import { format, parse } from "fecha";

// Format dates
const formatted = format(new Date(2023, 10, 20), 'YYYY-MM-DD');
// Result: '2023-11-20'

// Parse date strings
const parsed = parse('2023-11-20', 'YYYY-MM-DD');
// Result: Date object for November 20, 2023

// Use named masks
const dateStr = format(new Date(), 'mediumDate');
// Result: 'Nov 20, 2023'

// Custom format with tokens
const custom = format(new Date(2023, 10, 20, 15, 30), 'dddd MMMM Do, YYYY [at] HH:mm');
// Result: 'Monday November 20th, 2023 at 15:30'

Architecture

Fecha is built around several key architectural components that work together to provide robust date formatting and parsing:

  • Token System: Uses regular expressions to identify and process format tokens (YYYY, MM, DD, etc.) in format strings. The core token regex matches various patterns and replaces them with corresponding values or parsing logic.

  • Format Pipeline: Formatting uses a formatFlags object that maps each token to a transformation function. These functions receive a Date object and i18n settings, returning the appropriate string representation.

  • Parse Pipeline: Parsing reverses this process using parseFlags that map tokens to regex patterns and parsing functions. The system builds a composite regex from the format string and extracts values to construct a Date object.

  • Internationalization Layer: Global i18n settings (globalI18n) can be overridden per-call. The system merges settings using the assign utility, allowing flexible localization without affecting global state.

  • Mask Registry: Named format shortcuts are stored in globalMasks and resolved before token processing. This allows reusable format definitions like 'shortDate' and 'isoDateTime'.

  • Validation Engine: Date parsing includes comprehensive validation that checks field ranges, validates constructed dates against input fields, and handles timezone offset calculations.

Capabilities

Date Formatting

Convert Date objects or timestamps into formatted strings using custom format tokens or predefined masks.

/**
 * Format a date into a string using format tokens or named masks
 * @param dateObj - Date object or timestamp to format
 * @param mask - Format string (defaults to global default), can be custom format or named mask
 * @param i18n - Optional internationalization settings override
 * @returns Formatted date string
 * @throws Error for invalid Date objects
 */
function format(
  dateObj: Date,
  mask?: string,
  i18n?: I18nSettingsOptional
): string;

Usage Examples:

import { format } from "fecha";

// Basic formatting
format(new Date(2023, 10, 20), 'YYYY-MM-DD'); // '2023-11-20'
format(new Date(2023, 5, 15, 14, 30, 25), 'YYYY-MM-DD HH:mm:ss'); // '2023-06-15 14:30:25'

// Named masks
format(new Date(2023, 10, 20), 'shortDate'); // '11/20/23'
format(new Date(2023, 10, 20), 'mediumDate'); // 'Nov 20, 2023'
format(new Date(2023, 10, 20), 'isoDate'); // '2023-11-20'

// Custom format with literals
format(new Date(2023, 10, 20, 15, 30), '[Today is] dddd, MMMM Do'); // 'Today is Monday, November 20th'

// Timestamps work too
format(1700482800000, 'YYYY-MM-DD'); // '2023-11-20'

Date Parsing

Parse date strings into JavaScript Date objects using format patterns with validation.

/**
 * Parse a date string into a JavaScript Date object
 * @param dateStr - Date string to parse  
 * @param format - Parse format (required), can be custom format or named mask
 * @param i18n - Optional internationalization settings override
 * @returns Date object or null if parsing fails or date is invalid
 * @throws Error for invalid format strings or missing format parameter
 */
function parse(
  dateStr: string,
  format: string,
  i18n?: I18nSettingsOptional
): Date | null;

Usage Examples:

import { parse } from "fecha";

// Basic parsing
parse('2023-11-20', 'YYYY-MM-DD'); // Date object for November 20, 2023
parse('15:30:25', 'HH:mm:ss'); // Date object for today at 15:30:25

// Named masks
parse('11/20/23', 'shortDate'); // Date object for November 20, 2023
parse('Nov 20, 2023', 'mediumDate'); // Date object for November 20, 2023

// Complex formats
parse('Monday November 20th, 2023', 'dddd MMMM Do, YYYY'); // Date object
parse('3:30 PM', 'h:mm A'); // Date object for today at 15:30

// Invalid dates return null
parse('2023-13-45', 'YYYY-MM-DD'); // null (invalid month/day)
parse('invalid', 'YYYY-MM-DD'); // null (doesn't match format)

Internationalization

Configure global internationalization settings or provide per-call overrides for different languages and locales.

/**
 * Set global internationalization settings 
 * @param i18n - Partial I18N settings to merge with current global settings
 * @returns Updated global I18N settings
 */
function setGlobalDateI18n(i18n: I18nSettingsOptional): I18nSettings;

/**
 * Default internationalization settings with English names
 */
const defaultI18n: I18nSettings;

Usage Examples:

import { setGlobalDateI18n, format, parse } from "fecha";

// Set Spanish locale globally
setGlobalDateI18n({
  monthNames: [
    'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
    'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'
  ],
  dayNames: [
    'domingo', 'lunes', 'martes', 'miércoles', 
    'jueves', 'viernes', 'sábado'
  ]
});

// Now formatting uses Spanish names
format(new Date(2023, 10, 20), 'dddd, MMMM DD'); // 'lunes, noviembre 20'

// Per-call override (doesn't affect global settings)
const frenchFormat = format(new Date(2023, 10, 20), 'MMMM', {
  monthNames: [
    'janvier', 'février', 'mars', 'avril', 'mai', 'juin',
    'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'
  ]
}); // 'novembre'

// Parsing with custom i18n
parse('20 de noviembre de 2023', 'DD de MMMM de YYYY', {
  monthNames: [
    'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
    'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'
  ]
}); // Date object for November 20, 2023

Custom Format Masks

Define and use custom named format masks for reusable date formats across your application.

/**
 * Set global date format masks/shortcuts
 * @param masks - Object with mask names as keys and format strings as values
 * @returns Updated global masks object  
 */
function setGlobalDateMasks(masks: { [key: string]: string }): { [key: string]: string };

Usage Examples:

import { setGlobalDateMasks, format } from "fecha";

// Define custom masks
setGlobalDateMasks({
  apiDate: 'YYYY-MM-DDTHH:mm:ssZ',
  logFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
  displayDate: 'MMM DD, YYYY [at] h:mm A'
});

// Use custom masks
const now = new Date();
format(now, 'apiDate'); // '2023-11-20T15:30:25Z'
format(now, 'logFormat'); // '2023-11-20 15:30:25.123'
format(now, 'displayDate'); // 'Nov 20, 2023 at 3:30 PM'

// Built-in masks are still available
format(now, 'shortDate'); // '11/20/23'
format(now, 'isoDateTime'); // '2023-11-20T15:30:25Z'

Utility Functions

Helper functions for object manipulation and type safety.

/**
 * Object assignment utility with type safety (similar to Object.assign)
 */
function assign<A>(a: A): A;
function assign<A, B>(a: A, b: B): A & B;
function assign<A, B, C>(a: A, b: B, c: C): A & B & C;
function assign<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;

Format Tokens

Comprehensive list of format tokens supported for both formatting and parsing:

Date Tokens

  • D: Day of month (1-31)
  • DD: Zero-padded day of month (01-31)
  • Do: Day with ordinal suffix (1st, 2nd, 3rd...)
  • d: Day of week (0-6, Sunday=0)
  • dd: Zero-padded day of week (00-06)
  • ddd: Short day name (Sun, Mon...)
  • dddd: Full day name (Sunday, Monday...)

Month Tokens

  • M: Month (1-12)
  • MM: Zero-padded month (01-12)
  • MMM: Short month name (Jan, Feb...)
  • MMMM: Full month name (January, February...)

Year Tokens

  • YY: Two-digit year (70, 71...)
  • YYYY: Four-digit year (1970, 1971...)

Time Tokens

  • H: 24-hour format hour (0-23)
  • HH: Zero-padded 24-hour hour (00-23)
  • h: 12-hour format hour (1-12)
  • hh: Zero-padded 12-hour hour (01-12)
  • m: Minutes (0-59)
  • mm: Zero-padded minutes (00-59)
  • s: Seconds (0-59)
  • ss: Zero-padded seconds (00-59)
  • S: Fractional second (0-9)
  • SS: Two-digit fractional second (00-99)
  • SSS: Three-digit milliseconds (000-999)
  • a: Lowercase AM/PM (am/pm)
  • A: Uppercase AM/PM (AM/PM)

Timezone Tokens

  • Z: Timezone offset with colon (-07:00)
  • ZZ: Timezone offset without colon (-0700)

Literals

Use square brackets to include literal text in format strings:

  • [text]: Literal text that won't be interpreted as tokens

Built-in Format Masks

Pre-defined format masks for common date formats:

  • default: "ddd MMM DD YYYY HH:mm:ss"
  • shortDate: "M/D/YY"
  • mediumDate: "MMM D, YYYY"
  • longDate: "MMMM D, YYYY"
  • fullDate: "dddd, MMMM D, YYYY"
  • isoDate: "YYYY-MM-DD"
  • isoDateTime: "YYYY-MM-DDTHH:mm:ssZ"
  • shortTime: "HH:mm"
  • mediumTime: "HH:mm:ss"
  • longTime: "HH:mm:ss.SSS"

Types

/**
 * Complete internationalization settings interface
 */
interface I18nSettings {
  /** AM/PM labels */
  amPm: [string, string];
  /** Full day names array (Sunday through Saturday) */
  dayNames: Days;
  /** Short day names array (3 characters each) */
  dayNamesShort: Days;
  /** Full month names array (January through December) */
  monthNames: Months;
  /** Short month names array (3 characters each) */
  monthNamesShort: Months;
  /** Function to generate ordinal day suffixes (1st, 2nd, 3rd, etc.) */
  DoFn(dayOfMonth: number): string;
}

/**
 * Partial internationalization settings for optional overrides
 */
type I18nSettingsOptional = Partial<I18nSettings>;

/**
 * Tuple type for 7 day names (Sunday through Saturday)
 */
type Days = [string, string, string, string, string, string, string];

/**
 * Tuple type for 12 month names (January through December)
 */
type Months = [
  string, string, string, string, string, string,
  string, string, string, string, string, string
];

Error Handling

  • format() throws Error for invalid Date objects or timestamps
  • parse() throws Error for invalid format strings or missing format parameter
  • parse() returns null for strings that don't match the format or represent invalid dates
  • Both functions validate date ranges and return null/throw for out-of-range values
  • Parsing includes validation that prevents dates like February 29th on non-leap years

Error Examples:

import { format, parse } from "fecha";

// Format errors
format(new Date('invalid')); // Throws Error: "Invalid Date pass to format"
format(null); // Throws Error

// Parse errors  
parse('2023-11-20'); // Throws Error: "Invalid format in fecha parse" (missing format)
parse('2023-11-20', null); // Throws Error: "Invalid format in fecha parse"

// Parse returns null for invalid data
parse('2023-13-45', 'YYYY-MM-DD'); // null (invalid month)
parse('not-a-date', 'YYYY-MM-DD'); // null (doesn't match format)
parse('2023-02-29', 'YYYY-MM-DD'); // null (not a leap year)