JavaScript
Date
Creating & Parsing Date
เรียนรู้วิธีสร้าง Date ทั้ง 4 แบบ — `new Date()`, `new Date(timestamp)`, `new Date(string)`, `new Date(year, month, day)` — พร้อม static methods `Date.now()` และ `Date.parse()`
`Date` คืออะไร — built-in class สำหรับวันเวลา
`Date` เป็น built-in class ใน JavaScript สำหรับจัดการวันเวลา ทุก instance ของ `Date` เก็บค่าภายในเป็น **timestamp** — คือจำนวนมิลลิวินาทีนับจาก `1 มกราคม 1970 00:00:00 UTC` (เรียกว่า **Unix epoch**) ถึงเวลาที่ระบุ เราสร้าง `Date` instance ได้ 4 วิธี: 1. `new Date()` — เวลาปัจจุบัน 2. `new Date(timestamp)` — จาก timestamp 3. `new Date(dateString)` — จาก string 4. `new Date(year, monthIndex, day, ...)` — จาก component แต่ละตัว Timestamp คือหัวใจของ `Date` — ค่าที่เก็บจริง ๆ คือ number ตัวเดียว เราใช้ getter/setter เพื่ออ่านและเปลี่ยน component เช่น ปี เดือน วัน
// 1. เวลาปัจจุบัน
const now = new Date();
console.log(now.getTime()); // ตัวเลขมิลลิวินาทีมาก ๆ
// 2. จาก timestamp — 0 = epoch
const epoch = new Date(0);
console.log(epoch.getTime()); // 0
// 3. จาก date string (ISO format)
const fromStr = new Date("2025-01-15");
console.log(fromStr.getTime()); // 1736899200000
// 4. จาก components — month เริ่มที่ 0!
const fromParts = new Date(2025, 0, 15, 10, 30, 0);
console.log(fromParts.getTime()); // มีค่าต่างจาก fromStr เพราะ timezone- `Date` เก็บเวลาเป็น **timestamp** — จำนวน ms นับจาก 1 ม.ค. 1970 UTC
- สร้างได้ 4 วิธี: ไม่ระบุ, จาก timestamp, จาก string, จาก components
- ใช้ `.getTime()` ดู timestamp ภายในได้ตลอดเวลา
- ทุก instance ของ `Date` คือหนึ่งจุดในเวลา — ไม่ใช่ช่วงเวลา
`new Date()` — สร้าง Date ของเวลาปัจจุบัน
เมื่อเรียก `new Date()` โดยไม่ส่ง argument — JavaScript สร้าง Date ของ **เวลาปัจจุบัน** ตาม local timezone ของเครื่อง ใช้เมื่อต้องการ: - ดึงปี เดือน วันปัจจุบัน - วัดเวลาที่ผ่านไป (จับเวลา) - สร้าง timestamp ของ "ตอนนี้" `.toString()` แสดงวันที่แบบอ่านได้ ส่วน `.getTime()` แสดง timestamp เป็นตัวเลข
const now = new Date();
// แสดงแบบอ่านได้
console.log(now.toString());
// "Mon May 12 2025 14:30:00 GMT+0700 (Indochina Time)"
// ดู timestamp
console.log(now.getTime()); // 1747038600000 (ตัวอย่าง)
// ดึง component ของวันที่
console.log(now.getFullYear()); // 2025
console.log(now.getMonth()); // 4 (พฤษภาคม = index 4)
console.log(now.getDate()); // 12- `new Date()` ไม่มี argument — ได้ Date ของเวลาปัจจุบัน
- ใช้ `.getTime()` ดู timestamp หรือ `.toString()` ดูแบบอ่านได้
- เทียบได้กับ `Date.now()` — แต่ `Date.now()` คืน number ตรง ๆ ไม่ต้องสร้าง instance
`new Date(timestamp)` — สร้าง Date จาก timestamp
ส่ง timestamp (จำนวนมิลลิวินาทีนับจาก epoch) เข้าไป → ได้ Date ที่ตรงกับเวลานั้น **0 = epoch** — `new Date(0)` คือ 1 มกราคม 1970 เที่ยงคืน UTC Use case: - รับค่าจาก API หรือ database ที่เก็บเป็น timestamp - แปลง timestamp กลับเป็น Date เพื่ออ่าน component - ทดสอบด้วยค่าที่รู้ล่วงหน้า เช่น `new Date(0)`
// timestamp 0 = epoch (1 ม.ค. 1970 UTC)
const epoch = new Date(0);
console.log(epoch.toISOString()); // "1970-01-01T00:00:00.000Z"
// timestamp ที่รู้ค่า
const d = new Date(1736899200000);
console.log(d.toISOString()); // "2025-01-15T00:00:00.000Z"
// แปลงกลับ — Date → timestamp
console.log(epoch.getTime()); // 0
console.log(d.getTime()); // 1736899200000- timestamp เป็น `number` — จำนวนมิลลิวินาทีจาก epoch
- `new Date(0)` = 1 ม.ค. 1970 เที่ยงคืน UTC — ใช้ทดสอบได้
- รับ timestamp จาก API/database แล้วสร้าง Date เพื่ออ่าน component ต่อ
- ใช้ `.getTime()` แปลงกลับจาก Date เป็น timestamp
`new Date(dateString)` — สร้าง Date จาก string
ส่ง string เข้าไป → JavaScript จะ parse แล้วสร้าง Date **ใช้ format `"YYYY-MM-DD"` (ISO 8601) เท่านั้น** — เป็น format เดียวที่ทุก browser parse เหมือนกัน Format ที่ใช้ได้: - `"2025-01-15"` — date only - `"2025-01-15T10:30:00"` — date + time - `"2025-01-15T10:30:00.000Z"` — date + time + timezone (Z = UTC) **สิ่งสำคัญ:** string format แบบ `"YYYY-MM-DD"` จะถูก parse เป็น **UTC** (เที่ยงคืนตามเวลาสากล) ต่างจาก components ที่สร้างใน **local timezone**
// ✅ ISO format — ทุก browser parse เหมือนกัน
const d1 = new Date("2025-01-15");
console.log(d1.toISOString()); // "2025-01-15T00:00:00.000Z"
const d2 = new Date("2025-01-15T10:30:00");
console.log(d2.toISOString()); // มีเวลาด้วย
const d3 = new Date("2025-01-15T10:30:00.000Z");
console.log(d3.toISOString()); // "2025-01-15T10:30:00.000Z"
// ❌ format อื่น — อาจ parse ต่างกันในแต่ละ browser
// new Date("01-15-2025") // MM-DD-YYYY — ไม่น่าเชื่อถือ
// new Date("Jan 15 2025") // บาง browser ไม่รู้จัก
// เทียบ: string vs components
const fromStr = new Date("2025-01-15");
const fromParts = new Date(2025, 0, 15);
console.log(fromStr.getTime() === fromParts.getTime()); // false!
// เพราะ string → UTC, components → local timezoneระวัง timezone ตอนใช้ string
`new Date("2025-01-15")` parse เป็น UTC เที่ยงคืน — แต่ `new Date(2025, 0, 15)` สร้างใน local timezone เที่ยงคืน — timestamp อาจต่างกันหลายชั่วโมงขึ้นกับ timezone ของเครื่อง
- ใช้ format `"YYYY-MM-DD"` (ISO 8601) เท่านั้น — ปลอดภัยทุก browser
- string `"YYYY-MM-DD"` ถูก parse เป็น **UTC** — ต่างจาก components ที่สร้างใน **local timezone**
- ใช้เมื่อรับค่าจาก API, form input, หรือ configuration
- ถ้า format ไม่ตรง ISO → Date จะเป็น Invalid Date
`new Date(year, month, day, ...)` — สร้างจาก components
ระบุแต่ละส่วนของวันที่เป็น number — โดยเฉพาะเมื่อผู้ใช้กรอก year, month, day แต่ละช่องแยกกัน **สิ่งสำคัญที่สุด: month เริ่มที่ 0** - มกราคม = 0, กุมภาพันธ์ = 1, ..., ธันวาคม = 11 - ถ้าผู้ใช้เลือกเดือน 12 = ธันวาคม ต้องส่ง `11` เข้า constructor Parameter หลัง `day` เป็น optional — ไม่ระบุจะเป็น 0: - `hours` (default = 0) - `minutes` (default = 0) - `seconds` (default = 0) - `milliseconds` (default = 0)
// 15 มกราคม 2025 — month 0 = ม.ค.
const d1 = new Date(2025, 0, 15);
console.log(d1.getFullYear()); // 2025
console.log(d1.getMonth()); // 0 (มกราคม)
console.log(d1.getDate()); // 15
// 25 ธันวาคม 2025 เวลา 14:30:00 — month 11 = ธ.ค.
const d2 = new Date(2025, 11, 25, 14, 30, 0);
console.log(d2.getMonth()); // 11 (ธันวาคม)
// ❌ ผิด: นึกว่า 1 = ม.ค.
const wrong = new Date(2025, 1, 15);
console.log(wrong.getMonth()); // 1 = กุมภาพันธ์! ไม่ใช่ มกราคม| parameter | type | ตัวอย่าง | จำเป็น? |
|---|---|---|---|
| `year` | number | `2025` | ใช่ |
| `monthIndex` | number (0–11) | `0` = ม.ค., `11` = ธ.ค. | ใช่ |
| `day` | number (1–31) | `15` | ไม่จำเป็น (default = 1) |
| `hours` | number (0–23) | `10` | ไม่จำเป็น (default = 0) |
| `minutes` | number (0–59) | `30` | ไม่จำเป็น (default = 0) |
| `seconds` | number (0–59) | `0` | ไม่จำเป็น (default = 0) |
| `milliseconds` | number (0–999) | `500` | ไม่จำเป็น (default = 0) |
- **month เริ่มที่ 0** — มกราคม = 0, ธันวาคม = 11 — ต่างจากที่คนทั่วไปคิด
- ถ้าผู้ใช้เลือกเดือน 1–12 → ต้อง `- 1` ก่อนส่งเข้า constructor
- parameter หลัง day เป็น optional — ไม่ส่งจะเป็น 0
- สร้างใน **local timezone** — ต่างจาก `new Date(string)` ที่ parse เป็น UTC
`Date.now()` และ `Date.parse()` — static methods
`Date` มี static methods 2 ตัวที่คืนค่าเป็น timestamp โดยไม่ต้องสร้าง instance: **`Date.now()`** — คืน timestamp ของเวลาปัจจุบัน (ms since epoch) - ใช้แทน `new Date().getTime()` ได้เลย — เร็วกว่าเพราะไม่ต้องสร้าง object - Use case: วัด elapsed time, สร้าง unique ID **`Date.parse(str)`** — รับ date string แล้วคืน timestamp (ms since epoch) - เทียบเท่า `new Date(str).getTime()` แต่ไม่ต้องสร้าง instance - ถ้า string parse ไม่ได้ → คืน `NaN` - Use case: แปลง date string เป็น timestamp โดยตรง
// === Date.now() — timestamp ปัจจุบัน ===
const now = Date.now();
console.log(now); // 1747038600000 (ตัวเลข)
// เทียบกับ new Date().getTime()
console.log(new Date().getTime()); // ค่าเดียวกัน
// Use case: วัดเวลาที่ผ่านไป
const start = Date.now();
for (let i = 0; i < 1_000_000; i++) {}
const end = Date.now();
console.log("elapsed:", end - start, "ms");
// === Date.parse() — string → timestamp ===
const ts = Date.parse("2025-01-15");
console.log(ts); // 1736899200000
// เทียบกับ new Date(str).getTime()
console.log(new Date("2025-01-15").getTime()); // 1736899200000
// string ที่ parse ไม่ได้ → NaN
console.log(Date.parse("invalid")); // NaN| method | คืนค่า | ใช้เมื่อไหร่ |
|---|---|---|
| `Date.now()` | timestamp ปัจจุบัน (ms) | วัด elapsed time, ต้องการแค่ timestamp ไม่ต้องการ Date object |
| `Date.parse(str)` | timestamp จาก string (ms) | แปลง string → timestamp โดยตรง ไม่ต้องสร้าง instance |
| `new Date().getTime()` | timestamp ปัจจุบัน (ms) | เหมือน Date.now() แต่ช้ากว่าเล็กน้อย — ต้องสร้าง object |
- `Date.now()` ใช้บ่อยที่สุด — ไม่ต้อง `new Date()` เมื่อต้องการแค่ timestamp
- `Date.parse(str)` เทียบเท่า `new Date(str).getTime()` — เลือกใช้ตามความสะดวก
- ทั้งคู่คืน `number` (timestamp) — ไม่ใช่ Date object
- ถ้า string parse ไม่ได้ `Date.parse()` คืน `NaN`
Invalid Date — ตรวจสอบว่า Date valid หรือไม่
เมื่อส่งค่าที่ JavaScript parse ไม่ได้เข้าไปใน `new Date()` — จะไม่มี error ถูกโยนออกมา แต่จะได้ **Invalid Date** Invalid Date มีพฤติกรรมพิเศษ: - `.getTime()` คืน `NaN` - `.toString()` แสดง `"Invalid Date"` - ทุก getter คืน `NaN` **วิธีตรวจสอบ:** ใช้ `isNaN(d.getTime())` หรือ `Number.isNaN(d.getTime())` — ถ้าเป็น `true` แสดงว่า Date นั้น invalid
// string ที่ parse ไม่ได้
const d1 = new Date("invalid");
console.log(d1.toString()); // "Invalid Date"
console.log(d1.getTime()); // NaN
// undefined / null
const d2 = new Date(undefined);
console.log(d2.toString()); // "Invalid Date"
// ✅ ตรวจสอบด้วย isNaN()
console.log(isNaN(d1.getTime())); // true — invalid!
// ✅ ตรวจสอบด้วย Number.isNaN()
console.log(Number.isNaN(d1.getTime())); // true
// ✅ Date ที่สร้างถูกต้อง
const valid = new Date("2025-01-15");
console.log(isNaN(valid.getTime())); // false — valid!Invalid Date ไม่ throw error
`new Date("invalid")` ไม่โยน error — มันคืน Date object ที่มีค่าเป็น Invalid Date แทน ต้องตรวจสอบด้วย `isNaN()` เอง
- `new Date("invalid")` ไม่ throw — คืน Invalid Date แทน
- ตรวจสอบด้วย `isNaN(d.getTime())` — `true` = invalid
- เกิดได้จาก string ผิด format, `undefined`, หรือค่าที่ parse ไม่ได้
- ควรตรวจสอบทุกครั้งที่รับ date string จากผู้ใช้หรือ API
ข้อควรระวังตอนสร้างและ parse Date
เรื่องที่ผิดบ่อยที่สุดเมื่อสร้าง Date: **1. Month 0-indexed** — `new Date(2025, 1, 1)` คือ 1 กุมภาพันธ์ ไม่ใช่ 1 มกราคม **2. Timezone แตกต่าง** — `new Date("2025-01-15")` parse เป็น UTC แต่ `new Date(2025, 0, 15)` สร้างใน local timezone → timestamp ต่างกัน **3. String format ไม่ปลอดภัย** — format อื่นนอกจาก ISO 8601 อาจ parse ต่างกันในแต่ละ browser **4. Invalid Date ไม่ throw** — ต้องตรวจสอบเองด้วย `isNaN()` **5. `.getYear()` ห้ามใช้** — เป็น method เก่าที่คืนปีลบ 1900 (เช่น `125` แทน `2025`) — ใช้ `.getFullYear()` เท่านั้น
// === 1. Month 0-indexed ===
const jan = new Date(2025, 0, 1); // ✅ 1 ม.ค.
const wrong = new Date(2025, 1, 1); // ❌ นึกว่า ม.ค. — แต่คือ 1 ก.พ.!
// === 2. Timezone: string vs components ===
const fromStr = new Date("2025-01-15"); // UTC
const fromParts = new Date(2025, 0, 15); // local
// timestamp ต่างกันถ้า timezone ไม่ใช่ UTC
// === 3. String format ===
const iso = new Date("2025-01-15"); // ✅ ISO — ปลอดภัย
// new Date("01-15-2025") // ❌ อาจ parse ไม่ได้
// === 4. Invalid Date ===
const d = new Date("invalid");
console.log(isNaN(d.getTime())); // true — ต้องตรวจเอง
// === 5. getYear() ห้ามใช้ ===
console.log(new Date(2025, 0, 1).getYear()); // 125 ❌
console.log(new Date(2025, 0, 1).getFullYear()); // 2025 ✅| ข้อผิดพลาด | สิ่งที่เกิดขึ้น | วิธีที่ถูก |
|---|---|---|
| `new Date(2025, 1, 1)` เพื่อเอา 1 ม.ค. | ได้ 1 ก.พ. — เดือน 1 = กุมภาพันธ์ | `new Date(2025, 0, 1)` — ใช้ 0 สำหรับมกราคม |
| ใช้ `.getYear()` | ได้ค่าแปลก ๆ (ปี - 1900) | ใช้ `.getFullYear()` เท่านั้น |
| `new Date("DD-MM-YYYY")` | บาง browser parse ไม่ได้ → Invalid Date | ใช้ `"YYYY-MM-DD"` หรือ `new Date(y, m, d)` |
| สร้างจาก string แล้วคิดว่าเป็น local | string ISO parse เป็น UTC | ใช้ components ถ้าต้องการ local timezone |
- month 0-indexed เป็นกับดักอันดับ 1 — จำให้ขึ้นใจ: มกราคม = 0, ธันวาคม = 11
- `.getFullYear()` เท่านั้น — ห้ามใช้ `.getYear()` ที่เลิกใช้แล้ว
- สร้าง Date จาก string — ใช้ `"YYYY-MM-DD"` (ISO 8601) เท่านั้น
- ระวัง timezone: string → UTC, components → local
- ตรวจสอบ Invalid Date ด้วย `isNaN(d.getTime())` เสมอเมื่อรับค่าจากภายนอก