Comment obtenir les parties individuelles d'une date formatée en JavaScript

Utilisez formatToParts() pour accéder séparément à chaque composant d'une date formatée selon les paramètres régionaux

Introduction

La méthode format() renvoie une chaîne formatée complète comme "15 janvier 2025" ou "15/01/2025". Cela fonctionne bien pour un affichage simple, mais vous ne pouvez pas styliser les parties individuelles différemment. Vous ne pouvez pas mettre le nom du mois en gras, colorer l'année différemment ou appliquer un balisage personnalisé à des composants spécifiques.

JavaScript fournit la méthode formatToParts() pour résoudre ce problème. Au lieu de renvoyer une seule chaîne, elle renvoie un tableau d'objets, chacun représentant une partie de la date formatée. Chaque partie a un type comme month, day ou year, et une valeur comme January, 15 ou 2025. Vous pouvez ensuite traiter ces parties pour appliquer un style personnalisé, créer des mises en page complexes ou intégrer des dates formatées dans des interfaces utilisateur riches.

Pourquoi les chaînes formatées sont difficiles à personnaliser

Lorsque vous recevez une chaîne formatée comme "15 janvier 2025", vous ne pouvez pas facilement identifier où se termine le mois et où commence le jour. Différents paramètres régionaux placent les composants dans des ordres différents. Certains paramètres régionaux utilisent des séparateurs différents. Analyser ces chaînes de manière fiable nécessite une logique complexe qui duplique les règles de formatage déjà implémentées dans l'API Intl.

Considérez une application de calendrier qui affiche les dates avec le nom du mois en gras. Avec format(), vous devriez :

  1. Détecter quels caractères représentent le nom du mois
  2. Tenir compte des espaces et de la ponctuation entre les composants
  3. Gérer différents formats de mois selon les paramètres régionaux
  4. Analyser la chaîne avec précaution pour éviter de casser la date

Cette approche est fragile et sujette aux erreurs. Toute modification des règles de formatage des paramètres régionaux casse votre logique d'analyse.

La méthode formatToParts() élimine ce problème en fournissant les composants séparément. Vous recevez des données structurées qui vous indiquent exactement quelle partie correspond à quoi, quel que soit le paramètre régional.

Utiliser formatToParts pour obtenir les composants de date

La méthode formatToParts() fonctionne de manière identique à format() à l'exception de sa valeur de retour. Vous créez un formateur avec les mêmes options, puis appelez formatToParts() au lieu de format().

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);

Cela produit un tableau d'objets :

[
  { type: "month", value: "January" },
  { type: "literal", value: " " },
  { type: "day", value: "15" },
  { type: "literal", value: ", " },
  { type: "year", value: "2025" }
]

Chaque objet contient une propriété type identifiant ce que la partie représente et une propriété value contenant la chaîne réelle. Les parties apparaissent dans le même ordre qu'elles apparaîtraient dans la sortie formatée.

Vous pouvez le vérifier en joignant toutes les valeurs ensemble :

const formatted = parts.map(part => part.value).join("");
console.log(formatted);
// Output: "January 15, 2025"

Les parties concaténées produisent exactement la même sortie que l'appel de format().

Comprendre les types de parties

La propriété type identifie chaque composant. Différentes options de formatage produisent différents types de parties.

Pour le formatage de date de base :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
//   { type: "month", value: "January" },
//   { type: "literal", value: " " },
//   { type: "day", value: "15" },
//   { type: "literal", value: ", " },
//   { type: "year", value: "2025" }
// ]

Le type month représente le nom ou le numéro du mois. Le type day représente le jour du mois. Le type year représente l'année. Le type literal représente l'espacement, la ponctuation ou tout autre texte inséré par le formateur.

Pour les dates avec jours de la semaine :

const formatter = new Intl.DateTimeFormat("en-US", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
//   { type: "weekday", value: "Wednesday" },
//   { type: "literal", value: ", " },
//   { type: "month", value: "January" },
//   { type: "literal", value: " " },
//   { type: "day", value: "15" },
//   { type: "literal", value: ", " },
//   { type: "year", value: "2025" }
// ]

Le type weekday représente le jour de la semaine.

Pour les dates avec heures :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  second: "numeric"
});

const date = new Date(2025, 0, 15, 14, 30, 45);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
//   { type: "month", value: "January" },
//   { type: "literal", value: " " },
//   { type: "day", value: "15" },
//   { type: "literal", value: ", " },
//   { type: "year", value: "2025" },
//   { type: "literal", value: " at " },
//   { type: "hour", value: "2" },
//   { type: "literal", value: ":" },
//   { type: "minute", value: "30" },
//   { type: "literal", value: ":" },
//   { type: "second", value: "45" },
//   { type: "literal", value: " " },
//   { type: "dayPeriod", value: "PM" }
// ]

Les types hour, minute et second représentent les composants temporels. Le type dayPeriod représente AM ou PM au format 12 heures.

Appliquer un style personnalisé aux parties de date

