@salesflare/date-format-infer
v0.3.0
Published
Infer date formats from a list of date strings. Handles ambiguous formats (DD/MM vs MM/DD) by analyzing multiple samples.
Readme
date-format-infer
A lightweight library to infer date formats from a list of date strings. Useful for data import features where date columns need to be normalized to a standard format (e.g., ISO 8601).
The Problem
When importing data with date columns, you often encounter ambiguous formats:
- Is
01/02/2023January 2nd (MM/DD/YYYY) or February 1st (DD/MM/YYYY)? - The library solves this by analyzing multiple date values from a column to determine the format.
Installation
npm install date-format-inferQuick Start
const { inferDateFormat, convertToISO } = require('date-format-infer');
// Analyze dates from a column
const result = inferDateFormat(['25/12/2023', '15/01/2024', '30/06/2023']);
if (result.confident) {
console.log(`Format: ${result.format}`); // 'DD/MM/YYYY'
// Convert to ISO format
const iso = convertToISO('25/12/2023', result.format);
console.log(iso); // '2023-12-25'
} else {
console.log('Ambiguous, could be:', result.possibleFormats);
}How It Works
- Tests each date string against known format patterns
- Eliminates formats that don't match
- When a date has
day > 12, it disambiguates DD vs MM position - Returns early when confident (single format remaining)
- Falls back to natural language parsing via chrono-node if enabled
API
inferDateFormat(dates, options?)
Infers the date format from an array of date strings.
interface InferResult {
format: string | null; // The inferred format (e.g., 'DD/MM/YYYY')
possibleFormats: string[]; // All formats that could match
confident: boolean; // True if format is unambiguous
isNaturalLanguage: boolean; // True if dates are natural language
}
interface InferOptions {
maxSamples?: number; // Max dates to check (default: 100)
allowNaturalLanguage?: boolean; // Try chrono-node fallback (default: true)
locale?: SupportedLocale; // Locale for natural language parsing (default: 'en')
}
type SupportedLocale = 'en' | 'nl' | 'fr' | 'de' | 'es' | 'pt' | 'ja' | 'zh' | 'ru' | 'uk' | 'it' | 'sv';Examples:
// Unambiguous (day > 12 disambiguates)
inferDateFormat(['25/12/2023', '30/06/2024']);
// { format: 'DD/MM/YYYY', confident: true, ... }
// Ambiguous (all days ≤ 12)
inferDateFormat(['01/02/2023', '03/04/2024']);
// { format: null, confident: false, possibleFormats: ['DD/MM/YYYY', 'MM/DD/YYYY'] }
// Natural language
inferDateFormat(['next Monday', 'last Friday']);
// { format: null, confident: true, isNaturalLanguage: true }
// Natural language in other languages (French)
inferDateFormat(['13 Janvier 2026', '14 Février 2026'], { locale: 'fr' });
// { format: null, confident: true, isNaturalLanguage: true }parseDate(dateStr, pattern)
Parse a date string using a specific format pattern.
parseDate('25/12/2023', 'DD/MM/YYYY');
// { year: 2023, month: 12, day: 25 }
parseDate('25/12/2023 14:30:00', 'DD/MM/YYYY HH:mm:ss');
// { year: 2023, month: 12, day: 25, hour: 14, minute: 30, second: 0 }convertToISO(dateStr, pattern)
Convert a date string to ISO format using the specified pattern.
convertToISO('25/12/2023', 'DD/MM/YYYY');
// '2023-12-25'
convertToISO('25/12/2023 14:30:00', 'DD/MM/YYYY HH:mm:ss');
// '2023-12-25T14:30:00'parseNaturalDate(dateStr, locale?) / convertNaturalToISO(dateStr, locale?)
Parse natural language dates using chrono-node with multi-language support.
The locale parameter specifies a preferred language to try first (after English). The parser automatically falls back through all supported locales until one succeeds.
// English (default)
parseNaturalDate('December 25, 2023 at 2:30 PM');
// { year: 2023, month: 12, day: 25, hour: 14, minute: 30 }
convertNaturalToISO('December 25, 2023');
// '2023-12-25T12:00:00.000'
// French
parseNaturalDate('13 Janvier 2026', 'fr');
// { year: 2026, month: 1, day: 13 }
convertNaturalToISO('13 Janvier 2026', 'fr');
// '2026-01-13...'
// Spanish
parseNaturalDate('13 Enero 2026', 'es');
// { year: 2026, month: 1, day: 13 }
// German (note: requires period after day number)
parseNaturalDate('13. Januar 2026', 'de');
// { year: 2026, month: 1, day: 13 }
// Dutch (note: lowercase month names)
parseNaturalDate('13 januari 2026', 'nl');
// { year: 2026, month: 1, day: 13 }Supported locales: en, nl, fr, de, es, pt, ja, zh, ru, uk, it, sv
Note: Each language may have specific formatting requirements (e.g., German requires a period after the day number, Dutch is case-sensitive for month names).
Supported Formats
Date Only
| Pattern | Example |
|---------|---------|
| YYYY-MM-DD | 2023-12-25 |
| DD/MM/YYYY | 25/12/2023 |
| MM/DD/YYYY | 12/25/2023 |
| DD/MM/YY | 25/12/23 |
| MM/DD/YY | 12/25/23 |
| DD MMM YYYY | 25 Dec 2023 |
| MMM DD YYYY | Dec 25, 2023 |
| YYYYMMDD | 20231225 |
Date with Time
| Pattern | Example |
|---------|---------|
| YYYY-MM-DDTHH:mm:ss | 2023-12-25T14:30:00 |
| YYYY-MM-DDTHH:mm:ss.SSS | 2023-12-25T14:30:00.123 |
| DD/MM/YYYY HH:mm | 25/12/2023 14:30 |
| DD/MM/YYYY HH:mm:ss | 25/12/2023 14:30:00 |
| DD/MM/YYYY h:mm A | 25/12/2023 2:30 PM |
| MM/DD/YYYY HH:mm:ss | 12/25/2023 14:30:00 |
With Timezone
| Pattern | Example |
|---------|---------|
| YYYY-MM-DDTHH:mm:ssZ | 2023-12-25T14:30:00Z |
| YYYY-MM-DDTHH:mm:ssZ | 2023-12-25T14:30:00+05:30 |
| YYYY-MM-DDTHH:mm:ss.SSSZ | 2023-12-25T14:30:00.123Z |
Note: Separators (/, -, .) are treated equivalently.
TypeScript
Full TypeScript support with exported types:
import {
inferDateFormat,
parseDate,
convertToISO,
parseNaturalDate,
convertNaturalToISO,
InferResult,
InferOptions,
ParsedDate,
SupportedLocale
} from 'date-format-infer';Assumptions
- ISO 8601 is unambiguous:
YYYY-MM-DDis assumed to be year-month-day (not year-day-month) - Consistent column format: All dates in a column use the same format
- Reasonable dates: Years are between 1-9999, validated for days in month
License
MIT
