تاریخ، زمان و بین‌المللی‌سازی

Date و متدهای آن، UTC و Time Zone، ISO Date، قالب‌بندی با Intl برای تاریخ، اعداد و مرتب‌سازی زبان‌ها، Relative Time و آشنایی با Temporal.

Date — تاریخ و زمان

Date تاریخ را به‌صورت تعداد میلی‌ثانیه از ۱ ژانویه ۱۹۷۰ (Epoch) نگه می‌دارد:

// الان:
const now = new Date();
console.log(now); // تاریخ و ساعت فعلی

// با میلی‌ثانیه از Epoch:
const epoch = new Date(0);
console.log(epoch.toISOString()); // 1970-01-01T00:00:00.000Z

// با اجزا:
const d = new Date(2025, 0, 15, 10, 30);  // ماه از 0 شروع می‌شود!
console.log(d.toLocaleString("fa-IR"));   // تاریخ شمسی!

// با رشته ISO:
const iso = new Date("2025-01-15T10:30:00Z");
console.log(iso.getUTCFullYear()); // 2025
ماه‌ها از ۰ شروع می‌شوند — new Date(2025, 0, 15) یعنی ۱۵ دی / ۱۵ ژانویه!

دریافت اجزای تاریخ

const date = new Date(2025, 5, 15, 14, 30, 45);

console.log(date.getFullYear());   // 2025
console.log(date.getMonth());      // 5 — ژوئن (از 0)
console.log(date.getDate());       // 15 — روز ماه
console.log(date.getDay());        // 0 — یکشنبه (از 0)
console.log(date.getHours());      // 14
console.log(date.getMinutes());    // 30
console.log(date.getSeconds());    // 45
console.log(date.getMilliseconds()); // 0
console.log(date.getTime());       // میلی‌ثانیه از Epoch

تغییر تاریخ

const d = new Date(2025, 5, 15);

d.setFullYear(2026);
d.setMonth(11);      // دسامبر
d.setDate(25);
d.setHours(23, 59, 59);

console.log(d.toLocaleString("fa-IR"));

// جمع و تفریق تاریخ — با میلی‌ثانیه:
const tomorrow = new Date(Date.now() + 24 * 60 * 60 * 1000);
const weekLater = new Date();
weekLater.setDate(weekLater.getDate() + 7);

UTC و Time Zone

متدهای getUTC* زمان جهانی را برمی‌گردانند:

const d = new Date();

// زمان محلی در برابر UTC:
console.log(d.getHours());      // ساعت محلی
console.log(d.getUTCHours());   // ساعت جهانی

// اختلاف منطقه زمانی (دقیقه):
console.log(d.getTimezoneOffset());

// تبدیل به رشته در منطقه زمانی مشخص:
console.log(d.toLocaleString("fa-IR", { timeZone: "Asia/Tehran" }));
console.log(d.toLocaleString("en-US", { timeZone: "America/New_York" }));

ISO 8601 — استاندارد تبادل

const d = new Date();

// ISO — برای API و دیتابیس:
console.log(d.toISOString());     // 2025-01-15T10:30:45.123Z
console.log(d.toJSON());          // همان ISO

// فقط تاریخ:
console.log(d.toISOString().split("T")[0]); // 2025-01-15

// تبدیل معکوس:
const parsed = new Date("2025-01-15T10:30:00Z");
console.log(parsed.getTime() > 0); // true

قالب‌بندی با Intl.DateTimeFormat

Intl قالب‌بندی حرفه‌ای برای هر زبان:

const now = new Date();

// فارسی با تاریخ شمسی:
console.log(new Intl.DateTimeFormat("fa-IR").format(now));
// ۱۴۰۳/۱۰/۲۵

// با گزینه‌های کامل:
const full = new Intl.DateTimeFormat("fa-IR", {
    dateStyle: "full",
    timeStyle: "medium"
});
console.log(full.format(now)); // چهارشنبه ۲۵ دی ۱۴۰۳، ساعت ۱۴:۳۰:۴۵

