본문으로 건너뛰기 date-fns Complete Guide

date-fns Complete Guide

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:

LibrarySizeMutableTree-shakeTypeScriptStatus
Moment.js70KBYes ❌No ❌OKLegacy (deprecated)
date-fns2-5KBNo ✅Yes ✅Excellent ✅Active
Day.js2KBNo ✅PartialGoodActive
Luxon15-25KBNo ✅PartialGoodActive

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:

  1. Import only what you need
  2. All functions are immutable
  3. Use formatISO for storage
  4. date-fns-tz for time zones
  5. 200+ utility functions

Next Steps:

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.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers date-fns, JavaScript, Date, Utilities, i18n.