date-fns Complete Guide
이 글의 핵심
date-fns is a modern JavaScript date utility library with over 200 functions. It's modular, immutable, tree-shakeable, and provides excellent TypeScript support.
Introduction
date-fns provides comprehensive utilities for JavaScript dates. Unlike Moment.js, it’s modular and tree-shakeable, meaning you only import what you need.
Why date-fns?
// Moment.js (legacy, not recommended)
moment().add(7, 'days').format('YYYY-MM-DD');
// Bundle size: ~70KB
// date-fns (modern, recommended)
import { addDays, format } from 'date-fns';
format(addDays(new Date(), 7), 'yyyy-MM-dd');
// Bundle size: ~2-5KB (only what you import!)
Real-World Adoption
date-fns has replaced Moment.js as the go-to date library:
Market Position:
- 18+ million weekly npm downloads (April 2026)
- 34,000+ GitHub stars - community favorite
- Created by Sasha Koss (2014) - functional programming principles
- Used in 2+ million repositories - modern standard
Why date-fns Won:
- Modular & tree-shakeable: Import only what you need (2-5KB vs Moment’s 70KB)
- Immutable: Functions return new dates, no mutations
- Functional: Pure functions, no global state
- TypeScript: First-class TypeScript support
- 200+ functions: Comprehensive date manipulation
Enterprise Usage:
- Airbnb: Uses date-fns for all date handling on web
- Microsoft: Integrated into Microsoft Teams web app
- Shopify: Powers date formatting in Shopify Admin
- GitLab: All date utilities use date-fns
- GitHub: Used in GitHub Desktop and web interface
vs Alternatives:
| Library | Size | Mutable | Tree-shake | TypeScript | Status |
|---|---|---|---|---|---|
| Moment.js | 70KB | Yes ❌ | No ❌ | OK | Legacy (deprecated) |
| date-fns | 2-5KB | No ✅ | Yes ✅ | Excellent ✅ | Active |
| Day.js | 2KB | No ✅ | Partial | Good | Active |
| Luxon | 15-25KB | No ✅ | Partial | Good | Active |
Performance:
- 2-10x smaller than Moment.js in production builds
- Faster than Luxon for most operations
- Tree-shaking: Only pay for functions you use
Internationalization:
- 90+ locales supported
- date-fns/locale: Import only your locale (3-5KB)
- Format dates in any language without bloat
Time Zone Support:
- date-fns-tz: Companion package for time zones
- Parse and format across time zones
- Lighter than Moment Timezone
Framework Integration:
- React: Most popular date library in React ecosystem
- Angular: Used in Angular Material date pickers
- Vue: Recommended by Vue.js core team
- Next.js, Remix: Standard choice for date handling
Migration from Moment:
- Drop-in replacement for most operations
- Codemod tools available for automatic migration
- 80% smaller bundles after migration
Use Cases:
- Date formatting: Most common use (format, parse)
- Relative time: “2 days ago”, “in 5 hours”
- Date arithmetic: Add/subtract days, months, years
- Comparison: isBefore, isAfter, isEqual
- Internationalization: Multi-language date display
Adoption Statistics:
- 2019-2026: Downloads grew 400%
- Moment.js → date-fns: 1,000+ migration blog posts
- Bundle size savings: Teams report 60-90KB reduction
Community Endorsements:
- Moment.js team: Official recommendation to use date-fns
- Create React App: Switched default recommendation
- Next.js docs: Use date-fns in examples
date-fns is now what you reach for when “modern JavaScript date library” - no question.
1. Installation
npm install date-fns
2. Basic Usage
Formatting Dates
import { format } from 'date-fns';
const date = new Date(2024, 0, 15); // January 15, 2024
format(date, 'yyyy-MM-dd'); // "2024-01-15"
format(date, 'MMMM do, yyyy'); // "January 15th, 2024"
format(date, 'h:mm a'); // "12:00 AM"
format(date, "EEEE 'at' h:mm a"); // "Monday at 12:00 AM"
Parsing Dates
import { parse, parseISO } from 'date-fns';
// Parse ISO string
parseISO('2024-01-15'); // Date object
// Parse custom format
parse('15/01/2024', 'dd/MM/yyyy', new Date());
parse('Jan 15, 2024', 'MMM dd, yyyy', new Date());
3. Date Arithmetic
import { addDays, addMonths, addYears, subDays, subMonths } from 'date-fns';
const date = new Date(2024, 0, 15);
// Addition
addDays(date, 7); // January 22, 2024
addMonths(date, 3); // April 15, 2024
addYears(date, 1); // January 15, 2025
// Subtraction
subDays(date, 7); // January 8, 2024
subMonths(date, 1); // December 15, 2023
// All functions return NEW date (immutable)
const original = new Date(2024, 0, 15);
const modified = addDays(original, 7);
console.log(original); // Still January 15, 2024
console.log(modified); // January 22, 2024
4. Comparison
import {
isAfter,
isBefore,
isEqual,
isFuture,
isPast,
isToday,
isYesterday,
isTomorrow,
isWeekend,
} from 'date-fns';
const date1 = new Date(2024, 0, 15);
const date2 = new Date(2024, 0, 20);
isAfter(date2, date1); // true
isBefore(date1, date2); // true
isEqual(date1, date1); // true
isFuture(new Date(2025, 0, 1)); // true
isPast(new Date(2020, 0, 1)); // true
isToday(new Date()); // true
isWeekend(new Date(2024, 0, 13)); // true (Saturday)
5. Difference Calculations
import {
differenceInDays,
differenceInMonths,
differenceInYears,
differenceInHours,
differenceInMinutes,
} from 'date-fns';
const start = new Date(2024, 0, 1);
const end = new Date(2024, 0, 15);
differenceInDays(end, start); // 14
differenceInHours(end, start); // 336
differenceInMinutes(end, start); // 20160
const birthDate = new Date(1990, 0, 1);
differenceInYears(new Date(), birthDate); // 34
6. Start/End of Period
import {
startOfDay,
endOfDay,
startOfWeek,
endOfWeek,
startOfMonth,
endOfMonth,
startOfYear,
endOfYear,
} from 'date-fns';
const date = new Date(2024, 0, 15, 14, 30); // Jan 15, 2:30 PM
startOfDay(date); // Jan 15, 12:00:00 AM
endOfDay(date); // Jan 15, 11:59:59 PM
startOfWeek(date); // Jan 14 (Sunday)
endOfWeek(date); // Jan 20 (Saturday)
startOfMonth(date); // Jan 1
endOfMonth(date); // Jan 31
startOfYear(date); // Jan 1
endOfYear(date); // Dec 31
7. Internationalization
npm install date-fns
import { format } from 'date-fns';
import { ko, ja, es, fr } from 'date-fns/locale';
const date = new Date(2024, 0, 15);
// English (default)
format(date, 'PPPP');
// "Monday, January 15th, 2024"
// Korean
format(date, 'PPPP', { locale: ko });
// "2024년 1월 15일 월요일"
// Japanese
format(date, 'PPPP', { locale: ja });
// "2024年1月15日月曜日"
// Spanish
format(date, 'PPPP', { locale: es });
// "lunes, 15 de enero de 2024"
8. Time Zones
npm install date-fns date-fns-tz
import { format } from 'date-fns';
import { formatInTimeZone, utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';
const date = new Date('2024-01-15T12:00:00Z');
// Format in specific timezone
formatInTimeZone(date, 'America/New_York', 'yyyy-MM-dd HH:mm:ss zzz');
// "2024-01-15 07:00:00 EST"
formatInTimeZone(date, 'Asia/Seoul', 'yyyy-MM-dd HH:mm:ss zzz');
// "2024-01-15 21:00:00 KST"
// Convert UTC to timezone
const newYorkDate = utcToZonedTime(date, 'America/New_York');
// Convert timezone to UTC
const utcDate = zonedTimeToUtc('2024-01-15 12:00:00', 'America/New_York');
9. Validation
import { isValid, isDate, isMatch } from 'date-fns';
isValid(new Date()); // true
isValid(new Date('invalid')); // false
isDate(new Date()); // true
isDate('2024-01-15'); // false
isMatch('2024-01-15', 'yyyy-MM-dd'); // true
isMatch('15/01/2024', 'yyyy-MM-dd'); // false
10. Real-World Examples
Relative Time Display
import { formatDistanceToNow } from 'date-fns';
const postDate = new Date(2024, 0, 14);
formatDistanceToNow(postDate, { addSuffix: true });
// "1 day ago"
const futureDate = new Date(2024, 0, 20);
formatDistanceToNow(futureDate, { addSuffix: true });
// "in 5 days"
Date Range Filtering
import { isWithinInterval } from 'date-fns';
const rangeStart = new Date(2024, 0, 1);
const rangeEnd = new Date(2024, 0, 31);
const testDate = new Date(2024, 0, 15);
isWithinInterval(testDate, { start: rangeStart, end: rangeEnd });
// true
Business Days
import { addBusinessDays, isWeekend, differenceInBusinessDays } from 'date-fns';
const date = new Date(2024, 0, 15); // Monday
addBusinessDays(date, 5); // Next Monday (skips weekend)
differenceInBusinessDays(
new Date(2024, 0, 22),
new Date(2024, 0, 15)
); // 5 business days
Age Calculator
import { differenceInYears, differenceInMonths, differenceInDays } from 'date-fns';
function calculateAge(birthDate) {
const now = new Date();
const years = differenceInYears(now, birthDate);
const months = differenceInMonths(now, birthDate) % 12;
return { years, months };
}
calculateAge(new Date(1990, 0, 15));
// { years: 34, months: 0 }
Event Countdown
import { intervalToDuration, formatDuration } from 'date-fns';
function countdown(eventDate) {
const duration = intervalToDuration({
start: new Date(),
end: eventDate,
});
return formatDuration(duration);
}
countdown(new Date(2024, 11, 25));
// "11 months 10 days 3 hours 25 minutes"
11. Best Practices
1. Always Import Specific Functions
// Good: tree-shakeable
import { format, addDays } from 'date-fns';
// Bad: imports everything
import * as dateFns from 'date-fns';
2. Use ISO Format for Storage
import { formatISO, parseISO } from 'date-fns';
// Store dates as ISO strings
const dateString = formatISO(new Date());
// "2024-01-15T12:00:00.000Z"
// Parse back to Date
const date = parseISO(dateString);
3. Handle Invalid Dates
import { isValid, parse } from 'date-fns';
function parseDate(dateString, formatString) {
const parsed = parse(dateString, formatString, new Date());
if (!isValid(parsed)) {
throw new Error('Invalid date');
}
return parsed;
}
12. Performance Tips
// Create reusable formatter
import { format } from 'date-fns';
const formatDate = (date) => format(date, 'yyyy-MM-dd');
// Use once, reuse many times
dates.map(formatDate);
Summary
date-fns is the modern choice for date manipulation:
- Modular - tree-shakeable, small bundle
- Immutable - pure functions
- TypeScript - full type support
- i18n - 100+ locales
- Time zones with date-fns-tz
Key Takeaways:
- Import only what you need
- All functions are immutable
- Use formatISO for storage
- date-fns-tz for time zones
- 200+ utility functions
Next Steps:
- Try Day.js
- Learn Lodash
- Build with TypeScript
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete date-fns guide for date manipulation in JavaScript.
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- Immer Complete Guide | Immutable State Made Easy
- Mongoose Complete Guide | MongoDB ODM for Node.js
- Yup Complete Guide | Schema Validation for JavaScript
Keywords Covered in This Article (Related Search Terms)
This article covers date-fns, JavaScript, Date, Utilities, i18n.