Date คือโครงสร้าง Foundation ที่แสดงถึงช่วงเวลาที่เฉพาะเจาะจง โดยไม่ขึ้นกับปฏิทินและเขตเวลา ชนิดนี้เก็บจำนวนวินาทีที่ผ่านไปตั้งแต่วันที่อ้างอิงวันที่ 1 มกราคม ค.ศ. 2001 และมีดำเนินการพื้นฐานสำหรับการเปรียบเทียบและการคำนวณช่วงเวลา ตามเอกสาร Apple Developer (2025) Date ถูกใช้ในทุกเฟรมเวิร์กของ Apple ตั้งแต่ UIKit และ SwiftUI ไปจนถึง CloudKit และ Core Data การทำความเข้าใจวิธีทำงานของ Date เป็นสิ่งจำเป็นสำหรับนักพัฒนา iOS ทุกคน เนื่องจากหากไม่มีมันแล้วจะไม่สามารถจัดการเวลาในแอปพลิเคชันได้
ประเด็นสำคัญ
Date เป็นชนิดค่าจากเฟรมเวิร์ก Foundation ที่เก็บช่วงเวลาสัมบูรณ์เดียว ซึ่งแตกต่างจากการแสดงปฏิทิน (ปี เดือน วัน) Date ไม่ขึ้นกับเขตเวลาหรือระบบปฏิทิน — เป็นค่ากำกับเวลาที่เป็นตัวเลขล้วนๆ
การแสดงภายในของ Date คือ TimeInterval (นามแฝงชนิดสำหรับ Double) ซึ่งเก็บจำนวนวินาทีสัมพันธ์กับวันที่อ้างอิง — 1 มกราคม ค.ศ. 2001, 00:00:00 UTC Apple เลือกวันที่นี้แทนยุค Unix (ค.ศ. 1970) เพื่อความเข้ากันได้กับระบบ NeXTSTEP เดิม ซึ่ง iOS และ macOS สร้างขึ้นบนพื้นฐานนั้น
Date ถูกใช้เป็นชนิดเวลามาตรฐานใน API ทั้งหมดของ Apple: UIDatePicker, DatePicker, UserDefaults, Codable, Core Data, CloudKit หากไม่มี Date จะไม่สามารถทำงานกับกำหนดการ ตัวจับเวลา เหตุการณ์ในปฏิทิน การทำให้ข้อมูลเป็นลำดับ และการดำเนินการใดๆ ที่เกี่ยวข้องกับเวลา
Date แตกต่างจากชนิดปฏิทินตรงที่มันแสดงถึงกำกับเวลาทางกายภาพแทนที่จะเป็นค่าที่มนุษย์อ่านได้ Date เดียวกันสามารถสอดคล้องกับวันที่ในปฏิทินที่แตกต่างกันในเขตเวลาที่แตกต่างกัน ในการแยกส่วนประกอบ (ปี เดือน วัน) จะแปลง Date ผ่าน Calendar และ DateComponents
Date ยังแตกต่างจาก DispatchTime ซึ่งใช้สำหรับการจัดส่งงานใน Grand Central Dispatch DispatchTime สัมพันธ์กับเวลาบูตระบบ ในขณะที่ Date เป็นกำกับเวลาสัมบูรณ์ที่สามารถบันทึก ส่ง และกู้คืนได้
Date() เป็นวิธีที่ง่ายที่สุดในการสร้างออบเจ็กต์ด้วยช่วงเวลาปัจจุบัน ตัวเริ่มต้นที่ไม่มีพารามิเตอร์จะคืนเวลาเรียกที่แน่นอน ในการสร้างวันที่ในอดีตหรืออนาคต ให้ใช้ TimeInterval และเมธอด addingTimeInterval หรือการเริ่มต้นจาก Date ที่มีอยู่
ในการสร้างวันที่ตามอำเภอใจจากส่วนประกอบ ให้ใช้คู่ Calendar และ DateComponents Calendar แปลงส่วนประกอบที่มนุษย์อ่านได้ (ปี เดือน วัน ชั่วโมง นาที) เป็น Date คุณยังสามารถเริ่มต้น Date ผ่าน ISO8601DateFormatter จากสตริง ISO 8601 หรือผ่าน DateFormatter จากสตริงที่กำหนดเอง
Date.distantPast และ Date.distantFuture เป็นคุณสมบัติคงที่สองอย่างที่แสดงถึงช่วงเวลาที่ห่างไกลอย่างไม่สิ้นสุดในอดีตและอนาคต ถูกใช้เป็นค่าขอบเขตสำหรับการกรองและเรียงลำดับวันที่ในอัลกอริทึม
import Foundation
// สร้าง Date ด้วยเวลาปัจจุบัน
let now = Date()
print("Current time: \(now)")
// วันที่ใน 1 ชั่วโมง (3600 วินาที)
let inOneHour = now.addingTimeInterval(3600)
// วันที่จากส่วนประกอบ
var components = DateComponents()
components.year = 2025
components.month = 12
components.day = 25
let christmas = Calendar.current.date(from: components)!
ตัวอย่างแสดงสามวิธีในการสร้าง Date: เวลาปัจจุบัน การเพิ่มช่วงเวลา และการสร้างผ่าน DateComponents ทั้งสามวิธีคืนค่าเป็นชนิด Date ด้วยความแม่นยำระดับมิลลิวินาที Calendar.current ใช้ปฏิทินระบบของผู้ใช้ — บนอุปกรณ์ Apple โดยทั่วไปจะเป็นปฏิทินเกรกอเรียน
TimeInterval คือนามแฝงชนิดสำหรับ Double ที่แสดงจำนวนวินาทีระหว่างสองช่วงเวลา ความแม่นยำของ TimeInterval ถึงเศษส่วนของมิลลิวินาที ซึ่งเพียงพอสำหรับงานที่ใช้งานได้จริงส่วนใหญ่ TimeInterval ที่เป็นลบบ่งชี้ถึงอดีตเมื่อเทียบกับจุดอ้างอิง
Date รองรับตัวดำเนินการเปรียบเทียบมาตรฐานทั้งหมด: ==, <, >, <=, >= Swift เปรียบเทียบค่า TimeInterval ภายในโดยอัตโนมัติ เมธอด compare คืนค่า ComparisonResult พร้อมตัวเลือก .orderedSame, .orderedAscending, .orderedDescending สำหรับการเปรียบเทียบที่ชัดเจนยิ่งขึ้น
Date.distance(to:) เป็นเมธอดที่คืนค่า TimeInterval ถึงวันที่ที่ระบุ หากวันที่เป้าหมายอยู่ในอดีต ผลลัพธ์จะเป็นลบ advanced(by:) สร้างวันที่ใหม่โดยเพิ่ม TimeInterval ที่ระบุไปยังวันที่ปัจจุบัน เมธอดเหล่านี้ใช้โปรโตคอล Strideable ทำให้สามารถใช้ Date ใน Range และ ClosedRange
let start = Date()
let end = start.addingTimeInterval(86400)
// เปรียบเทียบด้วยตัวดำเนินการ
if start < end {
print("start is earlier")
}
// TimeInterval ระหว่างสองวันที่
let interval: TimeInterval = end.timeIntervalSince(start)
print("Seconds: \(Int(interval / 60)) minutes")
// ใช้ Date ในช่วง
let range = start...end
let mid = start.addingTimeInterval(43200)
if range.contains(mid) {
print("mid is between start and end")
}
TimeInterval ของ 86400 สอดคล้องกับหนึ่งวัน สำหรับช่วงที่ซับซ้อนมากขึ้น — สัปดาห์ เดือน ปี — ให้ใช้ Calendar และ DateComponents เนื่องจากหน่วยเหล่านี้มีความยาวแปรผัน (ปีอธิกสุรทิน เวลาออมแสง) TimeInterval ใช้ได้เฉพาะกับช่วงเวลาคงที่เป็นวินาที
Calendar คือสะพานเชื่อมระหว่าง Date และส่วนประกอบที่มนุษย์อ่านได้ Calendar แปลง Date เป็น DateComponents (ปี เดือน วัน ชั่วโมง นาที วินาที) โดยคำนึงถึงเขตเวลาและตำแหน่งที่ตั้ง หากไม่มี Calendar จะไม่สามารถแยกปีหรือเดือนจาก Date ได้ — Date ไม่มีข้อมูลนี้เนื่องจากธรรมชาติสัมบูรณ์ของมัน
เมธอด Calendar.component แยกส่วนประกอบเดียวจาก Date: ปี เดือน วัน ชั่วโมง นาที วินาที วันในสัปดาห์ ไตรมาส เมธอด Calendar.dateComponents แยกชุดของส่วนประกอบในการเรียกครั้งเดียว — ซึ่งมีประสิทธิภาพมากกว่าการเรียก component สำหรับแต่ละฟิลด์แยกกัน
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday เป็นเมธอดที่สะดวกสำหรับการตรวจสอบวันที่สัมพัทธ์ Calendar.dateInterval คืนค่าเริ่มต้นและสิ้นสุดของช่วงเวลาที่ระบุ (วัน สัปดาห์ เดือน ปี) Calendar.compare เปรียบเทียบวันที่ด้วยความแม่นยำถึงส่วนประกอบที่ระบุ — เช่น ปีโดยไม่พิจารณาเดือนและวัน
let calendar = Calendar.current
// แยกส่วนประกอบ
let year = calendar.component(.year, from: Date())
let month = calendar.component(.month, from: Date())
// ตรวจสอบวันที่สัมพัทธ์
if calendar.isDateInToday(someDate) {
print("Today!")
}
// จุดเริ่มต้นและสิ้นสุดของวัน
let dayInterval = calendar.dateInterval(of: .day, for: Date())!
print("Day start: \(dayInterval.start)")
print("Day end: \(dayInterval.end)")
Calendar.current ใช้การตั้งค่าระบบของผู้ใช้ — ปฏิทิน เขตเวลา และตำแหน่งที่ตั้ง สำหรับการทดสอบหรือการคำนวณเฉพาะ คุณสามารถสร้าง Calendar ด้วยพารามิเตอร์เฉพาะผ่าน Calendar(identifier: .gregorian) และตั้งค่า TimeZone ที่ต้องการผ่านคุณสมบัติ timeZone
DateFormatter เป็นคอมโพเนนต์ที่จำเป็นหากต้องการแสดง Date ให้ผู้ใช้ DateFormatter แปลง Date เป็นสตริงตามรูปแบบและตำแหน่งที่ตั้งที่ระบุ การแปลง Date เป็นสตริงโดยตรงผ่าน String(describing:) จะคืนค่าการแสดงทางเทคนิคพร้อมวันที่อ้างอิงและ TimeInterval — ซึ่งไม่ได้มีไว้สำหรับผู้ใช้
วิธีพื้นฐานคือการใช้สไตล์ที่ตั้งไว้ล่วงหน้า dateStyle และ timeStyle iOS รองรับสี่สไตล์: .short, .medium, .long, .full การรวมกันของสไตล์วันที่และเวลาช่วยให้สามารถกำหนดค่าการแสดงผลได้อย่างยืดหยุ่น DateFormatter ใช้การแปลเป็นภาษาท้องถิ่นโดยอัตโนมัติ: สำหรับตำแหน่งที่ตั้งของรัสเซีย วันที่จะแสดงในรูปแบบ “21 กรกฎาคม 2026”
ISO8601DateFormatter เป็นฟอร์แมตเตอร์เฉพาะสำหรับ ISO 8601 ซึ่งเป็นรูปแบบทั่วไปที่สุดสำหรับ API และการแลกเปลี่ยนข้อมูล ฟอร์แมตเตอร์นี้ทำงานเร็วกว่า DateFormatter และไม่ขึ้นกับตำแหน่งที่ตั้ง ทำให้เป็นที่นิยมสำหรับการทำให้วันที่เป็นลำดับใน JSON
// สไตล์ที่ตั้งไว้ล่วงหน้า
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let userString = formatter.string(from: Date())
// ISO 8601 สำหรับ API
let isoFormatter = ISO8601DateFormatter()
let apiString = isoFormatter.string(from: Date())
// แยกวิเคราะห์จากสตริง
let parsed = isoFormatter.date(from: "2026-07-21T10:30:00Z")!
เมื่อทำงานกับ DateFormatter สิ่งสำคัญคือต้องจำเกี่ยวกับ ประสิทธิภาพ: การสร้างฟอร์แมตเตอร์ใหม่เป็นการดำเนินการที่แพง ขอแนะนำให้แคชฟอร์แมตเตอร์หรือสร้างครั้งเดียวแล้วนำกลับมาใช้ใหม่ คุณสมบัติของฟอร์แมตเตอร์อนุญาตให้ตั้งค่า timeZone — โดยค่าเริ่มต้นจะใช้เขตเวลาของระบบ แต่สำหรับวันที่จากเซิร์ฟเวอร์ มักต้องการ TimeZone(identifier: “UTC”)
ลองพิจารณาสถานการณ์ทั่วไปสำหรับการทำงานกับ Date ในแอปพลิเคชัน iOS สถานการณ์แรกคือ การคำนวณอายุ จากวันเกิดของผู้ใช้ สถานการณ์ที่สองคือ ตัวจับเวลาถอยหลัง ไปยังเหตุการณ์ สถานการณ์ที่สามคือ การจัดกลุ่มบันทึกตามวันที่ สำหรับแสดงเป็นส่วนของตาราง
Calendar.dateComponents พร้อมแฟล็ก [.year] คำนวณความแตกต่างระหว่างสองวันที่ การตั้งค่าเขตเวลาที่ถูกต้องเป็นสิ่งสำคัญ — หากคุณไม่ระบุ timeZone ใน Calendar ผลลัพธ์อาจแตกต่างกันหนึ่งวันเนื่องจากการข้ามเที่ยงคืนในเขตเวลาอื่น
func calculateAge(from birthDate: Date) -> Int {
let calendar = Calendar.current
let now = Date()
let components = calendar.dateComponents(
[.year], from: birthDate, to: now
)
return components.year ?? 0
}
ตัวจับเวลาถอยหลัง ใช้ TimeInterval ในการคำนวณ คำนวณความแตกต่างระหว่างวันที่เป้าหมายและวันที่ปัจจุบัน หาเศษเหลือเป็นวินาทีและแปลงเป็นวัน ชั่วโมง นาที สำหรับการอัปเดตเป็นประจำ ให้ใช้ Timer ด้วยช่วงเวลา 1 วินาที ObservableObject ที่มีคุณสมบัติ @Published ช่วยให้ SwiftUI อัปเดตอินเทอร์เฟซโดยอัตโนมัติ
การจัดกลุ่มตามวันที่ ใช้ดิกชันนารีโดยมี Date เป็นคีย์ Calendar.dateInterval(of: .day, for:) ทำให้วันที่เป็นปกติถึงจุดเริ่มต้นของวัน ซึ่งช่วยให้คุณจัดกลุ่มบันทึกที่เป็นของวันเดียวกัน วิธีการเดียวกันนี้ใช้ได้กับสัปดาห์ เดือน และปี — เพียงเปลี่ยนส่วนประกอบใน dateInterval เป็น .weekOfYear หรือ .month
| สถานการณ์ | API หลัก | หมายเหตุ |
|---|---|---|
| คำนวณอายุ | Calendar.dateComponents | พิจารณา timeZone |
| นับถอยหลัง | Date.timeIntervalSince | Timer+Combine |
| จัดกลุ่มวันที่ | Calendar.dateInterval | ทำให้เป็นปกติถึงวัน |
| ทำให้ JSON เป็นลำดับ | ISO8601DateFormatter | Locale ไม่มีผล |
คำถามที่พบบ่อย
Date คือการแสดงเวลาภายในโดยไม่ผูกกับปฏิทินและตำแหน่งที่ตั้ง สตริงคือการแสดงที่จัดรูปแบบซึ่งขึ้นอยู่กับการตั้งค่าของผู้ใช้ Date สามารถเปรียบเทียบ ทำให้เป็นลำดับ และประมวลผลทางคณิตศาสตร์ได้ด้วยความแม่นยำ 100% ในขณะที่การแสดงเป็นสตริงมักต้องมีการแยกวิเคราะห์ผ่านฟอร์แมตเตอร์
Date คือกำกับเวลาสัมบูรณ์ (จำนวนวินาทีจากวันที่อ้างอิง) ที่ไม่ขึ้นกับเขตเวลา เขตเวลาคือบริบทการแสดงผล Date เดียวกันใน UTC และในมอสโกแสดงถึงช่วงเวลาทางกายภาพเดียวกัน แต่แสดงเป็นเวลาปฏิทินที่แตกต่างกัน
Date รองรับโดย Core Data โดยตรงเป็นชนิดแอตทริบิวต์ Core Data จะทำให้ Date เป็นลำดับไปยังพื้นที่เก็บข้อมูลโดยอัตโนมัติ สำหรับคำสั่งค้นหาที่มีการกรองตามวันที่ ให้ใช้ NSPredicate พร้อมตัวดำเนินการเปรียบเทียบ — Core Data จัดการเขตเวลาอย่างถูกต้องในระดับ SQLite
CFAbsoluteTime คือชนิด Core Foundation ที่ใช้วันที่อ้างอิงเดียวกัน (1 มกราคม ค.ศ. 2001) Date และ CFAbsoluteTime สามารถใช้แทนกันได้ผ่านการแปลงโดยตรง Date(timeIntervalSinceReferenceDate:) รับ CFAbsoluteTime และ Date.timeIntervalSinceReferenceDate คืนค่า CFAbsoluteTime
Date มีความแม่นยำระดับมิลลิวินาที แต่ไม่รับประกันความแม่นยำระดับนาโนวินาทีเนื่องจากข้อจำกัดของฮาร์ดแวร์ iOS/macOS สำหรับการวัดความแม่นยำสูง ให้ใช้ mach_absolute_time หรือ ContinuousClock จาก Swift 5.7+ ซึ่งทำงานบนตัวนับรอบของโปรเซสเซอร์
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม