كان العمل مع التواريخ والأوقات نقطة ألم طويلة للمطورين في JavaScript. لقد دفع كائن Date
الأصلي، بخصائصه وحدوده، العديد من المطورين نحو مكتبات الطرف الثالث مثل Moment.js أو date-fns. ومع ذلك، فإن لجنة TC39 (المسؤولة عن تطوير JavaScript) تعمل على حل: واجهة برمجة التطبيقات الزمنية (Temporal API). يعد هذا النهج الشامل والحديث للتعامل مع التواريخ والأوقات وعداً بحل القضايا المستمرة مع العمليات الزمنية في JavaScript.
المشكلة مع كائن Date في JavaScript
قبل الغوص في واجهة برمجة التطبيقات الزمنية، من المهم فهم قيود كائن Date
الحالي:
- الحالة القابلة للتغيير: يمكن تعديل كائنات التاريخ في مكانها، مما يؤدي إلى آثار جانبية غير متوقعة
- وظائف محدودة: تتطلب العمليات البسيطة مثل إضافة الأيام أو مقارنة التواريخ كوداً معقداً
- عدم اتساق تحليل السلاسل: يعتبر تحليل التواريخ من السلاسل غير موثوق به عبر المتصفحات
- عدم وجود دعم للمنطقة الزمنية: معالجة ضعيفة للمناطق الزمنية بما يتجاوز UTC والوقت المحلي
- تقويم غريغوري فقط: عدم وجود دعم لأنظمة التقويم الأخرى
- واجهة برمجة التطبيقات المحيرة: طرق مثل
getMonth()
تعيد قيمًا بفهرس يبدأ من صفر (0-11 بدلاً من 1-12)
لقد جعلت هذه القضايا العمل مع التواريخ في JavaScript عرضة للأخطاء ومحبطًا، مما أدى إلى اعتماد واسع على مكتبات الطرف الثالث.
تقديم واجهة برمجة التطبيقات الزمنية
تقدم واجهة برمجة التطبيقات الزمنية إضافة مقترحة لJavaScript توفر حلاً حديثًا وشاملاً للعمل مع التواريخ والأوقات. تم تصميمها ككائن عالمي (Temporal
) يعمل كمساحة اسم على أعلى مستوى (مما يشبه كائن Math
)، ويحتوي على فئات مختلفة لعمليات التاريخ والوقت المختلفة.
تشمل المبادئ الأساسية وراء واجهة برمجة التطبيقات الزمنية ما يلي:
- عدم القابلية للتغيير: جميع كائنات Temporal غير قابلة للتغيير، مما يقضي على الآثار الجانبية
- الوضوح: فصل واضح بين الأنواع المختلفة من مفاهيم التاريخ/الوقت
- دعم المنطقة الزمنية: دعم من الدرجة الأولى لجميع المناطق الزمنية، بما في ذلك الحسابات الآمنة لتغيير التوقيت الصيفي
- أنظمة تقويم متعددة: دعم للتقاويم غير الغريغورية
- الدقة: دقة نانو ثانية لحسابات الوقت
- الاتساق: تحليل وتنسيق موحد
أنواع البيانات الرئيسية في واجهة برمجة التطبيقات الزمنية
تقدم واجهة برمجة التطبيقات الزمنية عدة فئات متخصصة للتعامل مع جوانب مختلفة من التاريخ والوقت:
أنواع البيانات البسيطة (بدون معلومات حول المنطقة الزمنية)
- Temporal.PlainDate: يمثل تاريخ تقويمي (مثل 24 أغسطس 2006) دون معلومات عن الوقت أو المنطقة الزمنية
- Temporal.PlainTime: يمثل الوقت كما هو على الساعة (مثل 7:39 مساءً) دون تاريخ أو منطقة زمنية
- Temporal.PlainDateTime: يجمع بين التاريخ ووقت الساعة دون معلومات عن المنطقة الزمنية
- Temporal.PlainYearMonth: يمثل سنة وشهر محددين (مثل أكتوبر 2020)
- Temporal.PlainMonthDay: يمثل شهرًا ويومًا دون السنة (مثل 14 يوليو)
أنواع البيانات الموزونة (مع معلومات عن المنطقة الزمنية)
- Temporal.ZonedDateTime: كائن تاريخ/وقت واعٍ بالمنطقة الزمنية، يمثل حدثًا حقيقيًا في وقت معين من وجهة نظر منطقة معينة
- Temporal.Instant: يمثل نقطة ثابتة في الوقت (الوقت المحدد)، دون اعتبار للتقويم أو الموقع
أنواع إضافية
- Temporal.Duration: يعبر عن فترة زمنية (مثل 5 دقائق و30 ثانية)
- Temporal.TimeZone: يمثل منطقة زمنية ويوفر طرق تحوّل
- Temporal.Calendar: يمثل نظام تقويم
العمل مع واجهة برمجة التطبيقات الزمنية
إنشاء كائنات زمنية
توفر واجهة برمجة التطبيقات الزمنية عدة طرق لإنشاء الكائنات:
// الحصول على التاريخ والوقت الحاليين
const now = Temporal.Now.plainDateTimeISO();
console.log(now.toString()); // مثل، 2023-08-24T14:30:45.123456789
// فقط التاريخ
const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // مثل، 2023-08-24
// فقط الوقت
const currentTime = Temporal.Now.plainTimeISO();
console.log(currentTime.toString()); // مثل، 14:30:45.123456789
// إنشاء كائنات من المكونات
const date = Temporal.PlainDate.from({ year: 2023, month: 8, day: 24 });
const time = Temporal.PlainTime.from({ hour: 14, minute: 30, second: 45 });
const dateTime = Temporal.PlainDateTime.from({
year: 2023,
month: 8,
day: 24,
hour: 14,
minute: 30,
second: 45
});
// إنشاء من سلاسل ISO
const dateFromString = Temporal.PlainDate.from("2023-08-24");
const timeFromString = Temporal.PlainTime.from("14:30:45");
const dateTimeFromString = Temporal.PlainDateTime.from("2023-08-24T14:30:45");
العمل مع المناطق الزمنية
تجعل واجهة برمجة التطبيقات الزمنية العمل مع المناطق الزمنية أسهل بكثير:
// الوقت الحالي في المنطقة الزمنية المحلية
const localTime = Temporal.Now.zonedDateTimeISO();
console.log(localTime.toString());
// مثل، 2023-08-24T14:30:45+01:00[أوروبا/لندن]
// الوقت الحالي في منطقة زمنية محددة
const tokyoTime = Temporal.Now.zonedDateTimeISO("آسيا/طوكيو");
console.log(tokyoTime.toString());
// مثل، 2023-08-24T22:30:45+09:00[آسيا/طوكيو]
// التحويل بين المناطق الزمنية
const nyTime = localTime.withTimeZone("أمريكا/نيو_يورك");
console.log(nyTime.toString());
// مثل، 2023-08-24T09:30:45-04:00[أمريكا/نيو_يورك]
العمليات الحسابية للتاريخ والوقت
تعد واحدة من أقوى ميزات واجهة برمجة التطبيقات الزمنية هي عملياتها الحسابية البديهية:
// إضافة الوقت
const tomorrow = today.add({ days: 1 });
const nextWeek = today.add({ days: 7 });
const twoHoursLater = currentTime.add({ hours: 2 });
// طرح الوقت
const yesterday = today.subtract({ days: 1 });
const lastWeek = today.subtract({ days: 7 });
const twoHoursEarlier = currentTime.subtract({ hours: 2 });
// العمل مع الفترات
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const laterTime = currentTime.add(duration);
// إيجاد الفرق بين تاريخين
const date1 = Temporal.PlainDate.from("2023-01-01");
const date2 = Temporal.PlainDate.from("2023-08-24");
const difference = date1.until(date2);
console.log(difference.toString()); // P236D (تنسيق فترة ISO 8601)
console.log(difference.days); // 236
تعديل المكونات باستخدام "with"
توفر واجهة برمجة التطبيقات الزمنية طريقة نظيفة لإنشاء كائنات جديدة بمكونات معدلة:
// تغيير سنة التاريخ
const nextYear = date.with({ year: date.year + 1 });
// إعداد مكونات محددة
const newDateTime = dateTime.with({ hour: 12, minute: 0, second: 0 });
console.log(newDateTime.toString()); // 2023-08-24T12:00:00
مقارنة الكائنات الزمنية
توفر الواجهة أساليب مقارنة بديهية:
const date1 = Temporal.PlainDate.from("2023-08-24");
const date2 = Temporal.PlainDate.from("2023-09-15");
console.log(date1.equals(date2)); // خطأ
console.log(date1.equals(date1)); // صحيح
console.log(date1.before(date2)); // صحيح
console.log(date1.after(date2)); // خطأ
console.log(date1.since(date2).days); // -22
التعامل مع التوقيت الصيفي والأوقات الغامضة
تتعامل واجهة برمجة التطبيقات الزمنية بأناقة مع تعقيدات انتقالات التوقيت الصيفي:
// إنشاء وقت يقع أثناء انتقال التوقيت الصيفي
const dstTime = Temporal.ZonedDateTime.from({
timeZone: "أمريكا/نيو_يورك",
year: 2023,
month: 11,
day: 5,
hour: 1,
minute: 30
});
// تتيح لك الواجهة تحديد كيفية التعامل مع الأوقات الغامضة
const dstTimeExact = Temporal.ZonedDateTime.from({
timeZone: "أمريكا/نيو_يورك",
year: 2023,
month: 11,
day: 5,
hour: 1,
minute: 30,
disambiguation: "earlier" // الخيارات: 'earlier', 'later', 'compatible', 'reject'
});
الدعم للتقاويم غير الغريغورية
على عكس كائن Date
، تدعم واجهة برمجة التطبيقات الزمنية أنظمة تقويم متعددة:
// إنشاء تاريخ في التقويم العبري
const hebrewDate = Temporal.PlainDate.from({
year: 5783,
month: 5,
day: 15,
calendar: "hebrew"
});
// التحويل بين أنظمة التقويم
const gregorianDate = hebrewDate.withCalendar("iso8601");
التحليل والتنسيق
توفر واجهة برمجة التطبيقات الزمنية طرقًا مدمجة للتحليل والتنسيق:
// التحليل من السلاسل
const date = Temporal.PlainDate.from("2023-08-24");
// التنسيق المخصص
const options = {
year: 'numeric',
month: 'long',
day: 'numeric'
};
console.log(date.toLocaleString("en-US", options)); // 24 أغسطس 2023
الحالة الراهنة ودعم المتصفحات
حتى وقت كتابة هذا، تعتبر واجهة برمجة التطبيقات الزمنية في المرحلة 3 من عملية اقتراح TC39، مما يعني أنها قريبة من أن تكون مكتملة ولكن ليست بعد جزءًا من معيار ECMAScript الرسمي. في حين أن دعم المتصفح الأصلي لا يزال معلقًا، يمكن للمطورين استخدام البرمجيات المؤقتة مثل @js-temporal/polyfill
لبدء استخدام هذه الواجهة اليوم:
// تثبيت البرمجية المؤقتة
// npm install @js-temporal/polyfill
// الاستخدام في كودك
import { Temporal } from "@js-temporal/polyfill";
const now = Temporal.Now.plainDateTimeISO();
الخاتمة
تمثل واجهة برمجة التطبيقات الزمنية تحسينًا كبيرًا في قدرات JavaScript على التعامل مع التواريخ والأوقات. من خلال معالجة القضايا المستمرة مع كائن Date
وتوفير واجهة شاملة وبديهية، تعد بmaking العمل مع المفاهيم الزمنية في JavaScript أكثر متعة وأقل عرضة للأخطاء.
تشمل الفوائد الرئيسية لواجهة برمجة التطبيقات الزمنية:
- عدم القابلية للتغيير: تعيد جميع العمليات كائنات جديدة، مما يمنع الآثار الجانبية
- الوضوح: تمييز واضح بين الأنواع المختلفة من التواريخ والأوقات
- شامل: يغطي كل شيء من التواريخ البسيطة إلى العمليات المعقدة المدركة للمنطقة الزمنية
- بديهي: تجعل الطرق مثل
add()
وsubtract()
وwith()
العمليات الشائعة بسيطة - دقيق: يدعم دقة النانو ثانية
- عالمي: دعم لمناطق زمنية وأنظمة تقويم متعددة
في حين ننتظر أن تقوم المتصفحات بتنفيذ هذه الواجهة بشكل أصلي، تتيح البرمجية المؤقتة للمطورين البدء في الاستفادة من هذه التحسينات اليوم. مع استمرار تطبيقات الويب في أن تصبح أكثر عالمية وحساسية للوقت، ستصبح واجهة برمجة التطبيقات الزمنية بلا شك أداة أساسية في مجموعة أدوات كل مطور JavaScript، مما يؤدي أخيرًا إلى إنهاء الحاجة إلى المكتبات الخارجية للعمليات الأساسية المتعلقة بالتاريخ والوقت.
من خلال التعامل مع واجهة برمجة التطبيقات الزمنية، يمكن للمطورين كتابة كود أكثر نظافة وسهولة في الصيانة يتعامل بشكل صحيح مع تعقيدات التواريخ والأوقات والمناطق الزمنية، مما يؤدي إلى تجارب مستخدم أفضل عبر العالم.