Category: reference
JavaScript Date & Intl API — จัดการวันที่และการแสดงผลหลายภาษา
วิธีใช้ Date object, Intl.DateTimeFormat, Intl.NumberFormat, Intl.RelativeTimeFormat และ Temporal API สำหรับจัดการวันที่ใน JavaScript โดยไม่ต้องใช้ library
สารบัญ
Date Object พื้นฐาน
const now = new Date(); // ตอนนี้
const specific = new Date('2026-06-14'); // จาก ISO string
const fromTimestamp = new Date(1749859200000); // จาก Unix timestamp (ms)
now.getFullYear(); // 2026
now.getMonth(); // 5 (0-based! มกราคม = 0)
now.getDate(); // วันที่ 1-31
now.getDay(); // 0-6 (0 = อาทิตย์)
now.getTime(); // Unix timestamp ใน ms
now.toISOString(); // "2026-06-14T00:00:00.000Z"
ข้อควรระวัง: getMonth() เริ่มจาก 0 — ต้อง +1 เสมอถ้าต้องการเดือนจริง
Intl.DateTimeFormat — แสดงวันที่หลายภาษา
const date = new Date('2026-06-14');
// ภาษาไทย
new Intl.DateTimeFormat('th-TH', {
year: 'numeric', month: 'long', day: 'numeric'
}).format(date);
// "14 มิถุนายน 2026"
// ภาษาไทย พ.ศ.
new Intl.DateTimeFormat('th-TH-u-ca-buddhist', {
year: 'numeric', month: 'short', day: 'numeric'
}).format(date);
// "14 มิ.ย. 2569"
// อังกฤษ
new Intl.DateTimeFormat('en-US', {
year: 'numeric', month: 'short', day: 'numeric'
}).format(date);
// "Jun 14, 2026"
// รูปแบบต่างๆ
new Intl.DateTimeFormat('th-TH', { dateStyle: 'full' }).format(date);
// "วันอาทิตย์ที่ 14 มิถุนายน พ.ศ. 2569"
new Intl.DateTimeFormat('th-TH', { dateStyle: 'medium', timeStyle: 'short' }).format(new Date());
// "14 มิ.ย. 2026 09:30"
Intl.RelativeTimeFormat — “2 วันที่แล้ว”
const rtf = new Intl.RelativeTimeFormat('th-TH', { numeric: 'auto' });
rtf.format(-1, 'day'); // "เมื่อวาน"
rtf.format(-2, 'day'); // "2 วันที่แล้ว"
rtf.format(1, 'day'); // "พรุ่งนี้"
rtf.format(-1, 'hour'); // "1 ชั่วโมงที่แล้ว"
rtf.format(-30, 'minute'); // "30 นาทีที่แล้ว"
// helper function
function timeAgo(date: Date): string {
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
const rtf = new Intl.RelativeTimeFormat('th-TH', { numeric: 'auto' });
if (seconds < 60) return rtf.format(-seconds, 'second');
if (seconds < 3600) return rtf.format(-Math.floor(seconds / 60), 'minute');
if (seconds < 86400) return rtf.format(-Math.floor(seconds / 3600), 'hour');
if (seconds < 604800) return rtf.format(-Math.floor(seconds / 86400), 'day');
return rtf.format(-Math.floor(seconds / 604800), 'week');
}
Intl.NumberFormat — จัดรูปแบบตัวเลข
// ตัวเลขทั่วไป
new Intl.NumberFormat('th-TH').format(1234567);
// "1,234,567"
// สกุลเงิน
new Intl.NumberFormat('th-TH', { style: 'currency', currency: 'THB' }).format(1500);
// "฿1,500.00"
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(29.99);
// "$29.99"
// เปอร์เซ็นต์
new Intl.NumberFormat('th-TH', { style: 'percent', maximumFractionDigits: 1 }).format(0.856);
// "85.6%"
// compact (ย่อ)
new Intl.NumberFormat('th-TH', { notation: 'compact' }).format(1500000);
// "1.5 ล."
Date Arithmetic
// บวก/ลบวัน
const tomorrow = new Date(Date.now() + 86400000); // +1 วัน (ms)
const nextWeek = new Date(Date.now() + 7 * 86400000);
// ระยะห่างระหว่างสองวัน
function daysBetween(a: Date, b: Date): number {
return Math.abs(Math.floor((b.getTime() - a.getTime()) / 86400000));
}
// ตรวจว่า date อยู่ในปีนี้หรือเปล่า
function isThisYear(date: Date): boolean {
return date.getFullYear() === new Date().getFullYear();
}
ใช้กับ Astro Content Collections
// formatDate utility สำหรับใช้ทั่วทั้ง site
export function formatDate(date: Date, locale = 'th-TH'): string {
return new Intl.DateTimeFormat(locale, {
year: 'numeric',
month: 'long',
day: 'numeric',
}).format(date);
}
export function formatDateShort(date: Date): string {
return new Intl.DateTimeFormat('th-TH', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).format(date);
}
---
// ใน [slug].astro
import { formatDate } from '@/utils/date';
const { date } = entry.data;
---
<time datetime={date.toISOString()}>
{formatDate(date)}
</time>
Temporal API (Future)
TC39 Proposal Stage 3 — จะมาแทน Date object ที่ design ไม่ดี:
// ยังไม่รองรับใน browser ทั่วไป (ต้องใช้ polyfill)
const today = Temporal.Now.plainDateISO();
const tomorrow = today.add({ days: 1 });
const diff = today.until(someDate).days;
// ข้อดีหลักของ Temporal:
// - ไม่ mutable (Date.setMonth() แก้ object ต้นฉบับ)
// - รองรับ timezone อย่างถูกต้อง
// - month เริ่มจาก 1 (ไม่ใช่ 0)
// - API อ่านง่ายกว่ามาก
ตอนนี้ใช้ Intl ที่มีอยู่แล้ว ไม่ต้องนำเข้า library เพิ่ม — date-fns หรือ dayjs จำเป็นน้อยลงมากเมื่อใช้ Intl ครบ