Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

JavaScript Date Formats - รูปแบบวันที่ต่างๆ


รูปแบบวันที่ใน 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 Only2024-01-15แนะนำมากที่สุด - Unambiguous
ISO 8601 DateTime Local2024-01-15T10:30:45Local time (no timezone)
ISO 8601 UTC2024-01-15T10:30:45ZZ = Zulu/UTC time
ISO 8601 With Offset2024-01-15T10:30:45+07:00Timezone offset
ISO Week Date2024-W03, 2024-W03-1Year-Week(-Day)
ISO Ordinal Date2024-015Year-DayOfYear
RFC 2822Mon, 15 Jan 2024 10:30:00 GMTEmail/HTTP headers
US Format01/15/2024⚠️ Ambiguous (MM/DD vs DD/MM)
Unix Timestamp (ms)1705312200000Milliseconds since epoch
Unix Timestamp (s)1705312200⚠️ JS ใช้ ms ต้อง ×1000

Formatting Methods เปรียบเทียบ

MethodOutput Exampleใช้เมื่อไหร่
toISOString()2024-01-15T10:30:45.123ZAPI, 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+0700Debug/Log (US format)
toUTCString()Mon, 15 Jan 2024 03:30:45 GMTHTTP 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+) สำหรับงานซับซ้อน