DateComponents ay isang istraktura ng Foundation na nag-iimbak ng mga component ng petsa ng kalendaryo bilang magkakahiwalay na field: taon, buwan, araw, oras, minuto, segundo at iba pa. Hindi tulad ng Date, na kumakatawan sa isang ganap na sandali sa oras, ang DateComponents ay naglalaman ng mga halaga na nababasa ng tao, depende sa kalendaryo at time zone. Ayon sa Apple Developer Documentation (2025), ang DateComponents ay ginagamit bilang intermediate na ugnayan sa pagitan ng Date at Calendar – sa pamamagitan nito ay kinukuha at binuo ang mga petsa ng kalendaryo, ginagawa ang mga kalkulasyon at paglipat ng petsa nang walang manual na aritmetika.
Mga pangunahing punto
DateComponents ay isang value type ng Foundation na idinisenyo para sa pag-iimbak ng mga kalendaryong component ng oras. Ang bawat component ay kinakatawan bilang isang opsyonal na Int field: year, month, day, hour, minute, second, nanosecond, weekday, weekOfMonth, weekOfYear, quarter, yearForWeekOfYear at iba pa.
Ang pangunahing pagkakaiba mula sa Date ay ang pagkakaugnay sa kalendaryo. Ang Date ay nag-iimbak ng ganap na oras (bilang ng mga segundo mula sa reference date), habang ang DateComponents ay isang representasyong nababasa ng tao na may kahulugan lamang sa konteksto ng isang partikular na Calendar. Ang parehong Date ay maaaring katawanin ng iba't ibang DateComponents sa iba't ibang kalendaryo at time zone.
Ang DateComponents ay hindi isang nagsasariling uri ng oras, kundi isang lalagyan ng data. Para sa interpretasyon ng DateComponents bilang petsa, kinakailangan ang Calendar na nauunawaan kung paano nauugnay ang mga component sa sistema ng kalendaryo. Ang Calendar.dateComponents(from: Date) ay nagsasagawa ng pagkuha ng mga component, ang Calendar.date(from: DateComponents) – ang baligtad na pagbubuo.
Bawat field ng DateComponents ay opsyonal (Int?), na pangunahing para sa pagtatrabaho sa hindi kumpletong petsa. Kung tinukoy mo lamang ang taon at buwan, kukumpletuhin ng Calendar ang mga nawawalang field gamit ang mga default na halaga: araw = 1, oras = 0, minuto = 0. Ito ay maginhawa para sa paglikha ng mga petsa ng simula ng panahon – kailangan mo lamang tukuyin ang mga component na interesado ka.
Kapag inihambing ang DateComponents gamit ang operator ==, tanging ang mga tinukoy (hindi nil) na field ang inihahambing. Dalawang istraktura ng DateComponents na may taong 2026 ngunit magkaibang buwan ay itinuturing na magkaiba. Ang isEqual mula sa NSObjectProtocol ay hindi inilalapat para sa DateComponents – ang DateComponents ay hindi nagmamana ng NSObject.
Mga pangunahing field ng DateComponents ay kinabibilangan ng year, month, day, hour, minute, second, nanosecond. Ang bawat field ay nag-iimbak ng numerikong halaga sa kaukulang yunit: taon – 2026, buwan – 1..12, araw – 1..31, oras – 0..23, minuto – 0..59, segundo – 0..59. Ang mga nanosecond ay maaaring tumanggap ng mga halagang 0..999999999.
Mga field ng linggo – weekday (1..7, kung saan 1 = Linggo sa kalendaryong Gregorian), weekOfMonth, weekOfYear. Ang mga field na ito ay nakadepende sa Calendar at walang kahulugan sa labas ng konteksto nito. Ang weekday ay nakadepende sa setting ng firstWeekday ng kalendaryo: sa lokal na Pilipino, ang linggo ay nagsisimula sa Lunes (weekday = 2 sa sistemang Gregorian), at sa lokal na Amerikano – sa Linggo (weekday = 1).
Mga espesyal na field – quarter (1..4), yearForWeekOfYear (taon kung saan nabibilang ang linggo), isLeapMonth (lohikal na bandila para sa mga leap month sa kalendaryong Hebrew o Chinese). Ang mga field na calendar at timeZone ay nag-iimbak ng mga sanggunian sa kaukulang mga bagay kung saan nilikha ang istraktura.
| Kategorya | Mga field | Saklaw |
|---|---|---|
| Kalendaryo | year, month, day | 1..∞, 1..12, 1..31 |
| Oras | hour, minute, second, nanosecond | 0..23, 0..59, 0..59, 0..999999999 |
| Lingguhan | weekday, weekOfMonth, weekOfYear | 1..7, 1..5, 1..53 |
| Espesyal | quarter, yearForWeekOfYear | 1..4, nakadepende |
Kapag kumukuha ng mga component sa pamamagitan ng Calendar.dateComponents, mahalagang humiling lamang ng mga kinakailangang field para sa pagganap. Kinukuha ng Calendar ang lahat ng hinihiling na field sa isang pagdaan – ito ay mas mabilis kaysa sa pagtawag ng Calendar.component para sa bawat field nang hiwalay.
Pagsisimula ng DateComponents – ang pinakasimpleng paraan: lumikha ka ng isang walang laman na istraktura at punan ang mga kinakailangang field. Lahat ng hindi tinukoy na field ay awtomatikong tumatanggap ng nil. Ang petsang nilikha mula sa bahagyang mga component ay hindi nabe-validate sa yugto ng pagsisimula – ang error ay maaaring mangyari lamang sa conversion sa Date sa pamamagitan ng Calendar.
Ang inisyalayser na DateComponents(calendar:timeZone:era:year:month:day:hour:minute:second:nanosecond:weekday:…) ay nagpapahintulot sa pagtatakda ng lahat ng field sa isang tawag. Ang inisyalayser na ito ay maginhawa para sa paglikha ng kumpletong petsa mula sa mga handa na halaga, ngunit bihirang ginagamit na may higit sa 5-6 na argumento dahil sa pagiging nababasa.
Calendar.dateComponents(_:from:) – ang pangunahing paraan ng pagkuha ng DateComponents mula sa isang umiiral na Date. Ang pangalawang argumento ay ang set ng mga component na kukunin. Ang Calendar ay nagsasagawa ng mga kalkulasyon sa kalendaryo na isinasaalang-alang ang time zone at nagbabalik ng istraktura lamang na may mga hinihiling na field, ang natitirang mga field ay nananatiling nil.
import Foundation
// Paglikha sa pamamagitan ng field inisyalayser
var components = DateComponents()
components.year = 2026
components.month = 7
components.day = 21
// Pagkuha mula sa Date
let now = Date()
let extracted = Calendar.current.dateComponents(
[.year, .month, .day],
from: now
)
print("Today: \(extracted.day!).\(extracted.month!).\(extracted.year!)")
// Paglikha sa pamamagitan ng pinalawak na inisyalayser
let birthday = DateComponents(
calendar: Calendar.current,
year: 1990, month: 5, day: 15
)
Kapag lumilikha ng DateComponents sa pamamagitan ng manual na mga field, palaging suriin ang Calendar bago ang conversion sa Date. Ang Calendar sa conversion na date(from:) ay maaaring magbalik ng nil kung ang mga component ay bumubuo ng isang hindi umiiral na petsa – halimbawa, 31 Pebrero o 30 Pebrero sa isang hindi leap year. Ang pagpapatunay ng petsa ay responsibilidad ng Calendar, hindi ng DateComponents.
Calendar.date(from:) – ang pangunahing paraan ng conversion ng DateComponents sa Date. Ang Calendar ay nag-interpret ng mga component ayon sa kalendaryo at time zone nito. Kung ang ilang field ay hindi nakatakda (nil), ang Calendar ay gumagamit ng mga default na halaga: araw = 1, oras = 0, minuto = 0, segundo = 0.
Ang pamamaraan ay nagbabalik ng isang opsyonal na Date – ang nil ay nangyayari kapag ang mga component ay sumasalungat sa isa't isa o bumubuo ng isang hindi wastong petsa. Mga karaniwang sanhi ng nil: hindi umiiral na petsa (32 Enero, 29 Pebrero 2023), magkasalungat na field (weekday=1, day=5 sa isang set), imposibleng taon para sa ibinigay na kalendaryo (taon 0 sa kalendaryong Gregorian).
DateComponents na may timeZone – kung ang DateComponents ay naglalaman ng timeZone, ginagamit ito ng Calendar sa conversion. Kung hindi tinukoy ang timeZone, ginagamit ng Calendar ang sarili nitong kasalukuyang timeZone. Kung ang Calendar.timeZone ay hindi tumutugma sa inaasahang time zone ng petsa, ang resulta ay maaaring mag-iba ng ilang oras – tiyakin na ang timeZone ay tahasang nakatakda sa isa sa mga bagay.
let calendar = Calendar(identifier: .gregorian)
// Paglikha ng Date mula sa DateComponents
var comps = DateComponents()
comps.year = 2026
comps.month = 12
comps.day = 25
comps.hour = 10
if let date = calendar.date(from: comps) {
print("Christmas: \(date)")
}
// Paglikha na may pagtukoy ng timeZone
calendar.timeZone = TimeZone(identifier: "UTC")!
let utcComps = DateComponents(
calendar: calendar, year: 2026, month: 7, day: 21,
hour: 12
)
let utcDate = calendar.date(from: utcComps)!
Calendar.dateComponents para sa pagkakaiba ng petsa – isa pang senaryo ng paggamit ng DateComponents. Ang Calendar.dateComponents([.year, .month, .day], from: Date(), to: futureDate) ay nagbabalik ng pagkakaiba sa mga taon, buwan at araw sa pagitan ng dalawang petsa. Ito ang tamang paraan ng pagkalkula ng edad sa halip na paghahati ng TimeInterval sa bilang ng mga segundo sa isang taon, dahil isinasaalang-alang ng Calendar ang mga leap year.
Calendar – ang sentral na klase na gumagana sa DateComponents. Lahat ng operasyon ng pagkuha, pagbubuo at paghahambing ng mga petsa ay dumadaan sa Calendar. Kung walang Calendar, ang DateComponents ay isang koleksyon lamang ng mga numero na walang temporal na kahulugan. Ang Calendar ay nagbibigay ng interpretasyon sa mga component: tinutukoy nito na ang buwan 2 ay Pebrero, at ang weekday 2 ay Lunes.
Calendar.nextDate at Calendar.enumerateDates – dalawang pamamaraan batay sa DateComponents. Ang nextDate(after: Date(), matching: DateComponents) ay nahahanap ang susunod na petsa na tumutugma sa mga tinukoy na component – halimbawa, ang susunod na Lunes pagkatapos ngayon. Ang enumerateDates(startingAfter:matching:matchingPolicy:using:) ay umuulit sa lahat ng petsang tumutugma sa pattern hanggang sa isang tinukoy na limitasyon.
Calendar.dateInterval – isang pamamaraan na nagbabalik ng DateInterval para sa tinukoy na component. Ang dateInterval(of: .month, for: Date()) ay nagbabalik ng simula at katapusan ng kasalukuyang buwan. Sa loob, ang pamamaraang ito ay gumagamit ng DateComponents upang mahanap ang mga hangganan ng panahon: lumilikha ito ng DateComponents na may una at huling araw ng buwan, kino-convert ang mga ito sa Date sa pamamagitan ng Calendar.
let calendar = Calendar.current
// Susunod na Lunes
let nextMonday = calendar.nextDate(
after: Date(),
matching: DateComponents(weekday: 2),
matchingPolicy: .nextTime
)!
// Pagkakaiba sa pagitan ng mga petsa sa mga araw
let diff = calendar.dateComponents(
[.day], from: Date(), to: nextMonday
)
// Saklaw ng buwan
let monthInterval = calendar.dateInterval(
of: .month, for: Date()
)!
let startOfMonth = monthInterval.start
let endOfMonth = monthInterval.end
MatchingPolicy – isang mahalagang parameter ng mga pamamaraan ng Calendar kapag nagtatrabaho sa DateComponents. Ang strictPolicy ay nangangailangan ng eksaktong pagtutugma ng lahat ng component, ang nextTimePolicy ay pumipili ng susunod na pagtutugma sa oras, ang nextTimePreservingSmallerComponents ay nagpapanatili ng mas maliliit na component (minuto, segundo) mula sa orihinal na petsa. Ang pagpili ng patakaran ay nakakaapekto sa resulta ng paghahanap ng petsa, lalo na sa paglipat sa pamamagitan ng daylight saving time.
Tatalakayin natin ang mga praktikal na senaryo ng paggamit ng DateComponents sa isang application. Ang bawat halimbawa ay nagpapakita ng isang tipikal na gawain na kinakaharap ng isang iOS developer kapag nagtatrabaho sa mga petsa ng kalendaryo.
Calendar.nextDate na may DateComponents(day: 1) ay nahahanap ang unang araw ng susunod na buwan. Awtomatikong tinutukoy ng Calendar ang bilang ng mga araw sa kasalukuyang buwan at lumipat sa susunod na buwan. Para sa mga paulit-ulit na notification, gamitin ang enumerateDates o Combine.Timer na may Calendar key.
func firstDayOfNextMonth(from date: Date) -> Date {
let calendar = Calendar.current
let comps = DateComponents(day: 1)
return calendar.nextDate(
after: date,
matching: comps,
matchingPolicy: .nextTime
)!
}
// Pagkalkula ng edad sa mga taon
func ageInYears(from birthDate: Date) -> Int {
let calendar = Calendar.current
let ageComponents = calendar.dateComponents(
[.year], from: birthDate, to: Date()
)
return ageComponents.year ?? 0
}
// Pagpapangkat ng mga kaganapan ayon sa taon at buwan
func groupEventsByMonth(_ events: [Event]) -> [String: [Event]] {
let calendar = Calendar.current
return Dictionary(grouping: events) { event in
let comps = calendar.dateComponents(
[.year, .month], from: event.date
)
return "\(comps.year!)-\(comps.month!)"
}
}
Pagkalkula ng edad sa pamamagitan ng Calendar.dateComponents([.year], from:to:) – ang tanging tamang paraan na isinasaalang-alang ang mga leap year. Ang pagkalkula na batay sa TimeInterval (segundo / 31536000) ay nagbibigay ng error para sa mga taong ipinanganak noong Pebrero 29. Tamang tinutukoy ng Calendar kung ang kaarawan ay nasa kasalukuyang taon at nagbabalik ng eksaktong edad.
Pagpapangkat ayon sa taon at buwan – isang karaniwang gawain para sa mga screen na may kasaysayan o kalendaryo. Ang DateComponents ay nagsisilbing key ng pagpapangkat: kinukuha mo ang taon at buwan mula sa petsa ng kaganapan, bumubuo ng string key, at pinagpangkat sa pamamagitan ng Dictionary(grouping:). Para sa pagpapakita, gamitin ang DateFormatter na may template na “LLLL yyyy” para sa lokalisadong pangalan ng buwan.
| Gawain | Paraan ng Calendar | Papel ng DateComponents |
|---|---|---|
| Unang araw ng buwan | nextDate(after:matching:) | day: 1 |
| Pagkalkula ng edad | dateComponents(from:to:) | [.year] mula sa pagkakaiba |
| Pagpapangkat ng petsa | dateComponents(_:from:) | year + month key |
| Paghahanap ng araw ng linggo | nextDate(after:matching:) | weekday: N |
Mga madalas itanong
Mga dahilan: hindi umiiral na petsa (31 Abril), magkasalungat na field (weekday=1 na may day=5), hindi wastong kumbinasyon ng mga field para sa napiling kalendaryo. Sinusubukan ng Calendar na i-interpret ang mga component sa sistema nito – kung imposible ang kumbinasyon, ang resulta ay nil. Palaging gamitin ang guard let o if let sa conversion.
Oo, sa pamamagitan ng operator ==. Ipinapatupad ng DateComponents ang Equatable, na inihahambing ang lahat ng field. Dalawang istraktura ay pantay kung ang lahat ng kanilang field ay pantay (ang nil == nil ay itinuturing na totoo). Para sa paghahambing ng bahagi lamang ng mga field – kunin ang parehong set sa pamamagitan ng Calendar.dateComponents.
Date – isang ganap na sandali sa oras na walang kaugnayan sa kalendaryo. DateComponents – isang set ng mga numerong nababasa ng tao (taon, buwan, araw) na may kahulugan lamang sa konteksto ng Calendar. Ang Date ay maaaring ihambing, ibawas, i-serialize sa ISO 8601. DateComponents – isang intermediate na representasyon para sa pakikipag-ugnayan sa kalendaryo.
Itakda lamang ang mga field na year at month, iwanan ang iba bilang nil. Sa conversion sa Date sa pamamagitan ng Calendar.date(from:), awtomatikong itatakda ng Calendar ang araw = 1, oras = 0, minuto = 0. Ang resulta – Date na tumutugma sa unang araw ng tinukoy na buwan sa hatinggabi.
DateComponents ay hindi nag-iimbak ng impormasyon tungkol sa time zone sa mga field – ang mga halaga ng field (taon, buwan, araw) mismo ay nakadepende sa timeZone kung saan sila nakuha. Ang mga component na “21 Hulyo 2026 14:00 MSK” at “21 Hulyo 2026 10:00 UTC” ay kumakatawan sa parehong Date, ngunit ang mga field ng DateComponents ay magkaiba.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din