UNPKG

@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
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 };