Formatting
Format dates, numbers, lists, and relative times with useFormatter
Basic Usage
import { useFormatter } from '@better-i18n/use-intl'
function ProductInfo({ price, date }) {
const format = useFormatter()
return (
<div>
<span>{format.number(price, { style: 'currency', currency: 'USD' })}</span>
<time>{format.dateTime(date, { dateStyle: 'medium' })}</time>
</div>
)
}Available Methods
| Method | Description |
|---|---|
dateTime(date, options) | Format a date/time |
number(value, options) | Format a number |
list(items, options) | Format a list of items |
relativeTime(date, options) | Format relative time (e.g., "2 hours ago") |
Date & Time Formatting
Date Styles
const format = useFormatter()
// Short date
format.dateTime(new Date(), { dateStyle: 'short' })
// "1/18/26"
// Medium date
format.dateTime(new Date(), { dateStyle: 'medium' })
// "Jan 18, 2026"
// Long date
format.dateTime(new Date(), { dateStyle: 'long' })
// "January 18, 2026"
// Full date
format.dateTime(new Date(), { dateStyle: 'full' })
// "Sunday, January 18, 2026"Time Styles
// Short time
format.dateTime(new Date(), { timeStyle: 'short' })
// "3:30 PM"
// With timezone
format.dateTime(new Date(), {
timeStyle: 'long',
timeZone: 'America/New_York'
})
// "3:30:00 PM EST"Combined Date & Time
format.dateTime(new Date(), {
dateStyle: 'medium',
timeStyle: 'short'
})
// "Jan 18, 2026, 3:30 PM"Custom Patterns
format.dateTime(new Date(), {
year: 'numeric',
month: 'long',
day: '2-digit',
weekday: 'short'
})
// "Sun, January 18, 2026"Number Formatting
Basic Numbers
const format = useFormatter()
format.number(1234567.89)
// "1,234,567.89"Currency
format.number(99.99, {
style: 'currency',
currency: 'USD'
})
// "$99.99"
format.number(99.99, {
style: 'currency',
currency: 'EUR'
})
// "€99.99"Percentages
format.number(0.75, { style: 'percent' })
// "75%"Compact Notation
format.number(1000000, { notation: 'compact' })
// "1M"
format.number(1234, { notation: 'compact', compactDisplay: 'long' })
// "1 thousand"Units
format.number(100, {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'short'
})
// "100 km"List Formatting
Conjunction (and)
const format = useFormatter()
format.list(['Apple', 'Banana', 'Orange'], { type: 'conjunction' })
// "Apple, Banana, and Orange"Disjunction (or)
format.list(['Red', 'Blue', 'Green'], { type: 'disjunction' })
// "Red, Blue, or Green"Unit Lists
format.list(['5 km', '10 km', '15 km'], { type: 'unit' })
// "5 km, 10 km, 15 km"Relative Time
Automatic Updates
import { useFormatter, useNow } from '@better-i18n/use-intl'
function TimeAgo({ date }) {
const format = useFormatter()
const now = useNow({ updateInterval: 60000 }) // Update every minute
return <time>{format.relativeTime(date, now)}</time>
}Examples
const format = useFormatter()
const now = new Date()
// Past times
format.relativeTime(new Date(now - 60000)) // "1 minute ago"
format.relativeTime(new Date(now - 3600000)) // "1 hour ago"
format.relativeTime(new Date(now - 86400000)) // "yesterday"
// Future times
format.relativeTime(new Date(now + 86400000)) // "tomorrow"
format.relativeTime(new Date(now + 604800000)) // "in 1 week"Real-World Examples
E-commerce Price Display
function PriceTag({ price, originalPrice, currency = 'USD' }) {
const format = useFormatter()
const discount = ((originalPrice - price) / originalPrice) * 100
return (
<div>
<span className="text-2xl font-bold">
{format.number(price, { style: 'currency', currency })}
</span>
{originalPrice > price && (
<>
<span className="line-through text-gray-500">
{format.number(originalPrice, { style: 'currency', currency })}
</span>
<span className="text-green-600">
{format.number(discount / 100, { style: 'percent' })} off
</span>
</>
)}
</div>
)
}Activity Feed
function ActivityItem({ action, users, timestamp }) {
const format = useFormatter()
return (
<div>
<span>{format.list(users, { type: 'conjunction' })}</span>
<span> {action}</span>
<time className="text-gray-500">
{format.relativeTime(timestamp)}
</time>
</div>
)
}Statistics Dashboard
function StatCard({ label, value, type }) {
const format = useFormatter()
const formattedValue = () => {
switch (type) {
case 'currency':
return format.number(value, { style: 'currency', currency: 'USD' })
case 'percent':
return format.number(value / 100, { style: 'percent' })
case 'compact':
return format.number(value, { notation: 'compact' })
default:
return format.number(value)
}
}
return (
<div className="p-4 bg-white rounded-lg shadow">
<p className="text-sm text-gray-500">{label}</p>
<p className="text-2xl font-bold">{formattedValue()}</p>
</div>
)
}Related
- Translations - Translation strings with inline formatting
- Provider - Configure timezone for formatting