Overview
React Native Calendars uses XDate internally for date manipulation and provides utilities for common date operations. Understanding how to work with dates is essential for effective calendar integration.
The library uses the YYYY-MM-DD string format for all date operations:
import {Calendar} from 'react-native-calendars';
<Calendar
current={'2024-11-06'}
minDate={'2024-01-01'}
maxDate={'2024-12-31'}
/>
All dates must be in the format ‘YYYY-MM-DD’. Other formats will not work correctly.
DateData object
When handling calendar events, you’ll receive a DateData object:
interface DateData {
year: number; // e.g., 2024
month: number; // 1-12
day: number; // 1-31
timestamp: number; // Unix timestamp
dateString: string; // 'YYYY-MM-DD'
}
Using DateData
const onDayPress = (day) => {
console.log('Selected date:', day.dateString);
console.log('Year:', day.year);
console.log('Month:', day.month);
console.log('Day:', day.day);
console.log('Timestamp:', day.timestamp);
};
<Calendar onDayPress={onDayPress} />
Setting the initial date
There are two ways to set the initially visible month:
Using current
<Calendar
current={'2024-11-06'}
onDayPress={day => console.log('selected day', day)}
/>
Using initialDate
Use initialDate if you want to update it dynamically:
const [initialDate, setInitialDate] = useState('2024-11-06');
<Calendar
initialDate={initialDate}
onDayPress={day => console.log('selected day', day)}
/>
initialDate will re-initialize the calendar when changed, while current only sets the initial state.
Restricting date selection
Control which dates users can select:
Min and max dates
<Calendar
minDate={'2024-01-01'}
maxDate={'2024-12-31'}
disableAllTouchEventsForDisabledDays={true}
/>
Allow selection outside range
<Calendar
minDate={'2024-01-01'}
maxDate={'2024-12-31'}
allowSelectionOutOfRange={true}
/>
Dates before minDate or after maxDate will be grayed out unless allowSelectionOutOfRange is enabled.
Disabling specific days
Disable by day of week
Disable specific days of the week (0 = Sunday, 6 = Saturday):
<Calendar
disabledByWeekDays={[0, 6]} // Disable weekends
disableAllTouchEventsForDisabledDays={true}
/>
Disable all days by default
<Calendar
disabledByDefault={true}
markedDates={{
'2024-11-06': {disabled: false, selected: true}
}}
/>
CalendarUtils
The library exports CalendarUtils for common date operations:
import {CalendarUtils} from 'react-native-calendars';
const today = CalendarUtils.getCalendarDateString(new Date());
console.log(today); // '2024-11-06'
Getting dates relative to a reference
const INITIAL_DATE = '2024-11-06';
const getDate = (count) => {
const date = new Date(INITIAL_DATE);
const newDate = date.setDate(date.getDate() + count);
return CalendarUtils.getCalendarDateString(newDate);
};
const yesterday = getDate(-1);
const tomorrow = getDate(1);
const nextWeek = getDate(7);
Date manipulation with XDate
While not directly exposed, you can use XDate for advanced date operations:
import XDate from 'xdate';
const date = new XDate('2024-11-06');
// Add/subtract time
const tomorrow = date.clone().addDays(1);
const nextMonth = date.clone().addMonths(1);
const nextYear = date.clone().addYears(1);
// Format dates
const formatted = date.toString('MMMM dd, yyyy');
// 'November 06, 2024'
Date parsing utilities
The library provides internal utilities that you can replicate:
const toMarkingFormat = (date) => {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};
const today = toMarkingFormat(new Date());
const parseDate = (input) => {
if (input instanceof Date) {
return toMarkingFormat(input);
}
if (typeof input === 'number') {
// Timestamp
return toMarkingFormat(new Date(input));
}
if (typeof input === 'string') {
// ISO string or YYYY-MM-DD
return toMarkingFormat(new Date(input));
}
return input;
};
Working with month changes
Handle month changes to load new data:
const [currentMonth, setCurrentMonth] = useState('2024-11-06');
const onMonthChange = (month) => {
console.log('Month changed to:', month.dateString);
setCurrentMonth(month.dateString);
// Load data for the new month
};
<Calendar
current={currentMonth}
onMonthChange={onMonthChange}
/>
First day of week
Control which day starts the week:
<Calendar
firstDay={0} // Sunday (default)
/>
<Calendar
firstDay={1} // Monday
/>
<Calendar
firstDay={6} // Saturday
/>
The firstDay prop accepts a number from 0 (Sunday) to 6 (Saturday).
Getting week dates
Calculate all dates in a week:
const getWeekDates = (dateString, firstDayOfWeek = 0) => {
const date = new Date(dateString);
const day = date.getDay();
const diff = (day - firstDayOfWeek + 7) % 7;
const weekStart = new Date(date);
weekStart.setDate(date.getDate() - diff);
const weekDates = [];
for (let i = 0; i < 7; i++) {
const current = new Date(weekStart);
current.setDate(weekStart.getDate() + i);
weekDates.push(toMarkingFormat(current));
}
return weekDates;
};
const week = getWeekDates('2024-11-06', 1); // Start on Monday
Checking if date is today
const isToday = (dateString) => {
const today = new Date();
const date = new Date(dateString);
return (
date.getFullYear() === today.getFullYear() &&
date.getMonth() === today.getMonth() &&
date.getDate() === today.getDate()
);
};
Date comparison
const isSameDate = (date1String, date2String) => {
return date1String === date2String;
};
const isSameMonth = (date1String, date2String) => {
const date1 = new Date(date1String);
const date2 = new Date(date2String);
return (
date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth()
);
};
const isPast = (dateString) => {
const date = new Date(dateString);
const today = new Date();
today.setHours(0, 0, 0, 0);
return date < today;
};
Date ranges
Generate a range of dates:
const getDateRange = (startDate, endDate) => {
const dates = [];
const current = new Date(startDate);
const end = new Date(endDate);
while (current <= end) {
dates.push(toMarkingFormat(current));
current.setDate(current.getDate() + 1);
}
return dates;
};
const range = getDateRange('2024-11-01', '2024-11-07');
// ['2024-11-01', '2024-11-02', ..., '2024-11-07']
Managing selected dates
Track and update selected dates:
const [selectedDates, setSelectedDates] = useState({});
const onDayPress = (day) => {
const dateString = day.dateString;
// Single selection
setSelectedDates({
[dateString]: {
selected: true,
selectedColor: 'blue'
}
});
// Multiple selection
setSelectedDates(prev => ({
...prev,
[dateString]: {
selected: !prev[dateString]?.selected,
selectedColor: 'blue'
}
}));
};
<Calendar
markedDates={selectedDates}
onDayPress={onDayPress}
/>
Timezone considerations
XDate creates dates in the local timezone by default. Be careful when working with timestamps from different timezones.
// Create date in UTC
const utcDate = new XDate('2024-11-06', true);
// Get UTC timestamp
const timestamp = utcDate.getTime();
Best practices
Always use YYYY-MM-DD format
Stick to the ‘YYYY-MM-DD’ format for all date strings to ensure consistency.
Handle timezones carefully
Be aware of timezone differences when working with timestamps and date strings.
Validate date inputs
Always validate dates from user input or external sources before passing to the calendar.
Use memoization
Memoize date calculations and marked dates objects to optimize performance.