Le cas d'usage principal de formatToParts() est d'appliquer différents styles à différents composants. Vous pouvez traiter le tableau de parties pour envelopper des types spécifiques dans des éléments HTML.

Mettre le nom du mois en gras :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const html = parts
  .map(part => {
    if (part.type === "month") {
      return `<strong>${part.value}</strong>`;
    }
    return part.value;
  })
  .join("");

console.log(html);
// Output: "<strong>January</strong> 15, 2025"

Cette approche fonctionne pour tout langage de balisage. Vous pouvez générer du HTML, du JSX ou tout autre format en traitant le tableau de parties.

Styliser l'année différemment :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const html = parts
  .map(part => {
    if (part.type === "year") {
      return `<span class="text-gray-500">${part.value}</span>`;
    }
    return part.value;
  })
  .join("");

console.log(html);
// Output: "January 15, <span class="text-gray-500">2025</span>"

Ce modèle est courant dans les affichages de calendrier où différents composants nécessitent une emphase visuelle différente.

Créer des affichages de date personnalisés avec plusieurs styles

Les interfaces complexes combinent souvent plusieurs règles de style. Vous pouvez appliquer différentes classes ou éléments à différents types de parties simultanément.

const formatter = new Intl.DateTimeFormat("en-US", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);

const html = parts
  .map(part => {
    switch (part.type) {
      case "weekday":
        return `<span class="weekday">${part.value}</span>`;
      case "month":
        return `<span class="month">${part.value}</span>`;
      case "day":
        return `<span class="day">${part.value}</span>`;
      case "year":
        return `<span class="year">${part.value}</span>`;
      case "literal":
        return `<span class="literal">${part.value}</span>`;
      default:
        return part.value;
    }
  })
  .join("");

console.log(html);
// Output: "<span class="weekday">Wednesday</span><span class="literal">, </span><span class="month">January</span><span class="literal"> </span><span class="day">15</span><span class="literal">, </span><span class="year">2025</span>"

Ce contrôle granulaire permet un style précis pour chaque composant. Vous pouvez ensuite utiliser CSS pour styliser chaque classe différemment.

Créer des mises en page de date personnalisées

Vous pouvez réorganiser les composants de date dans des mises en page personnalisées qui diffèrent du format de locale standard. Extrayez des parties spécifiques et composez-les dans n'importe quel ordre.

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);

const day = parts.find(p => p.type === "day").value;
const month = parts.find(p => p.type === "month").value;
const year = parts.find(p => p.type === "year").value;

const customLayout = `
  <div class="date-card">
    <div class="day-large">${day}</div>
    <div class="month-small">${month}</div>
    <div class="year-small">${year}</div>
  </div>
`;

console.log(customLayout);

Cela crée une mise en page de carte verticale avec le jour affiché de manière proéminente, suivi du mois et de l'année. Les composants restent correctement localisés même si la mise en page diffère du formatage standard.

Tous les types de parties disponibles

La propriété type peut avoir ces valeurs selon les options de formatage utilisées :

  • weekday : jour de la semaine comme lundi ou lun.
  • era : indicateur d'ère comme av. J.-C., apr. J.-C. ou AEC
  • year : année comme 2025
  • month : nom ou numéro du mois comme janvier ou 01
  • day : jour du mois comme 15
  • dayPeriod : AM ou PM ou autres périodes de jour spécifiques à la locale
  • hour : heure comme 14 ou 2
  • minute : minute comme 30
  • second : seconde comme 45
  • fractionalSecond : millisecondes ou autres fractions de secondes
  • timeZoneName : nom du fuseau horaire comme PST ou heure normale du Pacifique
  • literal : espacement, ponctuation ou autre texte ajouté par le formatage
  • relatedYear : année grégorienne dans les systèmes de calendrier alternatifs
  • yearName : année nommée dans certains systèmes de calendrier
  • unknown : jetons non reconnus

Toutes les options de formatage ne produisent pas tous les types de parties. Les parties que vous recevez dépendent de la valeur de la date et de la configuration du formateur.

Dates avec indicateurs d'ère :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  era: "short"
});

const date = new Date(-100, 0, 1);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
//   { type: "year", value: "101" },
//   { type: "literal", value: " " },
//   { type: "era", value: "BC" }
// ]

Dates avec fuseaux horaires :

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  timeZoneName: "short"
});

const date = new Date(2025, 0, 15, 14, 30);
const parts = formatter.formatToParts(date);
console.log(parts);
// Parts will include { type: "timeZoneName", value: "PST" } or similar

Dates avec fractions de secondes :

const formatter = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  second: "numeric",
  fractionalSecondDigits: 3
});

const date = new Date(2025, 0, 15, 14, 30, 45, 123);
const parts = formatter.formatToParts(date);
// Parts will include { type: "fractionalSecond", value: "123" }

Mise en évidence conditionnelle des composants de date

Certaines applications mettent en évidence des composants de date spécifiques en fonction de la logique métier. Avec formatToParts(), vous pouvez appliquer un style basé sur la valeur de la date tout en maintenant un formatage approprié.

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

