รูปแบบวันที่ใน JavaScript
JavaScript Date object รองรับการสร้างและแปลงรูปแบบวันที่หลายแบบ ตั้งแต่ ISO 8601, RFC 2822, Unix Timestamp จนถึง Locale-specific formats
ตัวอย่างโค้ดครบถ้วน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript Date Formats</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; max-width: 900px; margin: 0 auto; }
.panel { background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
.code { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 4px; font-family: monospace; overflow-x: auto; }
.output { background: #e8f5e9; padding: 15px; border-radius: 4px; font-family: monospace; white-space: pre-wrap; }
button { padding: 10px 20px; background: #7e32d4; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; margin-bottom: 10px; }
button:hover { background: #6a1b9a; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 14px; }
th, td { padding: 8px; border: 1px solid #ddd; text-align: left; }
th { background: #7e32d4; color: white; }
.format-row { display: grid; grid-template-columns: 200px 1fr; gap: 10px; padding: 8px; background: white; margin: 5px 0; border-radius: 4px; }
.format-label { font-weight: bold; color: #555; font-family: monospace; font-size: 13px; }
.format-value { font-family: monospace; color: #333; word-break: break-all; }
</style>
</head>
<body>
<h1>JavaScript Date Formats & Parsing</h1>
<div class="panel">
<h3>Parsing Date Strings (Constructor)</h3>
<button onclick="demoParsing()">ทดสอบ Parsing รูปแบบต่างๆ</button>
<button onclick="demoFormatting()">ทดสอบ Formatting Methods</button>
<button onclick="demoLocale()">Locale Formats (toLocaleString)</button>
<button onclick="demoISO()">ISO 8601 Variants</button>
</div>
<div class="panel">
<h3>ผลลัพธ์</h3>
<div class="output" id="output"></div>
</div>
<script>
const output = document.getElementById('output');
function log(msg) {
output.textContent += msg + '\n';
}
function clear() { output.textContent = ''; }
function demoParsing() {
clear();
log('=== Date Constructor Parsing ===\n');
const testCases = [
// ISO 8601 (แนะนำ - มาตรฐานสากล)
'2024-01-15', // Date only
'2024-01-15T10:30:00', // Local time
'2024-01-15T10:30:00Z', // UTC (Zulu)
'2024-01-15T10:30:00+07:00', // With timezone offset
'2024-01', // Year-Month
'2024', // Year only
// RFC 2822 / Legacy
'Jan 15, 2024',
'Mon, 15 Jan 2024 10:30:00 GMT',
'01/15/2024', // US format (ambiguous!)
'15.01.2024', // European format
// Timestamps
1705312200000, // Milliseconds since epoch
'1705312200000', // String timestamp
// Invalid
'not a date',
'2024-13-45' // Invalid date
];
testCases.forEach(input => {
const date = new Date(input);
const valid = !isNaN(date.getTime());
log(`Input: ${JSON.stringify(input)}`);
log(` → ${valid ? date.toISOString() : 'Invalid Date'}`);
log(` → Local: ${valid ? date.toString() : 'N/A'}`);
log('');
});
}
function demoFormatting() {
clear();
const date = new Date('2024-01-15T10:30:45.123Z');
log('=== Date Formatting Methods ===\n');
log(`Original (ISO): ${date.toISOString()}\n`);
log('--- Built-in Methods ---');
log(`toString(): ${date.toString()}`);
log(`toISOString(): ${date.toISOString()}`);
log(`toUTCString(): ${date.toUTCString()}`);
log(`toLocaleString(): ${date.toLocaleString()}`);
log(`toLocaleDateString(): ${date.toLocaleDateString()}`);
log(`toLocaleTimeString(): ${date.toLocaleTimeString()}`);
log(`toDateString(): ${date.toDateString()}`);
log(`toTimeString(): ${date.toTimeString()}`);
log(`valueOf()/getTime(): ${date.valueOf()} ms`);
log('\n--- Custom Formatting (Manual) ---');
const pad = (n) => n.toString().padStart(2, '0');
log(`YYYY-MM-DD: ${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`);
log(`HH:mm:ss: ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`);
log(`YYYYMMDD_HHmmss: ${date.getFullYear()}${pad(date.getMonth()+1)}${pad(date.getDate())}_${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`);
}
function demoLocale() {
clear();
const date = new Date('2024-01-15T10:30:45.123Z');
log('=== toLocaleString() with Locales ===\n');
const locales = [
['th-TH', 'Thai (Thailand)'],
['en-US', 'English (US)'],
['en-GB', 'English (UK)'],
['ja-JP', 'Japanese'],
['zh-CN', 'Chinese (Simplified)'],
['ar-SA', 'Arabic (Saudi Arabia)'],
['de-DE', 'German'],
['fr-FR', 'French'],
['ru-RU', 'Russian'],
];
const options = {
dateStyle: 'full',
timeStyle: 'long'
};
locales.forEach(([locale, name]) => {
try {
const formatted = date.toLocaleString(locale, options);
log(`${name} (${locale}): ${formatted}`);
} catch (e) {
log(`${name} (${locale}): Error - ${e.message}`);
}
});
log('\n--- Custom Options ---');
const customOpts = [
{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },
{ hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false },
{ year: '2-digit', month: '2-digit', day: '2-digit' },
{ era: 'long', year: 'numeric', month: 'long', day: 'numeric' }
];
customOpts.forEach((opt, i) => {
log(`Option ${i+1}: ${date.toLocaleString('th-TH', opt)}`);
});
}
function demoISO() {
clear();
log('=== ISO 8601 Variants ===\n');
const variants = [
'2024-01-15',
'2024-01-15T10:30',
'2024-01-15T10:30:45',
'2024-01-15T10:30:45.123',
'2024-01-15T10:30:45Z',
'2024-01-15T10:30:45+07:00',
'2024-01-15T10:30:45-05:00',
'2024-W03', // Week date
'2024-W03-1', // Week date with day
'2024-015', // Ordinal date
];
variants.forEach(iso => {
const date = new Date(iso);
const valid = !isNaN(date.getTime());
log(`${iso.padEnd(30)} → ${valid ? date.toISOString() : 'Invalid'}`);
});
}
demoParsing();
</script>
</body>
</html>
รูปแบบวันที่ที่รองรับ (Parsing)
| Format | ตัวอย่าง | หมายเหตุ |
| ISO 8601 Date Only | 2024-01-15 | แนะนำมากที่สุด - Unambiguous |
| ISO 8601 DateTime Local | 2024-01-15T10:30:45 | Local time (no timezone) |
| ISO 8601 UTC | 2024-01-15T10:30:45Z | Z = Zulu/UTC time |
| ISO 8601 With Offset | 2024-01-15T10:30:45+07:00 | Timezone offset |
| ISO Week Date | 2024-W03, 2024-W03-1 | Year-Week(-Day) |
| ISO Ordinal Date | 2024-015 | Year-DayOfYear |
| RFC 2822 | Mon, 15 Jan 2024 10:30:00 GMT | Email/HTTP headers |
| US Format | 01/15/2024 | ⚠️ Ambiguous (MM/DD vs DD/MM) |
| Unix Timestamp (ms) | 1705312200000 | Milliseconds since epoch |
| Unix Timestamp (s) | 1705312200 | ⚠️ JS ใช้ ms ต้อง ×1000 |
Formatting Methods เปรียบเทียบ
| Method | Output Example | ใช้เมื่อไหร่ |
toISOString() | 2024-01-15T10:30:45.123Z | API, Database, Storage (UTC, standardized) |
toLocaleString() | 15/1/2567, 10:30:45 (th-TH) | แสดงให้ผู้ใช้ (User-facing) |
toLocaleDateString() | 15 มกราคม 2567 | เฉพาะวันที่ |
toLocaleTimeString() | 10:30:45 | เฉพาะเวลา |
toString() | Mon Jan 15 2024 17:30:45 GMT+0700 | Debug/Log (US format) |
toUTCString() | Mon, 15 Jan 2024 03:30:45 GMT | HTTP headers, Cookies |
Modern: Intl.DateTimeFormat (แนะนำสำหรับ Production)
const date = new Date('2024-01-15T10:30:45.123Z');
// Reusable formatter (performant)
const thaiFormatter = new Intl.DateTimeFormat('th-TH', {
dateStyle: 'full',
timeStyle: 'short'
});
const usFormatter = new Intl.DateTimeFormat('en-US', {
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
hour: '2-digit', minute: '2-digit', hour12: true
});
console.log(thaiFormatter.format(date)); // "วันจันทร์ที่ 15 มกราคม 2567 เวลา 17:30 น."
console.log(usFormatter.format(date)); // "Monday, January 15, 2024 at 10:30 AM"
// Format parts (สำหรับ custom layout)
const parts = thaiFormatter.formatToParts(date);
console.log(parts); // [{type: 'weekday', value: 'วันจันทร์'}, {type: 'literal', value: 'ที่ '}, ...]
Best Practices
- เก็บ/ส่งข้อมูล: ใช้ ISO 8601 UTC (
toISOString())
- แสดงให้ผู้ใช้: ใช้
toLocaleString() หรือ Intl.DateTimeFormat
- Parse input: รับ ISO 8601 เท่านั้น หลีกเลี่ยง ambiguous formats
- Timezone: เก็บ UTC, แปลงที่ Client ตาม timezone ผู้ใช้
- Libraries: พิจารณา date-fns, Luxon, Temporal API (ES2024+) สำหรับงานซับซ้อน