JavaScript
Built-in Classes
Date
เรียนรู้ `Date` built-in class — การสร้าง Date, getter/setter methods, การ format แสดงผล, การคำนวณหาผลต่างของวันเวลา และข้อควรระวังที่สำคัญ
`Date` คือ built-in class สำหรับวันเวลา — เก็บ timestamp ภายในเป็นมิลลิวินาที
`Date` เป็น built-in class ใน JavaScript — ใช้สำหรับจัดการวันเวลา ทุก instance ของ `Date` จะเก็บค่า **timestamp** ภายใน ซึ่งคือจำนวนมิลลิวินาทีนับจาก `1 มกราคม 1970 00:00:00 UTC` (Unix epoch) ถึงเวลาที่ระบุ การสร้าง `Date` instance ทำได้ 4 วิธีหลัก: 1. `new Date()` — สร้าง Date ของเวลาปัจจุบัน 2. `new Date(timestamp)` — สร้าง Date จาก timestamp (มิลลิวินาทีนับจาก epoch) 3. `new Date(dateString)` — สร้าง Date จาก string ในรูปแบบที่ JavaScript parse ได้ เช่น `"2025-01-15"`, `"2025-01-15T10:30:00"` 4. `new Date(year, monthIndex, day, hours, minutes, seconds, ms)` — สร้าง Date จาก component แต่ละตัว (**month เริ่มที่ 0:** มกราคม = 0, ธันวาคม = 11) **Timestamp** คือหัวใจของ Date — ค่าที่เก็บใน Date จริง ๆ คือ `timestamp` (number) กลับไปกลับมา เราใช้ getter/setter เพื่ออ่านและเปลี่ยนค่า component เช่น ปี เดือน วัน ชั่วโมง
// 1. เวลาปัจจุบัน
const now = new Date();
console.log(now); // 2025-01-15T... (เวลาตอนรัน)
// 2. จาก timestamp (0 = epoch)
const fromTimestamp = new Date(0);
console.log(fromTimestamp); // 1970-01-01T00:00:00.000Z
// 3. จาก date string
const fromString = new Date("2025-01-15");
console.log(fromString); // 2025-01-15T00:00:00.000Z
// 4. จาก components — month เริ่มที่ 0!
const fromComponents = new Date(2025, 0, 15, 10, 30, 0);
console.log(fromComponents); // 2025-01-15T03:30:00.000Z
// ทุก Date มี timestamp ภายใน
console.log(now.getTime()); // 1737000000000 (timestamp ปัจจุบัน)
console.log(fromTimestamp.getTime()); // 0- `Date` เก็บเวลาเป็น **timestamp** — จำนวนมิลลิวินาทีนับจาก 1 ม.ค. 1970 UTC
- สร้าง Date ได้ 4 วิธี: ไม่ระบุ, จาก timestamp, จาก string, จาก components
- **month เริ่มที่ 0** — มกราคม = 0, กุมภาพันธ์ = 1, …, ธันวาคม = 11
- ทุก instance ของ `Date` เก็บวันที่แบบเจาะจง ไม่ใช่ relative — แต่ละ instance คือหนึ่งจุดในเวลา
- `Date` object มี state ภายใน และ **mutable** — setter จะเปลี่ยนค่าใน instance เดิม
Getter methods — ดึงค่า year, month, day, hours, minutes ออกจาก Date
Getter methods ใช้อ่านค่าส่วนประกอบของ Date ออกมาเป็นตัวเลข — มีทั้งแบบ **local time** (ตาม timezone ของเครื่อง) และแบบ **UTC**: **Local time:** - `.getFullYear()` — ปี ค.ศ. (4 หลัก เช่น `2025`) - `.getMonth()` — เดือน **0-indexed** (0 = มกราคม, 11 = ธันวาคม) - `.getDate()` — วันที่ในเดือน (1–31) - `.getDay()` — วันในสัปดาห์ (0 = อาทิตย์, 1 = จันทร์, …, 6 = เสาร์) - `.getHours()` — ชั่วโมง (0–23) - `.getMinutes()` — นาที (0–59) - `.getSeconds()` — วินาที (0–59) - `.getMilliseconds()` — มิลลิวินาที (0–999) - `.getTime()` — **timestamp** (ms since epoch) — getter ที่สำคัญที่สุด **UTC:** ใช้ `.getUTCFullYear()`, `.getUTCMonth()`, `.getUTCDate()`, ฯลฯ — ดึงค่าตาม UTC โดยไม่สน timezone ท้องถิ่น **Use case**: แสดงส่วนประกอบของวันที่ใน UI, ตรวจสอบว่าเป็นวันไหนของสัปดาห์, คำนวณอายุจากปีเกิด
const d = new Date(2025, 0, 15, 10, 30, 45, 500);
// 15 มกราคม 2025, 10:30:45.500
// ส่วนของวันที่
console.log(d.getFullYear()); // 2025
console.log(d.getMonth()); // 0 ← มกราคม = 0!
console.log(d.getDate()); // 15
console.log(d.getDay()); // 3 ← พุธ (0=อาทิตย์ → 3=พุธ)
// ส่วนของเวลา
console.log(d.getHours()); // 10
console.log(d.getMinutes()); // 30
console.log(d.getSeconds()); // 45
console.log(d.getMilliseconds()); // 500
// timestamp — สำคัญที่สุด
console.log(d.getTime()); // 1736944245500
// UTC getters
console.log(d.getUTCHours()); // ชั่วโมงใน UTC (ต่างจาก local ตาม timezone)| getter | ค่า | ตัวอย่าง | หมายเหตุ |
|---|---|---|---|
| `.getFullYear()` | ปี ค.ศ. (4 หลัก) | `2025` | ใช้แทน `.getYear()` ที่เลิกใช้แล้ว |
| `.getMonth()` | 0–11 | `0` = มกราคม | **0-indexed** — บวก 1 ก่อนแสดงผล |
| `.getDate()` | 1–31 | `15` | วันที่ในเดือน |
| `.getDay()` | 0–6 | `0` = อาทิตย์, `6` = เสาร์ | วันในสัปดาห์ — ใช้สร้าง calendar |
| `.getHours()` | 0–23 | `10` | ตามเวลา local timezone |
| `.getTime()` | timestamp (ms) | `1736944245500` | ค่า numeric สำหรับคำนวณผลต่าง |
- `.getMonth()` คืนค่า 0–11 — ต้อง **+1** ก่อนแสดงผลให้ผู้ใช้เห็นว่าเป็นเดือนมกราคมถึงธันวาคม
- `.getDay()` คืน 0–6 (อาทิตย์–เสาร์) — ใช้สร้าง calendar UI, เช็กวันหยุด
- `.getTime()` เป็น getter สำคัญที่สุดสำหรับการคำนวณ — ใช้เปรียบเทียบหรือหาผลต่างระหว่าง 2 Date
- UTC getters มีประโยชน์เมื่อทำงานกับ backend หรือ API ที่ใช้ UTC — ป้องกัน timezone bug
Setter methods — เปลี่ยนค่า year, month, day ใน Date object
Setter methods ใช้เปลี่ยนค่าส่วนประกอบของ Date — **Date object เป็น mutable** ต่างจาก string หรือ number ที่เป็น immutable **Local time:** - `.setFullYear(year, month?, day?)` — เปลี่ยนปี (เปลี่ยนเดือนกับวันได้ด้วย) - `.setMonth(month, day?)` — เปลี่ยนเดือน (0-indexed) - `.setDate(day)` — เปลี่ยนวันที่ในเดือน - `.setHours(hours, minutes?, seconds?, ms?)` — เปลี่ยนชั่วโมง - `.setMinutes(minutes, seconds?, ms?)` — เปลี่ยนนาที - `.setSeconds(seconds, ms?)` — เปลี่ยนวินาที - `.setTime(timestamp)` — เปลี่ยน timestamp ตรง ๆ **UTC:** `.setUTCFullYear()`, `.setUTCMonth()`, `.setUTCDate()`, ฯลฯ — เหมือนกันแต่ set ใน UTC **Use case สำคัญ**: `d.setDate(d.getDate() + 7)` — เพิ่ม 7 วัน หาก `setDate` ได้ค่าที่เกินจำนวนวันในเดือน Date จะ auto-correct เช่น 31 มกราคม + 1 = 1 กุมภาพันธ์ `setMonth` มีพฤติกรรมเดียวกัน — `d.setMonth(d.getMonth() + 1)` = เดือนถัดไป (ข้ามปีให้อัตโนมัติ)
const d = new Date(2025, 0, 15); // 15 ม.ค. 2025
console.log(d); // 2025-01-15
// เปลี่ยนปี
d.setFullYear(2026);
console.log(d.getFullYear()); // 2026
// เปลี่ยนเดือน — ยังคง 0-indexed
d.setMonth(5); // มิถุนายน (index 5)
console.log(d.getMonth()); // 5
// เปลี่ยนวันที่
d.setDate(1);
console.log(d.getDate()); // 1
// === use case: เพิ่ม/ลดวัน — Date auto-correct ===
const today = new Date(2025, 0, 31); // 31 ม.ค. 2025
today.setDate(today.getDate() + 1);
console.log(today); // 1 ก.พ. 2025 ← auto-correct!
today.setDate(0); // 0 = วันสุดท้ายของเดือนก่อน
console.log(today); // 31 ม.ค. 2025
// === use case: เปลี่ยน timestamp โดยตรง ===
const ts = Date.UTC(2025, 0, 15); // timestamp ของ 15 ม.ค. 2025 UTC
d.setTime(ts);
console.log(d.toISOString()); // 2025-01-15T00:00:00.000Z- **Date เป็น mutable** — setter เปลี่ยนค่า instance เดิม ไม่คืน Date ใหม่ (ต่างจาก string method)
- ใช้ `d.setDate(d.getDate() + N)` เพิ่ม/ลดวัน — auto-correct ข้ามเดือนปีให้อัตโนมัติ
- ใช้ `d.setMonth(d.getMonth() + N)` เพิ่ม/ลดเดือน — auto-correct เช่นกัน
- `.setDate(0)` คือการตั้งวันเป็นวันสุดท้ายของเดือนก่อน — เป็น trick หาจำนวนวันในเดือน
- UTC setters ใช้เมื่อทำงานกับ timestamp ใน UTC — ป้องกัน timezone shift
แปลง Date เป็น string — `.toString()`, `.toISOString()`, `.toLocaleString()`
Date มี methods สำหรับแปลงเป็น string ในรูปแบบต่าง ๆ — เลือกใช้ตามจุดประสงค์: **`.toString()`** — แสดงวันที่แบบอ่านง่ายใน local timezone: `"Wed Jan 15 2025 10:30:00 GMT+0700 (Indochina Time)"` — เหมาะกับการ debug **`.toISOString()`** — แสดงในรูปแบบ ISO 8601 (UTC): `"2025-01-15T03:30:00.000Z"` — **ใช้ส่งค่าให้ API / database** — เป็น format มาตรฐานที่ทุก platform อ่านได้ **`.toLocaleDateString(locale, options)`** — แสดงเฉพาะวันที่ตาม locale: `"15/1/2568"` (th-TH), `"1/15/2025"` (en-US) — เหมาะกับการแสดงผลใน UI **`.toLocaleString(locale, options)`** — แสดงวันที่และเวลาตาม locale **`.toLocaleTimeString(locale, options)`** — แสดงเฉพาะเวลา Options ที่ใช้บ่อยใน `.toLocaleDateString`: - `year: "numeric"`, `month: "long"` / `"short"` / `"2-digit"`, `day: "numeric"` - `weekday: "long"` — แสดงชื่อวัน - `era: "short"` — แสดง พ.ศ. (คู่กับ locale `"th-TH"`) - `calendar: "buddhist"` — บังคับใช้ปฏิทินพุทธ (ปกติ `th-TH` จะใช้ buddhist โดย default)
const d = new Date(2025, 0, 15, 10, 30, 0);
// .toString() — สำหรับ debug
console.log(d.toString());
// "Wed Jan 15 2025 10:30:00 GMT+0700 (Indochina Time)"
// .toISOString() — สำหรับ API / database
console.log(d.toISOString());
// "2025-01-15T03:30:00.000Z" ← UTC เสมอ
// .toLocaleDateString("th-TH") — แสดงใน UI ภาษาไทย
console.log(d.toLocaleDateString("th-TH"));
// "15/1/2568" (พ.ศ. โดย default)
// .toLocaleDateString("th-TH", options) — ควบคุมรูปแบบ
console.log(
d.toLocaleDateString("th-TH", {
year: "numeric",
month: "long",
day: "numeric",
weekday: "long",
})
);
// "วันพุธที่ 15 มกราคม พ.ศ. 2568"
// .toLocaleString("th-TH") — วันที่ + เวลา
console.log(
d.toLocaleString("th-TH", {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
})
);
// "15 มกราคม 2568 เวลา 10:30 น."
// .toLocaleTimeString — เฉพาะเวลา
console.log(
d.toLocaleTimeString("th-TH", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})
);
// "10:30:00"| method | output | timezone | ใช้เมื่อไหร่ |
|---|---|---|---|
| `.toString()` | human-readable เต็ม | local | debug, log |
| `.toISOString()` | ISO 8601 (`"2025-01-15T...Z"`) | **UTC เสมอ** | ส่ง API, database, JSON |
| `.toLocaleDateString()` | วันที่ตาม locale | local | แสดงวันที่ใน UI |
| `.toLocaleString()` | วันที่ + เวลาตาม locale | local | แสดงวันเวลาใน UI |
| `.toLocaleTimeString()` | เวลาตาม locale | local | แสดงเวลาใน UI |
- `.toISOString()` **คืนค่าเป็น UTC เสมอ** — ไม่เกี่ยวกับ timezone ของเครื่อง — เหมาะกับการสื่อสารระหว่าง server-client
- `.toLocaleDateString("th-TH")` แสดงผลเป็น **พ.ศ.** โดย default — ใช้เมื่อต้องการแสดงวันที่ให้ผู้ใช้คนไทยอ่าน
- options `{ month: "long" }` แสดงชื่อเดือนเต็มภาษาไทยเมื่อใช้ locale `"th-TH"`
- ใช้ `{ era: "short" }` ร่วมกับ `"th-TH"` เพื่อแสดง พ.ศ. ชัดเจน — มีประโยชน์เมื่อ locale อาจเปลี่ยน
คำนวณด้วย Date — หาผลต่าง, เปรียบเทียบ, `Date.now()`
การคำนวณกับ Date ใช้หลักการเดียว: **แปลง Date เป็น timestamp** (`.getTime()`) แล้วนำมาลบกัน ได้ผลต่างเป็นมิลลิวินาที — จากนั้นแปลงเป็นหน่วยที่ต้องการ **หาจำนวนวันระหว่าง 2 Date:** 1. `diffMs = date2.getTime() - date1.getTime()` 2. `diffDays = diffMs / (1000 * 60 * 60 * 24)` **เปรียบเทียบ Date** — ใช้ `<`, `>`, `===` ได้โดยตรง: - `<` / `>` — JavaScript เรียก `.valueOf()` (timestamp) เปรียบเทียบให้อัตโนมัติ - `===` — เปรียบเทียบ reference ไม่ใช่ค่า — ใช้ `d1.getTime() === d2.getTime()` แทน **`Date.now()`** — static method คืนค่า timestamp ปัจจุบัน — คือ shortcut ของ `new Date().getTime()` — ไม่ต้องสร้าง instance ใช้เมื่อต้องการแค่ timestamp **Static methods อื่น ๆ:** - `Date.parse(dateString)` — parse date string เป็น timestamp - `Date.UTC(year, month, day, ...)` — สร้าง timestamp ใน UTC จาก components (month 0-indexed เหมือนกัน)
// === หาจำนวนวันระหว่าง 2 Date ===
const start = new Date("2025-01-01");
const end = new Date("2025-01-15");
const diffMs = end.getTime() - start.getTime();
const diffDays = diffMs / (1000 * 60 * 60 * 24);
console.log(diffDays); // 14
// === เปรียบเทียบ Date ===
console.log(start < end); // true ← timestamp เปรียบเทียบได้
console.log(start > end); // false
// console.log(start === end); // false ← เปรียบเทียบ reference! ไม่ใช่ค่า
// เปรียบเทียบค่า — ต้องใช้ getTime()
console.log(start.getTime() === start.getTime()); // true
// === Date.now() — timestamp ปัจจุบัน ===
const now = Date.now();
console.log(now); // 1737000000000 (timestamp ปัจจุบัน)
// ใช้ Date.now() วัด performance
const t0 = Date.now();
for (let i = 0; i < 1_000_000; i++) {}
const t1 = Date.now();
console.log("elapsed:", t1 - t0, "ms");
// === Date.parse() vs new Date().getTime() ===
console.log(Date.parse("2025-01-15")); // 1736899200000
console.log(new Date("2025-01-15").getTime()); // 1736899200000 ← เท่ากัน
// === Date.UTC() — สร้าง timestamp ใน UTC ===
const ts = Date.UTC(2025, 0, 15);
console.log(ts); // 1736899200000
console.log(new Date(ts).toISOString()); // 2025-01-15T00:00:00.000Z| วิธี | คืนค่า | ใช้เมื่อไหร่ |
|---|---|---|
| `d.getTime()` | timestamp (ms) | หาผลต่าง, เปรียบเทียบค่า, เก็บลง database |
| `Date.now()` | timestamp ปัจจุบัน (ms) | วัด elapsed time, สร้าง unique ID, หา timestamp โดยไม่สร้าง Date |
| `Date.parse(str)` | timestamp (ms) จาก string | แปลง date string → timestamp โดยไม่ต้องสร้าง instance |
| `Date.UTC(y, m, d, ...)` | timestamp (ms) ใน UTC | สร้าง timestamp ที่ไม่ขึ้นกับ local timezone |
- `Date.now()` คือ static method ที่ใช้บ่อยที่สุด — ไม่ต้องสร้าง instance เมื่อต้องการแค่ timestamp ปัจจุบัน
- เปรียบเทียบ Date ด้วย `<`, `>` ได้เพราะ JavaScript เรียก `.valueOf()` → timestamp ให้
- `===` เปรียบเทียบ **reference** ของ object — ใช้ `.getTime()` เพื่อเปรียบเทียบค่าจริง
- สูตรแปลง ms เป็นวัน: `diffMs / (1000 * 60 * 60 * 24)` — จำง่าย: 1000ms × 60s × 60m × 24h
- `Date.UTC()` ใช้สร้าง timestamp ใน UTC — รับ parameter เดียวกับ `new Date(year, month, day, ...)`
ข้อควรระวัง — month เริ่มที่ 0, timezone ดัก, Date เป็น mutable
เรื่องที่ผิดบ่อยที่สุดในการใช้ `Date`: **1. Month 0-indexed (0–11)** `new Date(2025, 0, 1)` = 1 มกราคม 2025 — **ไม่ใช่** `new Date(2025, 1, 1)` `.getMonth()` คืน 0–11 — ต้อง **+1** ก่อนแสดงผล **2. `.getYear()` vs `.getFullYear()`** `.getYear()` เป็น method เก่า — คืนปีลบ 1900 (เช่น `125` แทน `2025`) — ห้ามใช้! ใช้ `.getFullYear()` เท่านั้น **3. Timezone gotcha** - `new Date("2025-01-15")` — parse เป็น **UTC** (`2025-01-15T00:00:00.000Z`) - `new Date(2025, 0, 15)` — สร้างใน **local timezone** - `.toISOString()` — แสดงผลใน **UTC** เสมอ การแสดงผลอาจต่างจากที่คุณตั้งค่า - `.getHours()` — คืนค่าตาม **local timezone** ของเครื่อง **4. Date เป็น mutable** `.setDate()`, `.setMonth()` เปลี่ยนค่าใน instance เดิม — ไม่เหมือน string `.replace()` ที่คืนค่าใหม่ หากต้องการวันที่เดิมไว้ใช้ต่อ — ต้องก็อปด้วย `new Date(original.getTime())` **5. Browser อาจ parse date string ต่างกัน** `new Date("01-15-2025")` (MM-DD-YYYY) — อาจ parse ไม่ได้ในบาง browser ใช้ format `"YYYY-MM-DD"` (ISO 8601) เท่านั้น หรือใช้ `new Date(year, month, day)` แทน
// === 1. Month 0-indexed ===
const jan = new Date(2025, 0, 1); // ✅ 1 ม.ค.
const wrong = new Date(2025, 1, 1); // ❌ นึกว่า ม.ค. — แต่คือ 1 ก.พ.!
console.log(jan.getMonth()); // 0
console.log(wrong.getMonth()); // 1 ← ไม่ใช่ 0!
// === 2. getYear() — ห้ามใช้ ===
console.log(new Date(2025, 0, 1).getYear()); // 125 ← ผิด!
console.log(new Date(2025, 0, 1).getFullYear()); // 2025 ← ถูก
// === 3. Timezone: string vs components ===
const fromString = new Date("2025-01-15");
const fromComponents = new Date(2025, 0, 15);
console.log(fromString.getHours()); // อาจเป็น 7 (ไทย) ← UTC ตอนเที่ยงคืน
console.log(fromComponents.getHours()); // 0 ← local timezone
// === 4. Date เป็น mutable — ต้อง copy ก่อน ===
const original = new Date(2025, 0, 15);
const copy = new Date(original.getTime()); // ✅ copy timestamp
copy.setDate(20);
console.log(original.getDate()); // 15 ← ยังเหมือนเดิม
console.log(copy.getDate()); // 20 ← เปลี่ยนเฉพาะ copy
// ถ้าไม่ copy:
const ref = original; // ❌ ชี้ไปที่ object เดียวกัน
ref.setDate(25);
console.log(original.getDate()); // 25 ← เปลี่ยนทั้งคู่!| ข้อผิดพลาด | สิ่งที่เกิดขึ้น | วิธีที่ถูกต้อง |
|---|---|---|
| `new Date(2025, 1, 1)` เพื่อเอา 1 ม.ค. | ได้ 1 ก.พ. — เดือน 1 = กุมภาพันธ์ | `new Date(2025, 0, 1)` — ใช้ 0 สำหรับมกราคม |
| แสดงเดือนจาก `.getMonth()` โดยตรง | ผู้ใช้เห็นเดือน 0–11 (ผิด!) | `.getMonth() + 1` ก่อนแสดงผล |
| ใช้ `.getYear()` | ได้ค่าแปลก ๆ (ปี - 1900) | ใช้ `.getFullYear()` เท่านั้น |
| `.setDate()` บน Date โดยไม่ copy | เปลี่ยนค่าของ Date ต้นฉบับด้วย | copy ก่อน: `new Date(old.getTime())` |
| เปรียบเทียบ Date ด้วย `===` | ได้ `false` เสมอถ้าเป็นคนละ instance | ใช้ `d1.getTime() === d2.getTime()` |
| `new Date("DD-MM-YYYY")` | บาง browser parse ไม่ได้ → Invalid Date | ใช้ `"YYYY-MM-DD"` หรือ `new Date(y,m,d)` |
- month 0-indexed เป็นกับดักที่เจอบ่อยที่สุด — จำให้ขึ้นใจ: มกราคม = 0, ธันวาคม = 11
- `.getFullYear()` / `.setFullYear()` — ใช้ตัวนี้ตลอด ห้ามใช้ `.getYear()` / `.setYear()`
- ส่ง Date ให้ API — ใช้ `.toISOString()` เพื่อให้เป็น format มาตรฐานที่ไม่ขึ้นกับ timezone
- Date เป็น mutable — copy ด้วย `new Date(old.getTime())` เมื่อต้องการเก็บค่าเดิมไว้
- สร้าง Date จาก string — ใช้ ISO 8601 format (`"YYYY-MM-DD"`) เท่านั้น