Unix Timestamp คือจำนวนเต็มที่แสดงจำนวนวินาทีที่ผ่านไปตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC รูปแบบเวลาสากลนี้ใช้ในระบบปฏิบัติการ ฐานข้อมูล API และแอปพลิเคชันมือถือสำหรับจัดเก็บและส่งเครื่องหมายเวลาโดยไม่ขึ้นอยู่กับเขตเวลา ตามข้อมูลจาก Google Developers Blog (2025) Unix Timestamp ยังคงเป็นรูปแบบที่นิยมมากที่สุดสำหรับการทำซีเรียลไลซ์เวลาใน REST API — 87% ของอินเทอร์เฟซเว็บสาธารณะใช้งานมัน
ประเด็นสำคัญ
Unix Timestamp (หรือที่เรียกว่า POSIX time, Epoch time หรือ Unix time) เป็นระบบวัดเวลาที่กำหนดจำนวนวินาทีที่ผ่านไปตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC (ยุค Unix) วันที่นี้ถูกเลือกเป็นจุดเริ่มต้นสำหรับระบบปฏิบัติการ Unix และต่อมารูปแบบนี้ได้กลายเป็นมาตรฐานโดยพฤตินัยสำหรับการแสดงเวลาในระบบคอมพิวเตอร์ Timestamp ไม่คำนึงถึงวินาทีอธิกสุรทิน — แต่ละนาทีจะนับเป็น 60 วินาที แม้ว่าบริการหมุนโลกระหว่างประเทศจะเพิ่มวินาทีพิเศษเป็นครั้งคราวเพื่อแก้ไขเวลาอะตอม
การเลือกวันที่ 1 มกราคม 1970 เชื่อมโยงกับประวัติศาสตร์ของระบบปฏิบัติการ Unix นักพัฒนา Ken Thompson และ Dennis Ritchie เลือกวันที่นี้เป็นจุดเริ่มต้นที่เรียบง่าย — มันเร็วพอที่จะครอบคลุมวันที่ที่เป็นไปได้ทั้งหมด และช้าพอที่จะเก็บเวลาในจำนวนเต็มที่มีเครื่องหมาย 32 บิต ในตอนแรก เวลาถูกวัดในหนึ่งในหกสิบของวินาที จากนั้นในหน่วยติ๊ก (1/60 วินาที) และเฉพาะใน Unix ฉบับที่เจ็ด (V7, 1979) รูปแบบจึงคงที่เป็นจำนวนเต็มวินาที ตามThe Open Group Base Specifications (Issue 8, 2024) ระบบที่เข้ากันได้กับ POSIX จำเป็นต้องรองรับรูปแบบนี้
หลักการทำงานของ Unix Timestamp ขึ้นอยู่กับตัวนับอย่างง่าย: ในแต่ละวันที่ผ่านไปจะเพิ่ม 86,400 วินาทีให้กับค่า ตัวอย่างเช่น timestamp 1,720,000,000 สอดคล้องกับวันที่ในช่วงกลางปี 2024 — การแปลงที่แน่นอนสามารถทำได้โดยการหารด้วยจำนวนวินาทีในหนึ่งวัน หนึ่งชั่วโมง และหนึ่งนาที วิธีการนี้ทำให้ timestamp เหมาะสำหรับการจัดเก็บในเครื่อง: มันเป็นจำนวนเต็มที่ใช้พื้นที่ 4 ไบต์ (int 32 บิต) หรือ 8 ไบต์ (long 64 บิต) และรองรับการเปรียบเทียบโดยตรง — timestamp ที่มากกว่า = วันที่ที่ช้ากว่า
หนึ่งวัน = 86,400 วินาที (24 x 60 x 60) หนึ่งชั่วโมง = 3,600 วินาที ในการแปลง timestamp เป็นวันที่ คุณต้องคำนวณจำนวนวัน ชั่วโมง นาที และวินาทีจากยุคตามลำดับ การแปลงย้อนกลับ — แปลงวันที่เป็นวันนับจาก 1970-01-01 จากนั้นคูณด้วย 86,400 และเพิ่มออฟเซ็ต UTC ใน Java และ Kotlin การคำนวณเหล่านี้ถูกนำไปใช้แล้วในคลาสมาตรฐาน java.time.Instant และ java.util.Date ซึ่งช่วยนักพัฒนาจากการคำนวณด้วยตนเอง
// รับ Unix Timestamp ในหน่วยวินาที
val seconds = System.currentTimeMillis() / 1000
// แปลง timestamp เป็นวันที่ผ่าน java.time
val instant = Instant.ofEpochSecond(seconds)
val localDate = instant.atZone(ZoneId.of("Europe/Moscow")).toLocalDate()
// ย้อนกลับ: วันที่เป็น timestamp
val date = LocalDate.of(2026, 7, 21)
val ts = date.atStartOfDay(ZoneOffset.UTC).toEpochSecond()
การแปลง Unix Timestamp เป็นวันที่ที่มนุษย์อ่านได้เป็นหนึ่งในการดำเนินการที่พบบ่อยที่สุดในการพัฒนาแอปมือถือ ใน Android มีวิธีการแปลงหลายวิธีขึ้นอยู่กับเวอร์ชัน API ขั้นต่ำ: สำหรับ API 26+ แนะนำให้ใช้ java.time.Instant สำหรับเวอร์ชันเก่าให้ใช้ java.util.Date และ java.text.SimpleDateFormat สิ่งสำคัญที่ต้องจำคือ Android และ JVM ใช้มิลลิวินาทีเป็นค่าเริ่มต้น ไม่ใช่วินาที — หากได้รับ timestamp จากเซิร์ฟเวอร์ในหน่วยวินาที จะต้องคูณด้วย 1000 ก่อนส่งต่อไปยังคอนสตรัคเตอร์มาตรฐาน
ข้อดีหลักประการหนึ่งของ Unix Timestamp คือความเป็นอิสระจากตำแหน่งที่ตั้ง เซิร์ฟเวอร์จะส่งคืน timestamp ในหน่วย UTC เสมอ และการแปลงเป็นวันที่และเวลาท้องถิ่นจะดำเนินการฝั่งไคลเอนต์ ใน Kotlin ใช้ ZonedDateTime กับ ZoneId ที่เหมาะสม — ไม่ว่าจะเป็นของระบบหรือที่ผู้ใช้เลือก หากแอปพลิเคชันแสดงเวลาในเขตเวลาที่แตกต่างกัน (เช่น สำหรับนักเดินทาง) timestamp จะขจัดความจำเป็นในการส่งเขตเวลาจากเซิร์ฟเวอร์ — เครื่องหมายเวลาเดียวก็เพียงพอ
// แปลงด้วยเขตเวลาของผู้ใช้
fun formatTimestamp(seconds: Long, zoneId: ZoneId): String {
val instant = Instant.ofEpochSecond(seconds)
val formatter = DateTimeFormatter
.ofPattern("dd.MM.yyyy HH:mm:ss")
return formatter.format(instant.atZone(zoneId))
}
// ตัวอย่าง: timestamp = 1720000000, zone = Europe/Moscow
val result = formatTimestamp(1720000000, ZoneId.of("Europe/Moscow"))
ปัญหาปี 2038 (Y2K38) เป็นข้อจำกัดพื้นฐานของการจัดเก็บ Unix Timestamp เป็นจำนวนเต็มที่มีเครื่องหมาย 32 บิต ค่าสูงสุดของ int ที่มีเครื่องหมาย 32 บิตคือ 2,147,483,647 ซึ่งสอดคล้องกับวันที่ 19 มกราคม 2038 เวลา 03:14:07 UTC หลังจากวันที่นี้ค่าจะล้นและกลายเป็นจำนวนลบ ทำให้เกิดความล้มเหลวในระบบที่ใช้ time_t 32 บิต ปัญหาคล้ายกับ Y2K ที่รู้จักกันดี แต่ส่งผลกระทบต่อระบบฝังตัว Android เวอร์ชันเก่า และอุปกรณ์ IoT ที่มีสถาปัตยกรรม 32 บิตเป็นหลัก
ตามLinux Foundation (2025) อุปกรณ์ Linux ประมาณ 15% ในกลุ่มอุตสาหกรรมและ IoT ยังคงใช้บิลด์ 32 บิต สำหรับอุปกรณ์ Android ความเสี่ยงต่ำกว่า — สมาร์ทโฟนสมัยใหม่ส่วนใหญ่ทำงานบนโปรเซสเซอร์ 64 บิต (ARM64) แต่รุ่นเก่าที่ใช้ Android 4.x และต่ำกว่าอาจใช้ time_t 32 บิต วิธีแก้ปัญหาคือการย้ายไปยัง time_t 64 บิต ซึ่งปลอดภัยนานถึง 292 พันล้านปี ตั้งแต่ Android 5.0 (API 21) อุปกรณ์ทั้งหมดใช้เวลา 64 บิตในระดับเคอร์เนล นักพัฒนาแอปพลิเคชันมือถือเพียงแค่จัดเก็บ timestamp ในรูปแบบ Long (64 บิต) เพื่อหลีกเลี่ยงปัญหาในระดับแอปพลิเคชัน
ในการพัฒนา Android การจัดการ Unix Timestamp อย่างถูกต้องมีความสำคัญต่อการซิงโครไนซ์ข้อมูล การแสดงเวลา receiving ข้อความ การคำนวณไทม์เอาต์ และการจัดกำหนดการแจ้งเตือน การเรียกของระบบ System.currentTimeMillis() ส่งคืนเวลาปัจจุบันในหน่วยมิลลิวินาทีตั้งแต่ยุค Unix — นี่คือแหล่งเวลาที่แม่นยำที่สุดที่มีอยู่ในอุปกรณ์ สำหรับคำขอเครือข่าย โดยทั่วไปจะใช้ Unix Timestamp ในหน่วยวินาที เนื่องจาก REST API และฐานข้อมูลส่วนใหญ่ทำงานในหน่วยวินาที
อย่าใช้ System.currentTimeMillis() เพื่อวัดช่วงเวลา — สำหรับวัตถุประสงค์นี้มี System.nanoTime() ซึ่งเป็นแบบโมโนโทนิกและไม่ได้รับผลกระทบจากการเปลี่ยนแปลงนาฬิกาของผู้ใช้ สำหรับการแสดงเวลา ให้จัดเก็บ timestamp ในหน่วย UTC เสมอและแปลงเป็นเขตเวลาท้องถิ่นฝั่ง UI เมื่อทำงานกับฐานข้อมูล (SQLite, Room) ให้ใช้ประเภท INTEGER และจัดเก็บ timestamp ในหน่วยวินาที — ซึ่งใช้พื้นที่ 8 ไบต์ (Long) และรองรับการเรียงลำดับ SQL ดั้งเดิม สำหรับการทำซีเรียลไลซ์ JSON แนะนำให้ส่ง timestamp เป็นตัวเลข (Long) แทนสตริง — มีขนาดกะทัดรัดกว่าและแยกวิเคราะห์เร็วกว่า
// การวัดเวลาดำเนินการที่ถูกต้อง
val start = System.nanoTime()
// ... การดำเนินการ ...
val elapsed = System.nanoTime() - start
val seconds = elapsed / 1_000_000_000.0
// จัดเก็บใน Room (Entity)
@Entity
data class Message(
@PrimaryKey val id: Long,
val text: String,
val createdAt: Long // Unix Timestamp ในหน่วยวินาที
)
เมื่อรับ Unix Timestamp จากเซิร์ฟเวอร์ ให้ตรวจสอบหน่วยวัดเสมอ: บาง API ส่งคืนมิลลิวินาที (เข้ากันได้กับ JavaScript) บางส่วนส่งคืนวินาที (มาตรฐาน POSIX) ข้อตกลงเกี่ยวกับหน่วยควรถูกบันทึกในเอกสาร API ในการตอบสนองของเซิร์ฟเวอร์ timestamp สามารถส่งเป็น Long (ตัวเลข JSON) หรือ String (ISO 8601) สำหรับการดีบัก ให้เพิ่มฟังก์ชันอรรถประโยชน์ที่แสดง timestamp ในรูปแบบที่มนุษย์อ่านได้ — ซึ่งช่วยให้การตรวจสอบเครื่องหมายเวลาระหว่างการพัฒนาง่ายขึ้น
การเลือกรูปแบบการจัดเก็บเวลาในฐานข้อมูลส่งผลโดยตรงต่อประสิทธิภาพการค้นหา ความซับซ้อนของโค้ด และความถูกต้องของการจัดการเขตเวลา Unix Timestamp เป็นรูปแบบที่มีประสิทธิภาพมากที่สุดสำหรับฐานข้อมูลเชิงสัมพันธ์: มันถูกจัดเก็บเป็นจำนวนเต็ม (4 หรือ 8 ไบต์) รองรับการสร้างดัชนี และช่วยให้เรียงลำดับได้รวดเร็ว ไม่เหมือนสตริง ISO 8601 timestamp ไม่จำเป็นต้องแยกวิเคราะห์สำหรับการเรียงลำดับและใช้พื้นที่ในดัชนีน้อยกว่า สำหรับ Room และ SQLite แนะนำให้จัดเก็บ timestamp เป็น INTEGER และใช้ดัชนีบนคอลัมน์เวลา
| รูปแบบการจัดเก็บ | ขนาด | การเรียงลำดับ | การสร้างดัชนี |
|---|---|---|---|
| Unix Timestamp (INTEGER) | 4–8 ไบต์ | เร็ว | มีประสิทธิภาพ |
| ISO 8601 (TEXT) | 20–30 ไบต์ | ช้า | ปานกลาง |
| DATETIME (SQLite) | 8 ไบต์ | ปานกลาง | ปานกลาง |
สำหรับแอปพลิเคชัน Android ที่ใช้ไลบรารี Room แนะนำให้จัดเก็บ timestamps เป็น Long (64 บิต) และใช้ TypeConverter สำหรับการแปลงอัตโนมัติระหว่าง Long และ Date หรือ Instant เมื่อค้นหาฐานข้อมูล ให้ใช้ตัวดำเนินการเปรียบเทียบ (>, <, BETWEEN) — มันทำงานแบบดั้งเดิมกับประเภทจำนวนเต็ม สำหรับการแคชข้อมูลที่ต้องการการเรียงลำดับตามเวลา (เช่น รายการข้อความ) ให้สร้างดัชนีบนคอลัมน์ timestamp เสมอ — ซึ่งจะช่วยเร่งความเร็วการค้นหาด้วย ORDER BY หลายเท่าเมื่อมีปริมาณข้อมูลมาก
คำถามที่พบบ่อย
Unix Timestamp คือจำนวนวินาทีตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC มันทำงานเหมือนตัวนับอย่างง่าย: ในแต่ละวันที่ผ่านไปจะเพิ่ม 86,400 วินาที เป็นจำนวนเต็มที่สามารถเปรียบเทียบ เรียงลำดับ และถ่ายโอนระหว่างเซิร์ฟเวอร์และไคลเอนต์ได้โดยไม่ขึ้นกับเขตเวลา
ใช้ Instant.ofEpochSecond(timestamp) สำหรับ java.time (API 26+) หรือ Date(timestamp * 1000) สำหรับ Android เวอร์ชันเก่า หลังจากได้รับ Instant แล้วสามารถแปลงเป็น LocalDate, ZonedDateTime หรือจัดรูปแบบผ่าน DateTimeFormatter อย่าลืมคูณด้วย 1000 ถ้า timestamp อยู่ในหน่วยวินาที
ในวันที่ 19 มกราคม 2038 เวลา 03:14:07 UTC ค่า int ที่มีเครื่องหมาย 32 บิต (2,147,483,647) จะเกิน ทำให้เกิดโอเวอร์โฟลว์ ระบบที่ใช้ time_t 32 บิตจะเริ่มตีความเวลาเป็นจำนวนลบ วิธีแก้ไขคือการย้ายไปยัง time_t 64 บิต ซึ่งใช้อยู่แล้วในอุปกรณ์ Android สมัยใหม่ (API 21+)
เรียก System.currentTimeMillis() / 1000 สำหรับวินาทีหรือ System.currentTimeMillis() สำหรับมิลลิวินาที สำหรับผลลัพธ์ที่แม่นยำยิ่งขึ้นโดยคำนึงถึงการซิงโครไนซ์เครือข่าย ให้ใช้ Instant.now().epochSecond (ต้องใช้ API 26+) หรือไลบรารีไคลเอนต์ NTP สำหรับ Android
Unix Timestamp คือวินาทีตั้งแต่วันที่ 1970-01-01 UTC (จำนวนเต็ม) Java Timestamp ใช้ มิลลิวินาที — ออฟเซ็ตเดียวกันแต่แม่นยำกว่า 1000 เท่า สำหรับการแปลง: มิลลิวินาทีหารด้วย 1000 API JSON มักใช้วินาที (Unix Timestamp) ในขณะที่แพลตฟอร์ม Android ใช้มิลลิวินาที (System.currentTimeMillis)
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