Staffbase

Hooks

useFormatDateTime

A React hook that returns a memoised Intl.DateTimeFormat instance, letting you format dates and times in any locale with just a few props.

December 25, 2025 at 2:30 PM

The formatter is only recreated when locale, dateStyle, or timeStyle actually change — it’s memoised with useMemo internally, so the returned object is stable between renders.

Usage

Import the hook from the package and call it with a locale and the desired format styles.

Anatomy
import {useFormatDateTime} from '@staffbase/design/hooks';

const EventDate = ({date}: {date: Date}) => {
  const locale = navigator.language; // or from your i18n context
  const formatter = useFormatDateTime(locale, 'long', 'short');

  return <time dateTime={date.toISOString()}>{formatter.format(date)}</time>;
};

Date only vs time only

Pass undefined for timeStyle to get a date-only output, or undefined for dateStyle to get a time-only output.

Anatomy
// Date only — pass undefined for timeStyle
const dateFormatter = useFormatDateTime('de-DE', 'long', undefined);
dateFormatter.format(new Date()); // "25. Dezember 2025"

// Time only — pass undefined for dateStyle
const timeFormatter = useFormatDateTime('de-DE', undefined, 'short');
timeFormatter.format(new Date()); // "14:30"

Format styles

The same reference date — December 25, 2025 at 14:30 — rendered across every format option. Switch the language dropdown above each table to see how the output changes per locale.

dateStyle

dateStyle controls how the date portion is rendered. Pass undefined for timeStyle to get a date-only output.

dateStyleOutput
short
12/25/25
medium
Dec 25, 2025
long
December 25, 2025

timeStyle

timeStyle controls how the time portion is rendered. Pass undefined for dateStyle to get a time-only output.

timeStyleOutput
short
2:30 PM
medium
2:30:00 PM

Combined

When both dateStyle and timeStyle are provided, the date and time are joined in a single locale-aware string.

short
medium
short
12/25/25, 2:30 PM12/25/25, 2:30:00 PM
medium
Dec 25, 2025, 2:30 PMDec 25, 2025, 2:30:00 PM
long
December 25, 2025 at 2:30 PMDecember 25, 2025 at 2:30:00 PM

Formatting date ranges

Intl.DateTimeFormat exposes a formatRange(startDate, endDate) method that intelligently collapses the shared parts of two dates — so instead of “December 25, 2025 – January 3, 2026” you only see the parts that actually differ. The hook returns the formatter instance directly, so formatRange is available without any extra work.

Reference range: December 25, 2025 14:30 → January 3, 2026 09:15.

December 25, 2025 – January 3, 2026

Anatomy
import {useFormatDateTime} from '@staffbase/design/hooks';

const EventDuration = ({start, end}: {start: Date; end: Date}) => {
  const locale = navigator.language;
  const formatter = useFormatDateTime(locale, 'long', 'short');

  // "December 25, 2025, 2:30 PM – January 3, 2026, 9:15 AM"
  return <span>{formatter.formatRange(start, end)}</span>;
};

Use formatRangeToParts for custom rendering — for example to bold the parts that differ between the two dates:

Anatomy
const formatter = useFormatDateTime('en-US', 'long', undefined);
const parts = formatter.formatRangeToParts(start, end);

return (

  <span>
    {parts.map((part, i) =>
      part.source === 'shared' ? <span key={i}>{part.value}</span> : <strong key={i}>{part.value}</strong>,
    )}
  </span>
);

API reference

useFormatDateTime(locale, dateStyle, timeStyle)

Name Type Description
locale
stringstring[]Intl.LocaleIntl.Locale[]
A BCP 47 language tag (or list of tags) passed to Intl.DateTimeFormat.
dateStyle
shortmediumlongundefined
How the date portion is rendered. Pass undefined to omit the date.
timeStyle
shortmediumundefined
How the time portion is rendered. Pass undefined to omit the time.

Returns an Intl.DateTimeFormat instance. Use .format(date), .formatRange(start, end), or .formatRangeToParts(start, end).