A modern, compact date utilities library designed for React Native and web applications. Features comprehensive locale support with Arabic numerals, intelligent error handling, and production-ready logging. Efficient alternative to heavy date libraries.
- Overview
- Installation
- Quick Start
- Web Application Support
- Error Handling
- Multi-Locale Support
- API Reference
- Advanced Features
- Performance Benefits
- Testing
- Additional Resources
- Contributing
- License
A modern, performant date utilities library that replaces heavy date libraries with a compact, feature-rich alternative:
- 🚀 Compact bundle size (Small library with tree-shaking)
- 🌍 Dynamic locale registration - Add new locales at runtime
- 📝 Custom locale files - Support for user-provided locale configurations
- 🔢 Full Arabic locale support - Arabic numerals and RTL support
- ⚙️ Centralized locale management - Single source of truth for app locale
- 📱 Optimized for React Native - Built specifically for mobile performance
- 🌐 Web Application Ready - Perfect for React, Vue, Angular, and vanilla JS
- 🎯 Clean options object API - Modern destructuring syntax for better DX
- 🛡️ Comprehensive error handling - Safe handling of invalid dates with fallbacks
- 🚀 App initialization configuration - Configure everything during app startup
# Using npm
npm install date-core
# Using yarn
yarn add date-core
# Using pnpm
pnpm add date-core
// In your App.js or index.js
import { initializeApp } from 'date-core'
// Initialize with complete configuration
const result = initializeApp({
// Locale configuration
locale: 'ar', // Arabic locale with RTL support
// Error handling configuration (all optional)
logErrors: true,
fallbackDate: new Date(),
fallbackString: 'Invalid Date',
messages: {
invalidDate: 'Custom: Invalid date provided',
invalidDateNull: 'Custom: Date cannot be null',
},
// Additional configuration
strictMode: false,
validateDates: true,
})
console.log('App initialized:', result)
// Console Output:
// App initialized: {
// success: true,
// locale: 'ar',
// fallbackDate: Date object,
// errorConfig: { logErrors: true, ... }
// }
import {
formatDateLocalized,
getRelativeTimeLocalized,
getDayName,
formatLongDate,
isToday,
} from 'date-core'
// Basic formatting
const date = formatDateLocalized(new Date()) // "15 January 2024"
const dayName = getDayName(new Date(), { format: 'short' }) // "Mon"
const relativeTime = getRelativeTimeLocalized(someDate) // "2 hours ago"
// Advanced formatting
const longDate = formatLongDate(new Date(), { format: 'LLLL' }) // "Monday, 15 January 2024 14:30"
const isTodayCheck = isToday(someDate) // true/false
// Arabic locale example
const arabicDate = formatDateLocalized(new Date(), { locale: 'ar' }) // "١٥ يناير ٢٠٢٤"
// Smart formatting examples
formatDateSmart(new Date()) // "Today" (if today)
formatDateSmart(yesterday) // "Yesterday"
formatDateSmart(tomorrow) // "Tomorrow"
formatDateSmart(otherDate) // "15 January 2024" (if not today/yesterday/tomorrow)
// Arabic smart formatting
formatDateSmart(new Date(), { locale: 'ar' }) // "اليوم" (if today)
formatDateSmart(yesterday, { locale: 'ar' }) // "أمس"
formatDateSmart(tomorrow, { locale: 'ar' }) // "غداً"
Perfect for React, Vue, Angular, and vanilla JavaScript applications:
import { initializeApp, formatDateLocalized } from 'date-core'
// Initialize
initializeApp({ locale: 'en' })
// Use in component
function DateComponent() {
const date = new Date()
const locale = 'en'
return (
<div>
<p>Date: {formatDateLocalized(date)}</p>
<p>Locale: {locale}</p>
</div>
// Output: Date: 15 January 2024, Locale: en
)
}
// main.js
import { initializeApp } from 'date-core'
initializeApp({ locale: 'en' })
// Component
import { formatDateLocalized } from 'date-core'
export default {
data() {
return { date: new Date(), locale: 'en' }
},
computed: {
formattedDate() {
return formatDateLocalized(this.date)
// Output: "15 January 2024"
},
},
}
import { initializeApp, formatDateLocalized } from 'date-core'
initializeApp({ locale: 'en' })
const date = new Date()
document.getElementById('date').textContent = formatDateLocalized(date)
// Output: "15 January 2024"
- ✅ ES6 Modules - Works with Webpack, Vite, Rollup
- ✅ Tree Shaking - Only import what you need
- ✅ TypeScript Ready - Full type definitions
- ✅ Framework Agnostic - React, Vue, Angular, vanilla JS
- ✅ Performance Optimized - Minimal overhead
All functions now safely handle invalid dates with:
- Automatic validation - Every date input is validated
- Safe fallbacks - Invalid dates fallback to current date
- Detailed error messages - Helpful debugging information
- Configurable behavior - Customize error handling during app initialization
- Performance optimized - Minimal overhead for valid dates
import { formatDate, isValidDate, getDateValidationInfo } from 'date-core'
// Invalid dates are handled safely
formatDate('invalid-date') // Returns current date formatted
formatDate(null) // Returns current date formatted
formatDate('2024-13-45') // Returns current date formatted
// Check if date is valid
isValidDate('invalid-date') // false
isValidDate('2024-12-25') // true
// Get detailed validation info
const info = getDateValidationInfo('invalid-date')
console.log(info)
// Console Output:
// {
// isValid: false,
// error: 'Date results in NaN',
// fallback: Date object
// }
import { initializeApp } from 'date-core'
// Configure error handling during app initialization
initializeApp({
locale: 'en',
// Error handling configuration
logErrors: true, // Enable/disable console error logging
fallbackDate: new Date('2024-01-01'), // Custom fallback date
fallbackString: 'Date Error', // Custom fallback string
fallbackNumber: 0, // Custom fallback number
messages: {
invalidDate: 'Custom: Invalid date provided',
invalidDateNull: 'Custom: Date cannot be null',
invalidDateEmpty: 'Custom: Date cannot be empty',
invalidDateNaN: 'Custom: Date results in NaN',
// ... more custom messages
},
})
// Scenario 1: API returns null date
const apiResponse = { createdAt: null, updatedAt: undefined }
formatDateLocalized(apiResponse.createdAt) // Safe fallback
formatDateLocalized(apiResponse.updatedAt) // Safe fallback
// Scenario 2: User input validation
const userInputs = ['', 'invalid', '2024-13-01', '2024-02-30']
userInputs.forEach((input) => {
const isValid = isValidDate(input)
const formatted = isValid ? formatDate(input) : 'Invalid input'
console.log(`Input: "${input}" -> Valid: ${isValid}, Formatted: ${formatted}`)
})
// Console Output:
// Input: "" -> Valid: false, Formatted: Invalid input
// Input: "invalid" -> Valid: false, Formatted: Invalid input
// Input: "2024-13-01" -> Valid: false, Formatted: Invalid input
// Input: "2024-02-30" -> Valid: false, Formatted: Invalid input
The package includes intelligent logging that automatically adapts to your environment:
import { initializeApp } from 'date-core'
// Automatically detects environment
// Development: Helpful debugging information
// Production: Clean, no console spam
initializeApp({ locale: 'en' })
import { configureLogger, initializeApp } from 'date-core'
// Optional: Configure logging behavior
configureLogger({
enabled: process.env.NODE_ENV !== 'production',
level: 'warn',
})
initializeApp({ locale: 'en' })
// Scenario 3: Database date handling
const dbDates = [null, '2024-12-25', 'invalid-date', '2024-02-29']
dbDates.forEach((dbDate) => {
const validation = getDateValidationInfo(dbDate)
console.log(`DB Date: ${JSON.stringify(dbDate)}`)
console.log(` Valid: ${validation.isValid}`)
console.log(` Error: ${validation.error || 'None'}`)
console.log(` Safe Format: ${formatDate(dbDate)}`)
})
// Console Output:
// DB Date: null
// Valid: false
// Error: Date cannot be null
// Safe Format: 15 January 2024
// DB Date: "2024-12-25"
// Valid: true
// Error: None
// Safe Format: 25 December 2024
// DB Date: "invalid-date"
// Valid: false
// Error: Date results in NaN
// Safe Format: 15 January 2024
// DB Date: "2024-02-29"
// Valid: false
// Error: Invalid date (February 29, 2024 is not a leap year)
// Safe Format: 15 January 2024
The package comes with 5 built-in locales:
- English (en) - Default locale
- Arabic (ar) - Full RTL support with Arabic numerals
- French (fr) - French date and time formatting
- Spanish (es) - Spanish date and time formatting
- German (de) - German date and time formatting
import { registerLocale, setLocale } from 'date-core'
import { fr, es, de } from 'date-core'
// Register additional locales
registerLocale('fr', fr)
registerLocale('es', es)
registerLocale('de', de)
// Switch to any registered locale
setLocale('fr')
// Text view examples with different locales
const date = new Date()
// English
<p>Date: {formatDateLocalized(date, { locale: 'en' })}</p>
// Output: Date: 15 January 2024
// Arabic
<p>Date: {formatDateLocalized(date, { locale: 'ar' })}</p>
// Output: Date: ١٥ يناير ٢٠٢٤
// French
<p>Date: {formatDateLocalized(date, { locale: 'fr' })}</p>
// Output: Date: 15 janvier 2024
// Spanish
<Text>Date: {formatDateLocalized(date, { locale: 'es' })}</Text>
// Output: Date: 15 de enero de 2024
// German
<Text>Date: {formatDateLocalized(date, { locale: 'de' })}</Text>
// Output: Date: 15. Januar 2024
You can create and register your own locale files:
import {registerCustomLocale} from 'date-core';
// Your custom locale configuration
const myCustomLocale = {
months: ['January', 'February', 'March', ...],
monthsShort: ['Jan', 'Feb', 'Mar', ...],
weekdays: ['Sunday', 'Monday', 'Tuesday', ...],
weekdaysShort: ['Sun', 'Mon', 'Tue', ...],
weekdaysMin: ['Su', 'Mo', 'Tu', ...],
relativeTime: {
future: 'in %s',
past: '%s ago',
s: 'a few seconds',
// ... more translations
},
calendar: {
sameDay: 'today at LT',
nextDay: 'tomorrow at LT',
// ... more calendar formats
},
numberMap: {}, // For custom numeral systems
symbolMap: {}, // For custom numeral systems
};
// Register your custom locale
registerCustomLocale('my-locale', myCustomLocale);
// Use your custom locale
setLocale('my-locale');
import {
getAvailableLocales,
getCustomLocales,
getBuiltInLocales,
getLocaleInfo,
removeCustomLocale,
resetToDefaults,
} from 'date-core'
// Get all available locales
const allLocales = getAvailableLocales() // ['en', 'ar', 'fr', 'es', 'de', 'my-locale']
// Get custom locales only
const customLocales = getCustomLocales() // ['my-locale']
// Get built-in locales only
const builtInLocales = getBuiltInLocales() // ['en', 'ar', 'fr', 'es', 'de']
// Get locale information
const info = getLocaleInfo('ar')
// {
// code: 'ar',
// isCustom: false,
// isBuiltIn: true,
// hasArabicNumerals: true,
// sampleDate: 'يناير',
// sampleDay: 'الأحد'
// }
// Remove a custom locale
removeCustomLocale('my-locale')
// Reset to defaults
resetToDefaults()
- Basic Formatting: 5 functions
- Localized Formatting: 6 functions
- Relative Time: 3 functions
- Day/Month Names: 2 functions
- Date Checking: 6 functions
- Date Manipulation: 4 functions
- Date Ranges: 6 functions
- Date Differences: 3 functions
- Parsing/Validation: 4 functions
- Locale Management: 15+ functions
- Error Handling: 4 functions
- App Initialization: 3 functions
- Basic Usage: 8 functions
- Advanced Usage: 6 functions
- Multi-Locale: 8 functions
- Error Handling: 8 functions
- App Initialization: 13 functions
import {
formatDateLocalized,
getRelativeTimeLocalized,
getDayName,
} from 'date-core'
const date = formatDateLocalized(new Date()) // Uses app locale
const relative = getRelativeTimeLocalized(someDate) // Uses app locale
const dayName = getDayName(new Date(), { format: 'short' }) // Uses app locale
const arabicDate = formatDateLocalized(new Date(), { locale: 'ar' }) // Force Arabic
const englishDate = formatDateLocalized(new Date(), { locale: 'en' }) // Force English
const frenchDay = getDayName(new Date(), { locale: 'fr', format: 'short' }) // French short day
import React from 'react'
import { View, Text } from 'react-native'
import { formatDateSmart, formatTimeLocalized, getDayName } from 'date-core'
const DateDisplay = ({ date }) => (
<View>
<Text>Date: {formatDateSmart(date)}</Text>
<Text>Time: {formatTimeLocalized(date)}</Text>
<Text>Day: {getDayName(date, { format: 'short' })}</Text>
</View>
)
import React from 'react'
import { View, Text } from 'react-native'
import { formatDateLocalized, setLocale } from 'date-core'
const MultiLocaleDisplay = ({ date, locale }) => {
// Switch to specified locale
setLocale(locale)
return (
<View>
<Text>Date: {formatDateLocalized(date)}</Text>
<Text>Locale: {locale}</Text>
</View>
)
}
Function | Description | Parameters | Returns |
---|---|---|---|
formatDate(date) |
Format date as ISO string | date: Date|string |
string |
formatDateLocalized(date, options) |
Format date with locale support | date: Date|string, options: {locale?, format?} |
string |
formatLongDate(date, options) |
Format date in long format | date: Date|string, options: {locale?, format?} |
string |
getRelativeTimeLocalized(date) |
Get relative time (e.g., "2 hours ago") | date: Date|string |
string |
getDayName(date, options) |
Get day name | date: Date|string, options: {locale?, format?} |
string |
getMonthName(date, options) |
Get month name | date: Date|string, options: {locale?, format?} |
string |
isToday(date) |
Check if date is today | date: Date|string |
boolean |
isYesterday(date) |
Check if date is yesterday | date: Date|string |
boolean |
addDays(date, days) |
Add days to date | date: Date|string, days: number |
Date |
subtractDays(date, days) |
Subtract days from date | date: Date|string, days: number |
Date |
startOfDay(date) |
Get start of day | date: Date|string |
Date |
endOfDay(date) |
Get end of day | date: Date|string |
Date |
isValidDate(date) |
Validate date | date: any |
boolean |
Function | Description | Parameters | Returns |
---|---|---|---|
setLocale(locale) |
Set current locale | locale: string |
void |
getLocale() |
Get current locale | - | string |
registerLocale(code, config) |
Register new locale | code: string, config: object |
void |
getAvailableLocales() |
Get all available locales | - | string[] |
Function | Description | Parameters | Returns |
---|---|---|---|
initializeApp(config) |
Initialize app with configuration | config: object |
object |
configureErrorHandling(config) |
Configure error handling | config: object |
void |
Date-Core Function | Output Example | Description |
---|---|---|
formatDate(date) |
"2024-01-15" |
ISO date format |
formatDateDDMMYYYY(date) |
"15/01/2024" |
European format |
formatTime(date) |
"14:30" |
24-hour time |
formatLongDate(date, {format: 'LL'}) |
"15 January 2024" |
Long date |
formatLongDate(date, {format: 'LLLL'}) |
"Monday, 15 January 2024 14:30" |
Full long date |
getRelativeTimeLocalized(date) |
"2 hours ago" |
Relative time |
formatCalendar(date) |
"Today at 2:30 PM" |
Calendar context |
getDayName(date) |
"Monday" |
Day name |
getDayName(date, {format: 'short'}) |
"Mon" |
Short day name |
getMonthName(date) |
"January" |
Month name |
getMonthName(date, {format: 'short'}) |
"Jan" |
Short month name |
isToday(date) |
true |
Check if today |
isYesterday(date) |
true |
Check if yesterday |
addDays(date, 1) |
Date object |
Add days |
subtractDays(date, 1) |
Date object |
Subtract days |
startOfDay(date) |
Date object |
Start of day |
endOfDay(date) |
Date object |
End of day |
getDaysDifference(date1, date2) |
5 |
Days difference |
isValidDate(date) |
true |
Date validation |
// Automatic Arabic numeral conversion
formatDateLocalized(new Date(), { locale: 'ar' }) // "١٥ يناير ٢٠٢٤"
formatTimeLocalized(new Date(), { locale: 'ar' }) // "١٤:٣٠"
getDayName(new Date(), { locale: 'ar', format: 'short' }) // "إث"
formatDateSmart(date) // "اليوم" (if today)
formatDateSmart(yesterday) // "أمس" (if yesterday)
formatDateSmart(lastWeek) // "الإثنين" (if this week)
formatLongDate(date, { locale: 'ar', format: 'LL' }) // "١٥ يناير ٢٠٢٤"
formatLongDate(date, { locale: 'ar', format: 'LLLL' }) // "الإثنين ١٥ يناير ٢٠٢٤ ١٤:٣٠"
formatCalendar(date, { locale: 'ar' }) // "اليوم على الساعة ١٤:٣٠"
// Day name formats
getDayName(date, { format: 'long' }) // "الإثنين"
getDayName(date, { format: 'short' }) // "إث"
getDayName(date, { format: 'min' }) // "إ"
// Date formats
formatDateLocalized(date, { format: 'short' }) // "15 Jan 2024"
formatDateLocalized(date, { format: 'long' }) // "15 January 2024"
formatDateLocalized(date, { format: 'weekday' }) // "Monday, 15 January 2024"
- Bundle Size: Compact library with tree-shaking support
- Execution Speed: Optimized for React Native and web performance
- Memory Usage: Efficient memory footprint
- Tree Shaking: Only import what you need
- Error Handling: Minimal overhead for valid dates
import {
TestLocaleManager,
runMultiLocaleDemos,
runErrorHandlingDemos,
runAppInitializationDemos,
} from 'date-core/demos'
// Run basic tests
TestLocaleManager()
// Run comprehensive multi-locale tests
runMultiLocaleDemos()
// Run error handling tests
runErrorHandlingDemos()
// Run app initialization tests
runAppInitializationDemos()
import {
initializeApp,
setLocale,
testSpecificLocale,
testErrorScenario,
testAppInitialization,
} from 'date-core/demos'
// Test app initialization
const result = testAppInitialization({
locale: 'ar',
logErrors: true,
})
// Test specific locale
testSpecificLocale('fr')
// Test error scenarios
testErrorScenario('invalid-date', 'formatDate')
testErrorScenario(null, 'formatDateLocalized')
// Test locale switching
setLocale('en')
console.log('Switched to English')
- Demos: See
demos/
folder for comprehensive usage examples - Multi-Locale Demo: See
demos/multi-locale-demo.js
for dynamic locale registration - Error Handling Demo: See
demos/error-handling-demo.js
for invalid date handling - App Initialization Demo: See
demos/app-initialization-demo.js
for configuration examples - Locale Configs: See
lib/locales/
folder for locale configurations - Custom Locales: Create your own locale files following the same format
We welcome contributions! Please visit our GitHub repository for contribution guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with modern JavaScript (ES6+) best practices
- Inspired by the need for compact, performant date utilities
- Special thanks to the React Native community for feedback and testing