كيفية تنسيق التواريخ حسب المناطق المختلفة في React Router v7

عرض التواريخ بتنسيقات خاصة بكل منطقة

المشكلة

لا يوجد تنسيق كتابي عالمي للتواريخ. على سبيل المثال، التسلسل الرقمي 10/12/2025 يشير إلى 12 أكتوبر في الولايات المتحدة لكنه يعني 10 ديسمبر في المملكة المتحدة. حتى التنسيقات مثل "Oct 12, 2025" تفترض أسماء أشهر إنجليزية وترتيباً معيناً قد لا يتوافق مع توقعات المستخدمين. عندما تعرض التطبيقات التواريخ بشكل ثابت واحد، يبدو ذلك غريباً للمستخدمين من مناطق ذات عادات مختلفة، مما يقلل من وضوح المعلومات ويضعف الثقة.

كل منطقة جغرافية لها قواعدها الخاصة في عرض التواريخ، مثل ترتيب اليوم والشهر والسنة، ونوع الفواصل المستخدمة، وما إذا كانت أسماء الأشهر تكتب كاملة أو مختصرة. تجاهل هذه القواعد يجبر المستخدمين على ترجمة التواريخ ذهنياً إلى الصيغة التي اعتادوا عليها، ما يزيد من الجهد الذهني وخطر سوء الفهم.

الحل

قم بتنسيق قيم التواريخ حسب إعدادات المستخدم المحلية عبر الاعتماد على واجهات برمجة التطبيقات الخاصة بالتدويل والتي تدرك فروقات المناطق الجغرافية. بدلاً من بناء نصوص التواريخ يدوياً، مرر كائنات التاريخ إلى دوال أو مكونات تنسيق تتولى تطبيق الترتيب الصحيح والفواصل وأسماء الأشهر حسب المنطقة النشطة.

تقدم مكتبة React-intl مكونات إعلانية ودوال برمجية تستقبل خيارات تنسيق التواريخ القياسية وتنتج نصوصاً ملائمة للمنطقة. بتحديد أجزاء التاريخ المراد إظهارها ومستوى التفاصيل، يمكنك التحكم في نمط العرض مع ضمان التعامل مع اختلافات المناطق من خلال المكتبة. بهذه الطريقة، يبقى منطق تنسيق التواريخ منفصلاً عن مكونات العرض ويوفر اتساقاً في التطبيق بالكامل.

الخطوات

1. تنسيق التواريخ في المكونات باستخدام FormattedDate

استخدم المكون FormattedDate من مكتبة react-intl لعرض التواريخ بتنسيق يتوافق مع اللغة المحلية. يقبل هذا المكون قيمة تاريخية وخيارات تنسيق تتوافق مع Intl.DateTimeFormatOptions.

import { FormattedDate } from "react-intl";

export default function EventCard({ event }) {
  return (
    <article>
      <h2>{event.title}</h2>
      <time>
        <FormattedDate
          value={event.date}
          year="numeric"
          month="long"
          day="numeric"
        />
      </time>
      <p>{event.description}</p>
    </article>
  );
}

يستخدم المكون FormattedDate واجهات برمجة التطبيقات formatDate وIntl.DateTimeFormat لإنتاج نص يتناسب مع اللغة المحلية المحددة في IntlProvider. وتتحكم الخيارات year وmonth وday في تحديد الأجزاء التي تظهر وكيفية تنسيقها.

2. تنسيق التواريخ بشكل برمجي باستخدام useIntl

استخدم الخطاف useIntl للوصول لطريقة formatDate عندما تحتاج إلى سلسلة نصية لتاريخ منسق في سياقات غير مرئية مثل السمات أو ملصقات aria أو تحويلات البيانات.

import { useIntl } from "react-intl";

export default function EventList({ events }) {
  const intl = useIntl();

  return (
    <ul>
      {events.map((event) => {
        const formattedDate = intl.formatDate(event.date, {
          year: "numeric",
          month: "short",
          day: "numeric",
        });

        return (
          <li key={event.id}>
            <a
              href={`/events/${event.id}`}
              aria-label={`${event.title} on ${formattedDate}`}
            >
              {event.title}
            </a>
          </li>
        );
      })}
    </ul>
  );
}

تستقبل دالة formatDate قيمة تاريخية وخيارات Intl.DateTimeFormatOptions اختيارية، وتعيد نصًا منسقًا حسب اللغة المحلية. يعد ذلك مفيدًا عند الحاجة لإدراج التاريخ المنسق ضمن سلسلة نصية أخرى أو استخدامه كقيمة خاصية (prop).

3. إنشاء مساعد لتنسيق التواريخ قابل لإعادة الاستخدام

استخرج أنماط تنسيق التواريخ الشائعة في دالة مساعدة تقوم بلف intl.formatDate لضمان التناسق في جميع أنحاء التطبيق.

import { useIntl } from "react-intl";

export function useDateFormatter() {
  const intl = useIntl();

  return {
    formatShortDate: (date: Date | number) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "numeric",
        day: "numeric",
      }),

    formatLongDate: (date: Date | number) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "long",
        day: "numeric",
      }),

    formatDateTime: (date: Date | number) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "short",
        day: "numeric",
        hour: "numeric",
        minute: "2-digit",
      }),
  };
}

يقوم هذا الخطاف بتجميع منطق التنسيق في مكان واحد، مما يسهل تطبيق أنماط تواريخ موحدة في كامل التطبيق. تستدعي المكونات الطريقة المناسبة حسب مستوى التفاصيل المطلوب.

4. تنسيق التواريخ أثناء تحميل بيانات المسارات

عند الحاجة لتنسيق التواريخ أثناء تحميل البيانات، استخرج اللغة المحلية من الطلب واستخدم createIntl لتنسيق التواريخ قبل إعادة بيانات اللودر.

import type { Route } from "./+types/event";
import { createIntl, createIntlCache } from "react-intl";

const cache = createIntlCache();

export async function loader({ request }: Route.LoaderArgs) {
  const url = new URL(request.url);
  const locale = url.searchParams.get("locale") || "en";

  const event = await fetchEvent();

  const intl = createIntl({ locale, messages: {} }, cache);

  return {
    event,
    formattedDate: intl.formatDate(event.date, {
      year: "numeric",
      month: "long",
      day: "numeric",
    }),
  };
}

export default function Event({ loaderData }: Route.ComponentProps) {
  return (
    <article>
      <h1>{loaderData.event.title}</h1>
      <time>{loaderData.formattedDate}</time>
    </article>
  );
}

تنشئ دالة createIntl كائن intl يمكنه تنسيق التواريخ خارج مكونات React. تتيح لك هذه الطريقة تنسيق التواريخ مسبقًا على الخادم أو أثناء إنشاء الصفحات بشكل ثابت، مما يقلل من عبء العمل على المتصفح.