Handling Date and Time Correctly with Claude Code
Learn about handling date and time correctly using Claude Code. Includes practical code examples.
Implement Date and Time Handling Correctly With Claude Code
Date and time handling is full of unexpected pitfalls: time zones, formatting, locale support, and more. With Claude Code, you can efficiently implement robust date handling that follows best practices.
Choosing a Library
> Build a date/time utility.
> Use day.js, and implement timezone conversion, relative time display,
> formatting, and business day calculations.
- day.js: Lightweight (2KB), with a Moment.js-compatible API
- date-fns: Function-based, ideal for tree-shaking
- Temporal API: A future standard API (still in proposal stage)
Implementing a Date Utility
// src/lib/date-utils.ts
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import relativeTime from 'dayjs/plugin/relativeTime';
import 'dayjs/locale/en';
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(relativeTime);
dayjs.locale('en');
// Default timezone
const DEFAULT_TZ = 'America/New_York';
// Format presets
export const DATE_FORMATS = {
full: 'MMMM D, YYYY (ddd) HH:mm',
date: 'MMMM D, YYYY',
dateShort: 'M/D',
time: 'HH:mm',
iso: 'YYYY-MM-DDTHH:mm:ssZ',
api: 'YYYY-MM-DD',
} as const;
/**
* Format a UTC date string in the target timezone.
*/
export function formatDate(
date: string | Date,
format: keyof typeof DATE_FORMATS = 'date'
): string {
return dayjs(date).tz(DEFAULT_TZ).format(DATE_FORMATS[format]);
}
/**
* Return relative time ("3 minutes ago", "2 hours ago", "yesterday", etc.)
*/
export function timeAgo(date: string | Date): string {
const d = dayjs(date);
const now = dayjs();
const diffHours = now.diff(d, 'hour');
if (diffHours < 1) {
const diffMinutes = now.diff(d, 'minute');
if (diffMinutes < 1) return 'just now';
return `${diffMinutes} min ago`;
}
if (diffHours < 24) return `${diffHours} hours ago`;
if (diffHours < 48) return 'yesterday';
if (diffHours < 168) return `${Math.floor(diffHours / 24)} days ago`;
return formatDate(date, 'date');
}
/**
* Timezone conversion
*/
export function convertTimezone(
date: string | Date,
fromTz: string,
toTz: string
): dayjs.Dayjs {
return dayjs.tz(date, fromTz).tz(toTz);
}
/**
* Check whether a given date is a business day.
*/
export function isBusinessDay(date: string | Date): boolean {
const d = dayjs(date);
const dayOfWeek = d.day();
return dayOfWeek !== 0 && dayOfWeek !== 6; // Sunday=0, Saturday=6
}
/**
* Add N business days to a date.
*/
export function addBusinessDays(date: string | Date, days: number): dayjs.Dayjs {
let current = dayjs(date);
let remaining = days;
while (remaining > 0) {
current = current.add(1, 'day');
if (isBusinessDay(current.toDate())) {
remaining--;
}
}
return current;
}
Native Formatting With the Intl API
You can achieve many of these formats without a library, using the browser’s Intl API.
// src/lib/intl-date.ts
/**
* Format a date using Intl.DateTimeFormat.
*/
export function formatDateIntl(date: Date, style: 'long' | 'short' = 'long'): string {
return new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: style === 'long' ? 'long' : 'numeric',
day: 'numeric',
weekday: style === 'long' ? 'short' : undefined,
}).format(date);
}
/**
* Format the difference between two dates in a human-readable form.
*/
export function formatDateRange(start: Date, end: Date): string {
return new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).formatRange(start, end);
}
/**
* Format relative time.
*/
export function formatRelative(date: Date): string {
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffSec = Math.round(diffMs / 1000);
const diffMin = Math.round(diffSec / 60);
const diffHour = Math.round(diffMin / 60);
const diffDay = Math.round(diffHour / 24);
if (Math.abs(diffSec) < 60) return rtf.format(diffSec, 'second');
if (Math.abs(diffMin) < 60) return rtf.format(diffMin, 'minute');
if (Math.abs(diffHour) < 24) return rtf.format(diffHour, 'hour');
return rtf.format(diffDay, 'day');
}
Usage in a React Component
// src/components/TimeDisplay.tsx
'use client';
import { useState, useEffect } from 'react';
import { timeAgo } from '@/lib/date-utils';
export function TimeDisplay({ date }: { date: string }) {
const [display, setDisplay] = useState(timeAgo(date));
useEffect(() => {
const interval = setInterval(() => {
setDisplay(timeAgo(date));
}, 60000); // Update every minute
return () => clearInterval(interval);
}, [date]);
return (
<time dateTime={date} title={new Date(date).toLocaleString('en-US')}>
{display}
</time>
);
}
Common Pitfalls
- Ignoring time zones: When the server and client are in different time zones, always store UTC and convert on the client.
- Daylight saving time: Be careful when supporting users in regions that observe DST.
- Date.parse() quirks: Behavior varies between browsers, so use dayjs or similar to parse dates.
Related Articles
For internationalization in general, see the i18n implementation guide, and for currency formatting, see implementing currency formatting.
See the official day.js documentation (day.js.org) for the plugin list.
Free PDF: Claude Code Cheatsheet in 5 Minutes
Just enter your email and we'll send you the single-page A4 cheatsheet right away.
We handle your data with care and never send spam.
Level up your Claude Code workflow
50 battle-tested prompt templates you can copy-paste into Claude Code right now.
About the Author
Masa
Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.
Related Posts
7 Deployment Checks Before You Publish a Multilingual Claude Code Article Every Day
A practical checklist for publishing daily multilingual Claude Code articles without missing locales, breaking CTAs, or shipping stale pages.
Codex Automations for Content Ops: A Daily Revenue Workflow for Claude Code Sites
Use Codex Automations to turn analytics, article updates, CTA improvements, deployment, and verification into a daily revenue workflow.
Claude Code × GCP Cloud Functions Complete Guide | Rapid Serverless Function Development
Streamline GCP Cloud Functions with Claude Code. Implement HTTP/Pub/Sub/Firestore triggers, local testing, and deployment automation with real-world code examples from Masa's experience.
Related Products
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.