// اعداد فارسی با ماه نامی:
console.log(new Intl.DateTimeFormat("fa-IR", {
    year: "numeric",
    month: "long",
    day: "numeric",
    weekday: "long"
}).format(now));

Intl.NumberFormat — قالب‌بندی اعداد

// ارقام فارسی:
console.log(new Intl.NumberFormat("fa-IR").format(1234567));
// ۱٬۲۳۴٬۵۶۷

// واحد پول:
console.log(new Intl.NumberFormat("fa-IR", {
    style: "currency",
    currency: "IRR"
}).format(5000000)); // ۵٬۰۰۰٬۰۰۰ ریال

// درصد:
console.log(new Intl.NumberFormat("fa-IR", {
    style: "percent"
}).format(0.85)); // ۸۵٪

// فشرده‌سازی:
console.log(new Intl.NumberFormat("en", {
    notation: "compact"
}).format(1234567)); // 1.2M

Intl.Collator — مرتب‌سازی زبان‌ها

const names = ["زهرا", "علی", "آمنه", "محمد", "ا Fatemeh"];

// مرتب‌سازی درست فارسی:
const sorted = [...names].sort(new Intl.Collator("fa").compare);
console.log(sorted);

// با اعداد داخل رشته:
const files = ["فایل2", "فایل10", "فایل1"];
console.log(files.sort(new Intl.Collator("fa", { numeric: true }).compare));
// ["فایل1", "فایل2", "فایل10"] — منطقی!

Intl.RelativeTimeFormat — زمان نسبی

const rtf = new Intl.RelativeTimeFormat("fa", { numeric: "auto" });

console.log(rtf.format(-1, "day"));    // دیروز
console.log(rtf.format(0, "day"));     // امروز
console.log(rtf.format(1, "day"));     // فردا
console.log(rtf.format(-2, "hour"));   // ۲ ساعت پیش
console.log(rtf.format(3, "minute"));  // ۳ دقیقه دیگر

// تابع کمکی:
function timeAgo(date) {
    const seconds = Math.round((date - Date.now()) / 1000);
    const rtf = new Intl.RelativeTimeFormat("fa", { numeric: "auto" });
    const units = [
        ["year",   31536000],
        ["month",   2592000],
        ["day",      86400],
        ["hour",      3600],
        ["minute",      60]
    ];
    for (const [unit, secs] of units) {
        const interval = Math.round(seconds / secs);
        if (Math.abs(interval) >= 1) return rtf.format(interval, unit);
    }
    return "همین حالا";
}

console.log(timeAgo(new Date(Date.now() - 7200000))); // ۲ ساعت پیش

DurationFormat — مدت زمان (جدید)

const df = new Intl.DurationFormat("fa", { style: "long" });
console.log(df.format({ hours: 2, minutes: 30 }));
// ۲ ساعت و ۳۰ دقیقه

Temporal — آینده تاریخ در JS

Temporal جایگزین مدرن Date است (در حال استانداردسازی) — Immutable، پشتیبانی بهتر Time Zone و تقویم:

// نمونه از API آینده (فعلاً Polyfill):
// ساخت:
// const t = Temporal.Now.plainDateTimeISO();
// const date = Temporal.PlainDate.from("2025-01-15");

// محاسبات — بدون باگ:
// const later = date.add({ days: 30 });
// const diff = date.until(later, { largestUnit: "day" });

// تقویم شمسی — پشتیبانی داخلی:
// const persian = Temporal.PlainDate.from({
//     year: 1403, month: 10, day: 25,
//     calendar: "persian"
// });
تا زمان پشتیبانی گسترده، از کتابخانه‌های date-fns یا Day.js استفاده کنید — سبک و مدرن.

جمع‌بندی

ابزارکاربرد
new Date()ساخت تاریخ
toISOString()قالب استاندارد برای API
Intl.DateTimeFormatقالب‌بندی هر زبان/تقویم
Intl.NumberFormatاعداد، پول، درصد
Intl.RelativeTimeFormat«۲ ساعت پیش»
Temporalآینده — تقویم شمسی داخلی

این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.

ابزارهای مرتبط