Skip to content

formatDate

A default set of date formatters, which takes into account both the interval in between in each data point but also the start/end data points.

Without shown, the year rides on the first and last dates and on each January 1st. Given shown (the dates actually drawn, such as the axis labels left after thinning), it rides on the first shown date and on the first shown date after each change of year instead, so the year stays readable however the labels are thinned; at hourly steps, the date rides with the hour on the first shown date of each day. A label carrying the year at hourly steps reads its date, year, and hour.

Given a date and the full ordered array it belongs to, formatDate picks a label that fits the spacing of the whole series. Dates one year apart are labeled by year alone.

import {formatDate} from "@d3plus/format";

const yearly = [
  new Date(2018, 0, 1),
  new Date(2019, 0, 1),
  new Date(2020, 0, 1),
  new Date(2021, 0, 1),
  new Date(2022, 0, 1),
  new Date(2023, 0, 1),
  new Date(2024, 0, 1),
];
yearly.map(d => formatDate(d, yearly));

The third argument replaces d3’s timeFormat with any function that turns a specifier into a formatter. Here a timeFormatLocale built from the es-ES dictionary in @d3plus/locales supplies Spanish month names.

import {formatDate} from "@d3plus/format";
import {timeFormatLocale} from "d3-time-format";
import {locale} from "@d3plus/locales";

const monthly = [
  new Date(2023, 0, 1),
  new Date(2023, 1, 1),
  new Date(2023, 2, 1),
  new Date(2023, 3, 1),
  new Date(2023, 4, 1),
  new Date(2023, 5, 1),
  new Date(2023, 6, 1),
  new Date(2023, 7, 1),
  new Date(2023, 8, 1),
  new Date(2023, 9, 1),
  new Date(2023, 10, 1),
  new Date(2023, 11, 1),
];
monthly.map(d =>
  formatDate(d, monthly, timeFormatLocale(locale["es-ES"]).format),
);
const daily = [
  new Date(2024, 2, 1),
  new Date(2024, 2, 2),
  new Date(2024, 2, 3),
  new Date(2024, 2, 4),
  new Date(2024, 2, 5),
  new Date(2024, 2, 6),
  new Date(2024, 2, 7),
  new Date(2024, 2, 8),
  new Date(2024, 2, 9),
  new Date(2024, 2, 10),
];
daily.map(d => formatDate(d, daily, timeFormatLocale(locale["es-ES"]).format));

The interval between neighbouring dates decides the base format (quarter, month, day, or hour), and the first and last dates, plus any date that starts a new year or month, get a fuller label so the strip can be read without an axis title. Arrays of five dates or fewer always use the fuller label.

import {formatDate} from "@d3plus/format";

const quarterly = [
  new Date(2022, 0, 1),
  new Date(2022, 3, 1),
  new Date(2022, 6, 1),
  new Date(2022, 9, 1),
  new Date(2023, 0, 1),
  new Date(2023, 3, 1),
  new Date(2023, 6, 1),
  new Date(2023, 9, 1),
];
quarterly.map(d => formatDate(d, quarterly));
const monthly = [
  new Date(2023, 0, 1),
  new Date(2023, 1, 1),
  new Date(2023, 2, 1),
  new Date(2023, 3, 1),
  new Date(2023, 4, 1),
  new Date(2023, 5, 1),
  new Date(2023, 6, 1),
  new Date(2023, 7, 1),
  new Date(2023, 8, 1),
  new Date(2023, 9, 1),
  new Date(2023, 10, 1),
  new Date(2023, 11, 1),
];
monthly.map(d => formatDate(d, monthly));
const daily = [
  new Date(2024, 2, 1),
  new Date(2024, 2, 2),
  new Date(2024, 2, 3),
  new Date(2024, 2, 4),
  new Date(2024, 2, 5),
  new Date(2024, 2, 6),
  new Date(2024, 2, 7),
  new Date(2024, 2, 8),
  new Date(2024, 2, 9),
  new Date(2024, 2, 10),
];
daily.map(d => formatDate(d, daily));
const hourly = [
  new Date(2024, 2, 1),
  new Date(2024, 2, 1, 1),
  new Date(2024, 2, 1, 2),
  new Date(2024, 2, 1, 3),
  new Date(2024, 2, 1, 4),
  new Date(2024, 2, 1, 5),
  new Date(2024, 2, 1, 6),
  new Date(2024, 2, 1, 7),
  new Date(2024, 2, 1, 8),
  new Date(2024, 2, 1, 9),
  new Date(2024, 2, 1, 10),
  new Date(2024, 2, 1, 11),
];
hourly.map(d => formatDate(d, hourly));

Parameters

import {formatDate} from "@d3plus/format";
drequiredDate

The date to format.

dataArrayrequiredArray.<Date>

The full array of ordered Date Objects.

formatterDateFormatterDefault timeFormat

Optional custom format string or function.

shownArray.<Date>

Optional dates drawn alongside d, which decide which labels carry the year (and, at hourly steps, the date).