function formatDateWithHighlight(date) {
  const parts = formatter.formatToParts(date);
  const isWeekend = date.getDay() === 0 || date.getDay() === 6;

  const html = parts
    .map(part => {
      if (part.type === "day" && isWeekend) {
        return `<span class="text-blue-600 font-bold">${part.value}</span>`;
      }
      return part.value;
    })
    .join("");

  return html;
}

const saturday = new Date(2025, 0, 18);
console.log(formatDateWithHighlight(saturday));
// Output: "January <span class="text-blue-600 font-bold">18</span>, 2025"

const monday = new Date(2025, 0, 13);
console.log(formatDateWithHighlight(monday));
// Output: "January 13, 2025"

La date reçoit un formatage approprié pour la locale tandis que le style conditionnel s'applique en fonction de la logique métier.

Création d'affichages de dates accessibles

Vous pouvez utiliser formatToParts() pour ajouter des attributs d'accessibilité aux dates formatées. Cela aide les lecteurs d'écran à annoncer correctement les valeurs.

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

function formatAccessibleDate(date) {
  const parts = formatter.formatToParts(date);
  const formatted = parts.map(part => part.value).join("");
  const isoDate = date.toISOString().split('T')[0];

  return `<time datetime="${isoDate}">${formatted}</time>`;
}

const date = new Date(2025, 0, 15);
console.log(formatAccessibleDate(date));
// Output: "<time datetime="2025-01-15">January 15, 2025</time>"

Cela garantit que les lecteurs d'écran peuvent annoncer correctement la date tandis que l'affichage montre la version formatée selon la locale.

Comment les parties préservent le formatage spécifique à la locale

Le tableau de parties maintient automatiquement les règles de formatage spécifiques à la locale. Différentes locales placent les composants dans des ordres différents et utilisent des formats différents, mais formatToParts() gère ces différences.

const usFormatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const date = new Date(2025, 0, 15);
console.log(usFormatter.formatToParts(date));
// [
//   { type: "month", value: "January" },
//   { type: "literal", value: " " },
//   { type: "day", value: "15" },
//   { type: "literal", value: ", " },
//   { type: "year", value: "2025" }
// ]

const ukFormatter = new Intl.DateTimeFormat("en-GB", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(ukFormatter.formatToParts(date));
// [
//   { type: "day", value: "15" },
//   { type: "literal", value: " " },
//   { type: "month", value: "January" },
//   { type: "literal", value: " " },
//   { type: "year", value: "2025" }
// ]

Le formatage britannique place le jour avant le mois. Votre code de style traite le tableau de parties de la même manière quelle que soit la locale, et le formatage s'adapte automatiquement.

const jpFormatter = new Intl.DateTimeFormat("ja-JP", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(jpFormatter.formatToParts(date));
// [
//   { type: "year", value: "2025" },
//   { type: "literal", value: "年" },
//   { type: "month", value: "1月" },
//   { type: "day", value: "15" },
//   { type: "literal", value: "日" }
// ]

Le formatage japonais utilise un ordre différent et inclut des littéraux de caractères comme 年 (année) et 日 (jour). Le tableau de parties reflète automatiquement ces conventions spécifiques à la locale.

Combinaison de formatToParts avec des composants de framework

Les frameworks modernes comme React peuvent utiliser formatToParts() pour construire des composants efficacement.

function DateDisplay({ date, locale, options }) {
  const formatter = new Intl.DateTimeFormat(locale, options);
  const parts = formatter.formatToParts(date);

  return (
    <span className="date-display">
      {parts.map((part, index) => {
        if (part.type === "month") {
          return <strong key={index}>{part.value}</strong>;
        }
        if (part.type === "year") {
          return <span key={index} className="text-sm text-gray-500">{part.value}</span>;
        }
        return <span key={index}>{part.value}</span>;
      })}
    </span>
  );
}

Ce composant applique différents styles à différentes parties tout en maintenant un formatage approprié pour n'importe quelle locale.

Quand utiliser formatToParts plutôt que format

Utilisez format() lorsque vous avez besoin d'une simple chaîne formatée sans personnalisation. C'est le cas le plus courant pour l'affichage de dates.

Utilisez formatToParts() lorsque vous devez :

  • Appliquer différents styles à différentes parties de la date
  • Construire du HTML ou du JSX avec des dates formatées
  • Ajouter des attributs ou des métadonnées à des composants spécifiques
  • Réorganiser les composants de date dans des mises en page personnalisées
  • Intégrer des dates formatées dans des mises en page complexes
  • Traiter la sortie formatée de manière programmatique

La méthode formatToParts() a un léger surcoût par rapport à format() car elle crée un tableau d'objets au lieu d'une seule chaîne. Cette différence est négligeable pour les applications typiques, mais si vous formatez des milliers de dates par seconde, format() offre de meilleures performances.

Pour la plupart des applications, choisissez en fonction de vos besoins de style plutôt que des préoccupations de performance. Si vous n'avez pas besoin de personnaliser la sortie, utilisez format(). Si vous avez besoin d'un style ou d'un balisage personnalisé, utilisez formatToParts().