web-utilities-date-fns
TypeScriptで日付のフォーマット、解析、操作、比較、タイムゾーン処理、国際化など、日付に関する様々な処理をdate-fnsのパターンを使って効率的に行い、より柔軟で正確な日付操作を可能にするSkill。
📜 元の英語説明(参考)
date-fns patterns for TypeScript - formatting, parsing, manipulation, comparison, timezone handling, and internationalization
🇯🇵 日本人クリエイター向け解説
TypeScriptで日付のフォーマット、解析、操作、比較、タイムゾーン処理、国際化など、日付に関する様々な処理をdate-fnsのパターンを使って効率的に行い、より柔軟で正確な日付操作を可能にするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o web-utilities-date-fns.zip https://jpskill.com/download/10324.zip && unzip -o web-utilities-date-fns.zip && rm web-utilities-date-fns.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10324.zip -OutFile "$d\web-utilities-date-fns.zip"; Expand-Archive "$d\web-utilities-date-fns.zip" -DestinationPath $d -Force; ri "$d\web-utilities-date-fns.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
web-utilities-date-fns.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
web-utilities-date-fnsフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
date-fns Date Utility Patterns
クイックガイド: モジュール式でツリーシェイキング可能な日付操作には date-fns を使用します。必要なものだけをインポートしてください。ISO 文字列には
parseISOを、表示には Unicode トークン付きのformatを、そして新しい Date オブジェクトを返す純粋関数を使用します。タイムゾーンには、@date-fns/tzとTZDate(v4+)、またはdate-fns-tzとformatInTimeZone(v3.x) を使用します。日付を直接変更しないでください。
<critical_requirements>
重要: この Skill を使用する前に
すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case, 名前付きエクスポート, インポート順,
import type, 名前付き定数)
(ISO 8601 文字列には必ず parseISO() を使用してください - ブラウザによって挙動が異なる new Date(string) は絶対に使用しないでください)
*(必要な関数のみをインポートしてください - ツリーシェイキングを妨げる `import as dateFns` は絶対に使用しないでください)**
(新しい日付を返す純粋関数を使用してください - setDate() などで日付を直接変更しないでください)
(フォーマット文字列と期間には名前付き定数を使用してください - コード内に 'yyyy-MM-dd' のようなマジック文字列を散在させないでください)
</critical_requirements>
自動検出: date-fns, format, parseISO, addDays, subMonths, differenceInDays, formatDistance, isAfter, isBefore, eachDayOfInterval, date-fns-tz, @date-fns/tz, @date-fns/utc, TZDate, TZDateMini, UTCDate, UTCDateMini, tz(), transpose, tzName, tzScan, withTimeZone, locale
使用すべき場合:
- ロケール対応で日付を表示するためにフォーマットする場合
- 日付文字列を Date オブジェクトにパースする場合
- 日付の演算 (日、月、年を加算/減算)
- 日付の比較と期間の確認
- 日付間の差の計算
- カレンダー用の日付範囲の生成
- 相対的な時間フォーマット ("2時間前")
使用すべきでない場合:
- 単純な日付表示 -
Intl.DateTimeFormatを使用 (バンドルコストゼロ) - 非常に単純な操作 - ネイティブの
Dateで十分な場合 - 複雑な繰り返し日付 -
rrule.jsを併用 - 将来の Temporal API ブラウザサポートがあるプロジェクト
詳細なリソース:
- examples/core.md - フォーマット、パース、演算、境界、プリセット範囲
- examples/timezone.md - v4 TZDate, v3 date-fns-tz, DST 処理, UTC 操作
- examples/i18n.md - ロケール設定、ロケール対応フォーマット、週の開始日
- examples/relative.md - 相対時間、期間フォーマット、スマートな日付表示
- examples/comparison.md - 比較、期間、重複検出、バリデーション
- reference.md - 意思決定フレームワーク、移行ガイド、アンチパターン、クイックリファレンス
<philosophy>
Philosophy
date-fns は モジュール式で関数型 の日付ユーティリティライブラリです。各関数は独立しており、ツリーシェイキングによって使用するものだけを含めることができます。すべての関数は 純粋 であり、入力を変更するのではなく、新しい Date オブジェクトを返します。これにより、日付操作が予測可能でテスト可能になります。
重要な原則: 必要なものをインポートし、残りはバンドラーに削除させます。単純な format インポートは、ライブラリ全体 80KB ではなく、約 2KB を追加します。
// ツリーシェイキング可能 - format と parseISO のみを含む
import { format, parseISO } from "date-fns";
// モジュールレベルでのフォーマット定数
const DATE_DISPLAY_FORMAT = "MMMM d, yyyy";
const date = parseISO("2026-01-15");
const display = format(date, DATE_DISPLAY_FORMAT); // "January 15, 2026"
v3+ は 100% TypeScript であり、型定義が組み込まれています。@types/date-fns は不要です。
</philosophy>
<patterns>
Core Patterns
Pattern 1: Format Tokens (Unicode TR35)
date-fns は Unicode Technical Standard #35 のフォーマットトークンを使用します。これらは Moment.js とは異なります (yyyy は YYYY ではなく、dd は DD ではなく、EEEE は dddd ではありません)。
import { format } from "date-fns";
// モジュールレベルでフォーマット定数を定義
const ISO_DATE_FORMAT = "yyyy-MM-dd";
const DISPLAY_DATE_FORMAT = "MMMM d, yyyy";
const DISPLAY_DATETIME_FORMAT = "MMMM d, yyyy 'at' h:mm a";
const date = new Date(2026, 0, 15, 14, 30, 0);
format(date, ISO_DATE_FORMAT); // "2026-01-15"
format(date, DISPLAY_DATE_FORMAT); // "January 15, 2026"
format(date, DISPLAY_DATETIME_FORMAT); // "January 15, 2026 at 2:30 PM"
format(date, "EEEE"); // "Thursday"
format(date, "h:mm a"); // "2:30 PM"
完全なフォーマットトークンテーブルについては、reference.md を参照してください。
良い理由: 名前付き定数により、フォーマット文字列が再利用可能で発見しやすくなり、Unicode トークンは日付ライブラリ全体で標準になります。
Pattern 2: Locale-Aware Format Shortcuts
正確なフォーマットを指定せずにロケール対応の日付フォーマットを行うには、P、PP、PPP、PPPP を使用します。
import { format } from "date-fns";
import { enUS, de, ja, fr } from "date-fns/locale";
const date = new Date(2026, 0, 15);
// ✅ 良い例 - ロケール対応のフォーマット
// 短い日付
format(date, "P", { locale: enUS }); // "01/15/2026"
format(date, "P", { locale: de }); // "15.01.2026"
format(date, "P", { locale: ja }); // "2026/01/15"
// 中間の日付
format(date, "PP", { locale: enUS }); // "Jan 15, 2026"
format(date, "PP", { locale: de }); // "15. Jan. 2026"
// 長い日付
format(date, "PPP", { locale: enUS }); // "January 15th, 2026"
format(date, "PPP", { locale: fr }); // "15 janvier 2026"
// 完全な日付
format(date, "PPPP", { locale: enUS }); // "Thursday, January 15th, 2026"
format(date, "PPPP", { locale: ja }); // "2026年1月15日木曜日"
// 時間のショートカット
format(date, "p", { locale: enUS }); // "12:00 AM"
format(date, "pp", { locale: enUS }); // "12:00:00 AM"
// 日付と時間の組み合わせ
format(date, "PPpp", { locale: enUS }); // "Jan 15, 2026, 12:00:00 AM"
良い理由: P / PP / PPP はロケールの慣習に自動的に適応し、ユーザーは自分の地域に見慣れた形式で日付を表示できます。
// ❌ 悪い例 - ハードコードされたフォーマットはロケールを無視する
format(date, "MM/dd/yyyy"); // "01/15/2026" - 世界のほとんどの地域で間違っている!
悪い理由: ハードコードされた MM/dd/yyyy フォーマットは米国固有であり、異なる順序を期待するヨーロッパやアジアのユーザーにとっては紛らわしいです。
Pattern 3: Safe Parsing with parseISO
ISO 860 で parseISO を使用します
(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
date-fns Date Utility Patterns
Quick Guide: Use date-fns for modular, tree-shakeable date operations. Import only what you need. Use
parseISOfor ISO strings,formatwith Unicode tokens for display, and pure functions that return new Date objects. For timezones, use@date-fns/tzwithTZDate(v4+) ordate-fns-tzwithformatInTimeZone(v3.x). Never mutate dates.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use parseISO() for ISO 8601 strings - NEVER use new Date(string) which has browser inconsistencies)
*(You MUST import only needed functions - NEVER use `import as dateFns` which defeats tree-shaking)**
(You MUST use pure functions that return new dates - NEVER mutate dates with setDate() or similar)
(You MUST use named constants for format strings and durations - NO magic strings like 'yyyy-MM-dd' scattered in code)
</critical_requirements>
Auto-detection: date-fns, format, parseISO, addDays, subMonths, differenceInDays, formatDistance, isAfter, isBefore, eachDayOfInterval, date-fns-tz, @date-fns/tz, @date-fns/utc, TZDate, TZDateMini, UTCDate, UTCDateMini, tz(), transpose, tzName, tzScan, withTimeZone, locale
When to use:
- Formatting dates for display with locale support
- Parsing date strings into Date objects
- Date arithmetic (add/subtract days, months, years)
- Comparing dates and checking intervals
- Calculating differences between dates
- Generating date ranges for calendars
- Relative time formatting ("2 hours ago")
When NOT to use:
- Simple date display - use
Intl.DateTimeFormat(zero bundle cost) - Very simple operations - native
Datemay suffice - Complex recurring dates - use
rrule.jsalongside - Future projects with Temporal API browser support
Detailed Resources:
- examples/core.md - Formatting, parsing, arithmetic, boundaries, preset ranges
- examples/timezone.md - v4 TZDate, v3 date-fns-tz, DST handling, UTC operations
- examples/i18n.md - Locale setup, locale-aware formatting, week start days
- examples/relative.md - Relative time, duration formatting, smart date display
- examples/comparison.md - Comparisons, intervals, overlap detection, validation
- reference.md - Decision frameworks, migration guides, anti-patterns, quick reference
<philosophy>
Philosophy
date-fns is a modular, functional date utility library. Each function is independent, enabling tree-shaking to include only what you use. All functions are pure - they return new Date objects rather than mutating inputs. This makes date operations predictable and testable.
Key principle: Import what you need, let bundlers remove the rest. A simple format import adds ~2KB, not the entire 80KB library.
// Tree-shakeable - only includes format and parseISO
import { format, parseISO } from "date-fns";
// Format constant at module level
const DATE_DISPLAY_FORMAT = "MMMM d, yyyy";
const date = parseISO("2026-01-15");
const display = format(date, DATE_DISPLAY_FORMAT); // "January 15, 2026"
v3+ is 100% TypeScript with built-in type definitions. No @types/date-fns needed.
</philosophy>
<patterns>
Core Patterns
Pattern 1: Format Tokens (Unicode TR35)
date-fns uses Unicode Technical Standard #35 format tokens. These differ from Moment.js (yyyy not YYYY, dd not DD, EEEE not dddd).
import { format } from "date-fns";
// Define format constants at module level
const ISO_DATE_FORMAT = "yyyy-MM-dd";
const DISPLAY_DATE_FORMAT = "MMMM d, yyyy";
const DISPLAY_DATETIME_FORMAT = "MMMM d, yyyy 'at' h:mm a";
const date = new Date(2026, 0, 15, 14, 30, 0);
format(date, ISO_DATE_FORMAT); // "2026-01-15"
format(date, DISPLAY_DATE_FORMAT); // "January 15, 2026"
format(date, DISPLAY_DATETIME_FORMAT); // "January 15, 2026 at 2:30 PM"
format(date, "EEEE"); // "Thursday"
format(date, "h:mm a"); // "2:30 PM"
See reference.md for the full format token table.
Why good: named constants make format strings reusable and discoverable, Unicode tokens are standard across date libraries
Pattern 2: Locale-Aware Format Shortcuts
Use P, PP, PPP, PPPP for locale-aware date formatting without specifying exact format.
import { format } from "date-fns";
import { enUS, de, ja, fr } from "date-fns/locale";
const date = new Date(2026, 0, 15);
// ✅ Good Example - Locale-aware formatting
// Short date
format(date, "P", { locale: enUS }); // "01/15/2026"
format(date, "P", { locale: de }); // "15.01.2026"
format(date, "P", { locale: ja }); // "2026/01/15"
// Medium date
format(date, "PP", { locale: enUS }); // "Jan 15, 2026"
format(date, "PP", { locale: de }); // "15. Jan. 2026"
// Long date
format(date, "PPP", { locale: enUS }); // "January 15th, 2026"
format(date, "PPP", { locale: fr }); // "15 janvier 2026"
// Full date
format(date, "PPPP", { locale: enUS }); // "Thursday, January 15th, 2026"
format(date, "PPPP", { locale: ja }); // "2026年1月15日木曜日"
// Time shortcuts
format(date, "p", { locale: enUS }); // "12:00 AM"
format(date, "pp", { locale: enUS }); // "12:00:00 AM"
// Combined date and time
format(date, "PPpp", { locale: enUS }); // "Jan 15, 2026, 12:00:00 AM"
Why good: P/PP/PPP adapt to locale conventions automatically, users see dates in familiar format for their region
// ❌ Bad Example - Hardcoded format ignores locale
format(date, "MM/dd/yyyy"); // "01/15/2026" - wrong for most of world!
Why bad: hardcoded MM/dd/yyyy format is US-specific, confusing for European and Asian users who expect different order
Pattern 3: Safe Parsing with parseISO
Use parseISO for ISO 8601 strings. Use parse for custom formats.
import { parseISO, parse, isValid } from "date-fns";
// ✅ Good - parseISO for ISO strings
const date = parseISO("2026-01-15T14:30:00Z");
// ✅ Good - parse for custom formats (3rd arg is reference date)
const CUSTOM_DATE_FORMAT = "dd/MM/yyyy";
const customDate = parse("15/01/2026", CUSTOM_DATE_FORMAT, new Date());
// Always validate parsed dates
if (!isValid(date)) {
/* handle invalid */
}
Why good: parseISO handles all ISO 8601 variants, isValid catches invalid dates
// ❌ Bad - Using Date constructor
const date1 = new Date("2026-01-15"); // Browser-inconsistent!
const date2 = new Date("01/15/2026"); // May fail in non-US browsers
Why bad: new Date(string) parsing varies by browser and locale
See examples/core.md for strict round-trip parsing that catches invalid dates like Feb 30.
Pattern 4: Date Arithmetic
Use pure functions for date manipulation. All return new Date objects.
import {
addDays,
addMonths,
addYears,
subDays,
subMonths,
subYears,
addHours,
addMinutes,
} from "date-fns";
// Duration constants
const WEEK_IN_DAYS = 7;
const BILLING_CYCLE_MONTHS = 1;
const TRIAL_PERIOD_DAYS = 14;
const date = new Date(2026, 0, 15);
// ✅ Good Example - Pure functions return new dates
const nextWeek = addDays(date, WEEK_IN_DAYS); // Jan 22, 2026
const nextMonth = addMonths(date, BILLING_CYCLE_MONTHS); // Feb 15, 2026
const nextYear = addYears(date, 1); // Jan 15, 2027
const lastWeek = subDays(date, WEEK_IN_DAYS); // Jan 8, 2026
const trialEnd = addDays(date, TRIAL_PERIOD_DAYS); // Jan 29, 2026
// Chain operations
const twoWeeksFromNextMonth = addDays(addMonths(date, 1), WEEK_IN_DAYS * 2);
// Original date is unchanged
console.log(date); // Still Jan 15, 2026
Why good: pure functions are predictable and testable, original date unchanged, constants document business logic
// ❌ Bad Example - Mutating dates
const date = new Date(2026, 0, 15);
date.setDate(date.getDate() + 7); // Mutates original!
// Original date is now changed - causes bugs in shared references
Why bad: mutation creates side effects, especially problematic when date is passed as prop or stored in state
Pattern 5: Date Boundaries
Use boundary functions for consistent start/end of periods.
import {
startOfDay,
endOfDay,
startOfWeek,
endOfWeek,
startOfMonth,
endOfMonth,
startOfQuarter,
endOfQuarter,
startOfYear,
endOfYear,
} from "date-fns";
const date = new Date(2026, 0, 15, 14, 30, 0);
// ✅ Good Example - Boundary functions for consistent ranges
const dayStart = startOfDay(date); // Jan 15, 2026 00:00:00
const dayEnd = endOfDay(date); // Jan 15, 2026 23:59:59.999
// Week boundaries (weekStartsOn: 1 = Monday)
const weekStart = startOfWeek(date, { weekStartsOn: 1 }); // Jan 13, 2026
const weekEnd = endOfWeek(date, { weekStartsOn: 1 }); // Jan 19, 2026
const monthStart = startOfMonth(date); // Jan 1, 2026
const monthEnd = endOfMonth(date); // Jan 31, 2026 23:59:59.999
Why good: boundary functions handle edge cases (month lengths, leap years), consistent for database queries and filtering
See examples/core.md for range generation utilities (getMonthRange, preset ranges).
Pattern 6: Date Comparisons
Use comparison functions instead of manual timestamp comparisons.
import {
isAfter,
isBefore,
isEqual,
isSameDay,
isSameMonth,
isSameYear,
isWithinInterval,
isToday,
isPast,
isFuture,
isWeekend,
} from "date-fns";
const date1 = new Date(2026, 0, 15);
const date2 = new Date(2026, 0, 20);
// ✅ Good Example - Semantic comparison functions
const isLater = isAfter(date2, date1); // true
const isEarlier = isBefore(date1, date2); // true
const areSame = isEqual(date1, date1); // true
// Same period checks (ignore time)
const sameDay = isSameDay(date1, date1); // true
const sameMonth = isSameMonth(date1, date2); // true (both January)
const sameYear = isSameYear(date1, date2); // true (both 2026)
// Range check
const isInRange = isWithinInterval(new Date(2026, 0, 17), {
start: date1,
end: date2,
}); // true
// Convenience checks
const todayCheck = isToday(new Date()); // true
const pastCheck = isPast(date1); // depends on current date
const futureCheck = isFuture(date2); // depends on current date
const weekendCheck = isWeekend(date1); // false (Thursday)
Why good: semantic function names make code readable, handles edge cases like time zone differences
// ❌ Bad Example - Manual timestamp comparison
const isLater = date2.getTime() > date1.getTime();
const sameDay =
date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate();
Why bad: verbose, error-prone, doesn't handle edge cases, hard to read intent
</patterns>
<integration>
Version Notes
- v4+ (current, 4.1.0): Uses
@date-fns/tzfor timezone handling withTZDateclass andtz()helper - v3.x: Uses
date-fns-tzpackage withformatInTimeZone,toZonedTime,fromZonedTime - v4 is ESM-first; constants must be imported from
date-fns/constants - v4 returns Invalid Date/NaN instead of throwing errors for invalid inputs
- All versions are 100% TypeScript with built-in types
v4 Bundle Size:
- Core date-fns function: ~2KB each (tree-shakeable)
TZDate: 1.2 KB |TZDateMini: 916 B (use Mini for internal calculations)UTCDate: 504 B |UTCDateMini: 239 B (use Mini for internal calculations)
v4 Timezone Functions (@date-fns/tz):
tz(): Creates timezone context for theinoptiontzName(): Returns human-readable timezone name (short, long, generic formats)tzScan(): Detects DST transitions within a date rangetzOffset(): Returns UTC offset in minutes.withTimeZone(): TZDate method for timezone conversion
v4 Core Functions (from date-fns):
transpose(): Converts dates between timezones (replacestoZonedTime/fromZonedTime)
</integration>
<red_flags>
RED FLAGS
new Date(string)for parsing - Browser-inconsistent, useparseISOorparse- Mutating dates -
date.setDate()causes side effects, use pure functions likeaddDays - *`import ` from date-fns** - Defeats tree-shaking, import individual functions
- Magic format strings -
format(date, 'yyyy-MM-dd')scattered in code, use named constants - Missing
isValidcheck - Parsed dates can be invalid, always validate after parsing - Using Moment.js tokens -
YYYY/DD(Moment) vsyyyy/dd(date-fns) - Hardcoded locale formats -
MM/dd/yyyyis US-only, useP/PP/PPPwith locale isWithinIntervalwith inverted start/end - Throws error if start > end- Month boundary surprises - Jan 31 + 1 month = Feb 28, not March 3
See reference.md for the complete red flags and gotchas list.
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md
(You MUST use parseISO() for ISO 8601 strings - NEVER use new Date(string) which has browser inconsistencies)
*(You MUST import only needed functions - NEVER use `import as dateFns` which defeats tree-shaking)**
(You MUST use pure functions that return new dates - NEVER mutate dates with setDate() or similar)
(You MUST use named constants for format strings and durations - NO magic strings like 'yyyy-MM-dd' scattered in code)
Failure to follow these rules will cause browser inconsistencies, bundle bloat, and mutation bugs.
</critical_reminders>