كيفية تنسيق التواريخ للإعدادات المحلية المختلفة في 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 اختيارية وتعيد سلسلة منسقة حسب اللغة المحلية. هذا مفيد عندما يجب تضمين التاريخ المنسق في سلسلة أخرى أو استخدامه كقيمة خاصية.

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. يقوم هذا النهج بتنسيق التواريخ مسبقًا على الخادم أو أثناء الإنشاء الثابت، مما يقلل من العمل على جانب العميل.