راهنمای جامع استفاده از Temporal API جاوا اسکریپت برای محاسبات دقیق و شهودی بازههای زمانی، شامل همه چیز از ایجاد مدت زمان پایه تا محاسبات و قالببندی پیشرفته.
مدت زمان در جاوا اسکریپت تمپورال: تسلط بر محاسبات بازههای زمانی
Temporal API جاوا اسکریپت روشی مدرن و قدرتمند برای کار با تاریخ، زمان و بازههای زمانی معرفی میکند. شیء Temporal.Duration
یک طول زمانی را نشان میدهد و رویکردی واضح و شهودی برای انجام محاسبات با بازههای زمانی فراهم میکند. این مقاله به جزئیات Temporal.Duration
میپردازد و نشان میدهد چگونه میتوان مدت زمانها را برای کاربردهای مختلف ایجاد، دستکاری و قالببندی کرد.
Temporal.Duration چیست؟
Temporal.Duration
یک بازه زمانی را نشان میدهد و آن را بر حسب سال، ماه، روز، ساعت، دقیقه، ثانیه و کسری از ثانیه (میلیثانیه، میکروثانیه، نانوثانیه) بیان میکند. برخلاف اشیاء Date
که یک نقطه خاص در زمان را نشان میدهند، Temporal.Duration
یک مقدار از زمان را نشان میدهد. این شیء از فرمت مدت زمان ISO 8601 پیروی میکند (به عنوان مثال، P1Y2M10DT2H30M
نشاندهنده ۱ سال، ۲ ماه، ۱۰ روز، ۲ ساعت و ۳۰ دقیقه است). Temporal API طوری طراحی شده است که نسبت به شیء قدیمی Date
شهودیتر و کمتر مستعد خطا باشد.
ایجاد اشیاء Temporal.Duration
چندین راه برای ایجاد اشیاء Temporal.Duration
وجود دارد:
۱. از یک شیء ساده (Plain Object)
شما میتوانید با پاس دادن یک شیء با ویژگیهای مورد نظر، یک مدت زمان ایجاد کنید:
const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // خروجی: P1Y2M10DT2H30M
این کد یک مدت زمان ۱ سال، ۲ ماه، ۱۰ روز، ۲ ساعت و ۳۰ دقیقه ایجاد میکند. توجه داشته باشید که آرگومانها به ترتیب زیر هستند: years
، months
، weeks
، days
، hours
، minutes
، seconds
، milliseconds
، microseconds
، nanoseconds
.
۲. از یک رشته ISO 8601
شما همچنین میتوانید با استفاده از Temporal.Duration.from()
یک مدت زمان از روی یک رشته مدت زمان ISO 8601 ایجاد کنید:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // خروجی: P1Y2M10DT2H30M
این روش به ویژه هنگام کار با مدت زمانهایی که به صورت رشته ذخیره شدهاند یا از یک منبع خارجی دریافت شدهاند، مفید است.
۳. استفاده از متدهای add()
و subtract()
با Temporal.Instant
، Temporal.ZonedDateTime
و غیره
وقتی شما Temporal.Duration
را از دیگر انواع Temporal (مانند Temporal.Instant
یا Temporal.ZonedDateTime
) اضافه یا کم میکنید، و سپس آنها را از هم کم میکنید، یک Temporal.Duration
بازگردانده میشود که تفاوت بین دو نقطه زمانی را نشان میدهد. برای مثال:
const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // خروجی: PT5H
دسترسی به اجزای مدت زمان
شما میتوانید با استفاده از ویژگیهای یک شیء Temporal.Duration
به اجزای جداگانه آن دسترسی پیدا کنید:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years); // خروجی: 1
console.log(duration.months); // خروجی: 2
console.log(duration.days); // خروجی: 10
console.log(duration.hours); // خروجی: 2
console.log(duration.minutes); // خروجی: 30
console.log(duration.seconds); // خروجی: 0
console.log(duration.milliseconds); // خروجی: 0
console.log(duration.microseconds); // خروجی: 0
console.log(duration.nanoseconds); // خروجی: 0
انجام محاسبات با مدت زمانها
اشیاء Temporal.Duration
از جمع و تفریق با استفاده از متدهای add()
و subtract()
پشتیبانی میکنند. این متدها یک شیء Temporal.Duration
جدید را که نتیجه عملیات است، بازمیگردانند.
const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");
const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // خروجی: P1Y5M4D
const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // خروجی: P10M26D
شما همچنین میتوانید این متدها را برای محاسبات پیچیدهتر به صورت زنجیرهای استفاده کنید:
const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // خروجی: P1DT11H30M
متد negated()
یک شیء Temporal.Duration
جدید با تمام اجزای منفی شده بازمیگرداند:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // خروجی: -P1Y2M10DT2H30M
متد abs()
یک شیء Temporal.Duration
جدید با تمام اجزا به صورت مقادیر مثبت (قدر مطلق) بازمیگرداند:
const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // خروجی: P1Y2M10DT2H30M
متد with()
به شما امکان میدهد یک نمونه Temporal.Duration
جدید با برخی یا تمام ویژگیهای تغییر یافته به مقادیر جدید ایجاد کنید. اگر مقداری در شیء آرگومان مشخص نشده باشد، از مقدار اصلی مدت زمان استفاده خواهد شد. برای مثال:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // خروجی: P2Y2M5DT2H30M
نرمالسازی مدت زمانها
مدت زمانها گاهی اوقات میتوانند به شکلی غیرنرمال بیان شوند (مثلاً P1Y12M
که میتواند به P2Y
ساده شود). متد normalized()
تلاش میکند تا یک مدت زمان را به فشردهترین شکل خود ساده کند. با این حال، برای مدیریت پیچیدگیهای طولهای متفاوت ماهها، به یک تاریخ مرجع نیاز دارد. برای نرمالسازی صحیح، شما به یک نمونه Temporal.PlainDate
، Temporal.ZonedDateTime
یا Temporal.Instant
نیاز دارید.
برای مثال، نرمالسازی یک مدت زمان شامل ماهها و روزها به یک تاریخ مرجع نیاز دارد:
const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // خروجی: P2M1D
در این مثال، مدت زمان P1M32D
نسبت به اول ژانویه ۲۰۲۴ نرمالسازی شده و به P2M1D
تبدیل میشود، زیرا ژانویه ۳۱ روز دارد.
اگر فقط با اجزای زمانی (ساعت، دقیقه، ثانیه و غیره) کار میکنید، میتوانید بدون تاریخ مرجع نرمالسازی کنید:
const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //یا آرگومان relativeTo را حذف کنید
console.log(normalizedDuration.toString()); // خروجی: P1DT2H1M
مقایسه مدت زمانها
شما میتوانید با استفاده از متد compare()
مدت زمانها را مقایسه کنید. این متد بازمیگرداند:
- -1 اگر مدت زمان اول کوتاهتر از مدت زمان دوم باشد.
- 0 اگر مدت زمانها برابر باشند.
- 1 اگر مدت زمان اول طولانیتر از مدت زمان دوم باشد.
const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");
const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // خروجی: 1
مثالهای کاربردی
۱. محاسبه زمان باقیمانده تا یک رویداد
فرض کنید میخواهید زمان باقیمانده تا یک رویداد خاص را محاسبه کنید. با استفاده از Temporal.Now.zonedDateTimeISO()
برای دریافت زمان فعلی و کم کردن تاریخ رویداد. اگر تاریخ رویداد گذشته باشد، خروجی منفی خواهد بود.
const eventDate = Temporal.ZonedDateTime.from({ timeZone: 'America/Los_Angeles', year: 2024, month: 12, day: 25, hour: 9, minute: 0, second: 0 });
const now = Temporal.Now.zonedDateTimeISO('America/Los_Angeles');
const durationUntilEvent = eventDate.since(now);
console.log(durationUntilEvent.toString()); // خروجی: به عنوان مثال، P262DT14H30M (بسته به تاریخ و زمان فعلی)
۲. پیگیری مدت زمان وظایف پروژه
در مدیریت پروژه، میتوانید از Temporal.Duration
برای پیگیری مدت زمان تخمینی یا واقعی وظایف استفاده کنید.
const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // ۸ ساعت
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // ۱۶ ساعت
const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`مجموع مدت زمان تخمینی: ${totalEstimatedDuration.toString()}`); // خروجی: مجموع مدت زمان تخمینی: P1DT
۳. محاسبه سن
در حالی که محاسبه دقیق سن نیازمند در نظر گرفتن سالهای کبیسه و مناطق زمانی است، Temporal.Duration
میتواند تخمین معقولی ارائه دهد:
const birthDate = Temporal.PlainDate.from("1990-05-15");
const currentDate = Temporal.PlainDate.from("2024-01-20");
const ageDuration = currentDate.since(birthDate, { smallestUnit: 'years' });
console.log(`سن تخمینی: ${ageDuration.years} سال`); // خروجی: سن تخمینی: 33 سال
۴. نمایش مدت زمانها به صورت خوانا برای انسان
اغلب، شما نیاز دارید مدت زمانها را در یک قالب خوانا برای انسان نمایش دهید. در حالی که Temporal.Duration
توابع قالببندی داخلی ندارد، میتوانید منطق قالببندی سفارشی ایجاد کنید:
function formatDuration(duration) {
const parts = [];
if (duration.years) parts.push(`${duration.years} سال`);
if (duration.months) parts.push(`${duration.months} ماه`);
if (duration.days) parts.push(`${duration.days} روز`);
if (duration.hours) parts.push(`${duration.hours} ساعت`);
if (duration.minutes) parts.push(`${duration.minutes} دقیقه`);
if (duration.seconds) parts.push(`${duration.seconds} ثانیه`);
return parts.join('، ');
}
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // خروجی: ۱ سال، ۲ ماه، ۱۰ روز، ۲ ساعت، ۳۰ دقیقه
استفاده پیشرفته و ملاحظات
۱. مدیریت منطقه زمانی
هنگام کار با بازههای زمانی که از مرزهای مناطق زمانی یا تغییرات ساعت تابستانی عبور میکنند، استفاده از Temporal.ZonedDateTime
برای اطمینان از محاسبات دقیق بسیار مهم است. استفاده از Temporal.PlainDate
و Temporal.PlainTime
از هرگونه تبدیل منطقه زمانی جلوگیری میکند.
۲. کوچکترین واحد و گرد کردن
متدهای `since()` و `until()` اغلب گزینههایی برای تعریف کوچکترین واحد برای مدت زمان نتیجه را میپذیرند. برای مثال، محاسبه زمان *تا* یک رویداد و محدود کردن نتایج به روز.
const eventDate = Temporal.PlainDate.from("2024-12-25");
const now = Temporal.PlainDate.from("2024-01-20");
const durationUntilEvent = now.until(eventDate, { smallestUnit: 'days' });
console.log(durationUntilEvent.toString()); //خروجی نمونه PT340D
۳. ثانیههای کبیسه
Temporal به طور ذاتی ثانیههای کبیسه را در نظر نمیگیرد. اگر به دقت بسیار بالایی نیاز دارید، باید ثانیههای کبیسه را به طور جداگانه مدیریت کنید.
۴. مناطق زمانی IANA
Temporal API به پایگاه داده مناطق زمانی IANA (Internet Assigned Numbers Authority) متکی است. اطمینان حاصل کنید که محیط شما نسخه بهروزی از پایگاه داده IANA را برای مدیریت دقیق تبدیلهای منطقه زمانی دارد.
بهترین شیوهها
- از فرمت ISO 8601 برای رشتههای مدت زمان استفاده کنید: این کار سازگاری و قابلیت همکاری را تضمین میکند.
- نوع Temporal مناسب را انتخاب کنید: بسته به اینکه به پشتیبانی از منطقه زمانی نیاز دارید یا نه، از
Temporal.PlainDate
،Temporal.PlainTime
،Temporal.ZonedDateTime
یاTemporal.Instant
استفاده کنید. - در صورت لزوم مدت زمانها را نرمالسازی کنید: نرمالسازی مدت زمانها را ساده کرده و مقایسه آنها را آسانتر میکند.
- مناطق زمانی را با دقت مدیریت کنید: تبدیلهای منطقه زمانی میتوانند پیچیده باشند، بنابراین از
Temporal.ZonedDateTime
استفاده کنید و از تغییرات ساعت تابستانی آگاه باشید. - کوچکترین واحد را در نظر بگیرید: هنگام محاسبه مدت زمانها، کوچکترین واحد را برای رسیدن به سطح دقت مورد نظر مشخص کنید.
- تستهای واحد بنویسید: کد خود را به طور کامل آزمایش کنید تا اطمینان حاصل شود که محاسبات مدت زمان دقیق هستند.
اشتباهات رایج
- نادیده گرفتن مناطق زمانی: عدم توجه به مناطق زمانی میتواند منجر به محاسبات نادرست مدت زمان شود، به خصوص هنگام کار با رویدادها در مکانهای مختلف.
- استفاده از شیء قدیمی Date: شیء قدیمی
Date
به خاطر ویژگیهای عجیب و ناهماهنگیهایش شناخته شده است. برای مدیریت قابل اعتمادتر تاریخ و زمان، Temporal API را ترجیح دهید. - نرمالسازی نکردن مدت زمانها: عدم نرمالسازی مدت زمانها میتواند مقایسهها و محاسبات را پیچیدهتر کند.
- فرمت نادرست ISO 8601: استفاده از یک رشته مدت زمان ISO 8601 نامعتبر میتواند باعث خطا شود.
موارد استفاده واقعی در فرهنگهای مختلف
Temporal API میتواند به ویژه در برنامههای جهانی که تفاوتهای منطقه زمانی و ظرافتهای فرهنگی قابل توجه هستند، مفید باشد. در اینجا چند نمونه آورده شده است:
- زمانبندی رویدادهای جهانی: زمانبندی دقیق رویدادها در چندین منطقه زمانی، با در نظر گرفتن تغییرات ساعت تابستانی. به عنوان مثال، زمانبندی یک وبینار که ساعت ۹:۰۰ صبح PST شروع میشود و نمایش زمان شروع متناظر در مناطق زمانی مختلف مانند CET، JST و AEDT.
- برنامهریزی سفرهای بینالمللی: محاسبه مدت زمان سفر، شامل توقفها و تغییرات منطقه زمانی. این برای تولید برنامههای سفر و مدیریت برنامههای پرواز مفید است. به عنوان مثال، محاسبه کل زمان سفر از نیویورک به توکیو، شامل یک توقف در لندن و تنظیم برای تفاوتهای منطقه زمانی.
- تجارت الکترونیک جهانی: نمایش زمانهای تخمینی تحویل در منطقه زمانی محلی کاربر. این نیازمند در نظر گرفتن منطقه زمانی مبدأ، مدت زمان حمل و نقل و منطقه زمانی مقصد است. به عنوان مثال، کالایی که از یک انبار در آلمان به مشتری در استرالیا ارسال میشود، با زمان تحویل تخمینی ۷ روز، که در زمان محلی مشتری نمایش داده میشود.
- تراکنشهای مالی فرامرزی: محاسبه دقیق تعلق سود یا مهلت پرداخت در مناطق مختلف. این اغلب شامل در نظر گرفتن روزهای کاری و تعطیلات مختلف در هر کشور است. به عنوان مثال، محاسبه سود تعلق گرفته به یک وام در سنگاپور، با در نظر گرفتن تعطیلات رسمی سنگاپور.
- برنامههای تقویم چند فرهنگی: پشتیبانی از سیستمهای تقویم مختلف، مانند تقویم اسلامی یا عبری، و محاسبه دقیق مدت زمان رویدادها و یادآوریها بر اساس این تقویمها.
- مدیریت پروژه جهانی: پیگیری مدت زمان وظایف پروژه و مهلتها در تیمهای توزیع شده، با در نظر گرفتن برنامههای کاری و مناطق زمانی مختلف.
نتیجهگیری
Temporal.Duration
روشی قوی و شهودی برای کار با بازههای زمانی در جاوا اسکریپت فراهم میکند. با درک ویژگیها و بهترین شیوههای آن، میتوانید با اطمینان محاسبات مدت زمان دقیق و قابل اعتمادی را در برنامههای خود انجام دهید. پذیرش Temporal API منجر به کدی تمیزتر، قابل نگهداریتر و کاهش خطر خطاهای مرتبط با مدیریت تاریخ و زمان قدیمی میشود.
همانطور که عمیقتر به Temporal API میپردازید، به یاد داشته باشید که به مستندات رسمی مراجعه کرده و با سناریوهای مختلف آزمایش کنید تا به طور کامل قابلیتهای آن را درک کنید. با طراحی مدرن و ویژگیهای جامع خود، Temporal قرار است روش کار ما با تاریخها، زمانها و مدت زمانها در جاوا اسکریپت را متحول کند.