@statezero/core
Version:
The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate
100 lines (99 loc) • 4.52 kB
JavaScript
import { format, parse, parseISO } from 'date-fns';
/**
* Date parsing utilities for handling Django style date formats
*/
export class DateParsingHelpers {
/**
* Parse a date value using Django's format settings
* @param {string|Date} value - The date value to parse
* @param {string} fieldName - Name of the field (for schema lookup)
* @param {Object} schema - The model schema containing format info
* @returns {Date|null} - Parsed Date object or null if invalid
*/
static parseDate(value, fieldName, schema) {
if (!value)
return null;
// If already a Date object, return as-is
if (value instanceof Date)
return value;
const fieldFormat = schema.properties[fieldName].format;
if (!["date", "date-time"].includes(fieldFormat)) {
throw new Error(`Only date and date-time fields can be processed to JS date objects. ${fieldName} has format ${fieldFormat}`);
}
// Get field-specific format from schema
const formatStrings = {
'date': schema.date_format,
'date-time': schema.datetime_format
};
const dateFormat = formatStrings[fieldFormat];
// Check if format is supported
if (dateFormat && !this.SUPPORTED_FORMATS.hasOwnProperty(dateFormat)) {
throw new Error(`Unsupported date format "${dateFormat}" for field ${fieldName}. Supported formats: ${Object.keys(this.SUPPORTED_FORMATS).join(', ')}`);
}
try {
// Handle ISO format (Django's default)
if (!dateFormat || dateFormat === 'iso-8601') {
return parseISO(value);
}
// Handle supported Django formats
const dateFnsFormat = this.SUPPORTED_FORMATS[dateFormat];
return parse(value, dateFnsFormat, new Date());
}
catch (error) {
console.error(`Failed to parse date "${value}" with format "${dateFormat}"`, error);
return null;
}
}
/**
* Serialize a date using the field's configured format
* @param {Date} date - The date to serialize
* @param {string} fieldName - Name of the field (for schema lookup)
* @param {Object} schema - The model schema containing format info
* @returns {string|null} - Formatted date string or null if invalid
*/
static serializeDate(date, fieldName, schema) {
if (!date || !(date instanceof Date) || isNaN(date.getTime())) {
return date;
}
const fieldFormat = schema.properties[fieldName].format;
if (!["date", "date-time"].includes(fieldFormat)) {
throw new Error(`Only date and date-time fields can be processed to JS date objects. ${fieldName} has format ${fieldFormat}`);
}
// Get field-specific format from schema
const formatStrings = {
'date': schema.date_format,
'date-time': schema.datetime_format
};
const dateFormat = formatStrings[fieldFormat];
// Check if format is supported
if (dateFormat && !this.SUPPORTED_FORMATS.hasOwnProperty(dateFormat)) {
throw new Error(`Unsupported date format "${dateFormat}" for field ${fieldName}. Supported formats: ${Object.keys(this.SUPPORTED_FORMATS).join(', ')}`);
}
try {
// Handle ISO format (Django's default)
if (!dateFormat || dateFormat === 'iso-8601') {
return date.toISOString();
}
// Handle supported Django formats
const dateFnsFormat = this.SUPPORTED_FORMATS[dateFormat];
return format(date, dateFnsFormat);
}
catch (error) {
console.error(`Failed to format date with format "${dateFormat}"`, error);
return date.toISOString(); // Fallback to ISO format
}
}
}
// Supported Django strftime formats and their date-fns equivalents
DateParsingHelpers.SUPPORTED_FORMATS = {
'iso-8601': null, // Special case - use parseISO/toISOString
'%Y-%m-%d': 'yyyy-MM-dd', // 2024-12-31
'%Y-%m-%d %H:%M:%S': 'yyyy-MM-dd HH:mm:ss', // 2024-12-31 14:30:45
'%d/%m/%Y': 'dd/MM/yyyy', // 31/12/2024
'%m/%d/%Y': 'MM/dd/yyyy', // 12/31/2024
'%Y/%m/%d': 'yyyy/MM/dd', // 2024/12/31
'%d-%m-%Y': 'dd-MM-yyyy', // 31-12-2024
'%m-%d-%Y': 'MM-dd-yyyy', // 12-31-2024
'%B %d, %Y': 'MMMM dd, yyyy', // December 31, 2024
'%d %B %Y': 'dd MMMM yyyy', // 31 December 2024
};