Bibi's DevLog π€π
[Swift] Date, DateFormatter λ³Έλ¬Έ
μ΄ κΈμ μλ λ§ν¬ μλ¬Έμ λ²μλ³Έμ λλ€.
https://iharishsuthar.github.io/posts/swift-date/
Swift Date
μΊλ¦°λλ time zoneμ λ 립μ μΈ μκ°μ νΉμ μ§μ .
Date & Time
Swiftμμ Date()
μ κ°μ μκ°μ λ¨μΌ μμ (a single point in time) μ μΊ‘μνν©λλ€. μ΄κ²μ νΉμ μκ°λ(time zone)λ λ¬λ ₯ μμ€ν
(calendarical system)μ λ
립μ μ
λλ€. μ΄λ₯Ό λ¬μ±νκΈ° μν΄, Date()
κ°μ January 1, 2001 at 00:00:00 UTC
λΌλ κΈ°μ€ λ μ§λ‘λΆν° μλμ μΈ μ€νμ
μΌλ‘ μ΄ μλ₯Ό μΈλ 64λΉνΈ λΆλμμμ μ«μλ‘μ μ μ₯λ©λλ€.
Date
νμ
μ Foundation νλ μμν¬μ μΌλΆμ
λλ€. λ°λΌμ iOS, watchOS, macOS, Catalyst, tvOSμμ λ μ§λ₯Ό λ€λ£° λ μ¬μ©λλ κΈ°λ³Έ νμ
μ
λλ€.
μ°Έκ³ : UTCλ Coordinated Universal Timeμ λνλ λλ€.
μ°μ νμ¬ λ μ§/μκ°μ λνλ΄λ λ³μλ₯Ό μμ±νκ³ , κ·Έ κ²°κ³Όλ₯Ό μΆλ ₯ν΄ λ΄ λλ€.
let now = Date()
print("Current date/time: \(now)")
μμ Swift μ½λλ₯Ό ν΅ν΄, κΈ°λ³Έ λ μ§/μκ° outputμ΄ UTC κΈ°μ€μ ISO8601-ν¬λ§· λ¬Έμμ΄λ‘ μΆλ ₯λλ€λ κ²μ μ μ μμ΅λλ€.
let timestamp = Date().timeIntervalSince1970
print("Number of seconds since ref date: \(timestamp)")
μμ Swiftμ½λλ κΈ°μ€ λ μ§(January 1, 1970 at 00:00:00 UTC
)λ‘λΆν° μλμ μΈ μ΄μ μλ₯Ό μΆλ ₯ν©λλ€.
μ°Έκ³ : timeIntervalSince1970 νλ‘νΌν°μ κ°μ, λ§μ½ date κ°μ²΄κ° κΈ°μ€ λ μ§(January 1, 1970 at 00:00:00 UTC) λ³΄λ€ λΉ λ₯΄λ©΄ μμλ₯Ό λ°νν©λλ€.
νμ§λ§ Swiftμ μ§μ§ λ€μν κΈ°λ₯λ€μ μ΄μ μ DateFormatter
, Locale
, κ·Έλ¦¬κ³ Calendar
λ₯Ό μ¬μ©νλ λ°μ λμ΅λλ€. μ΄κ²μ Swiftκ° μκ°λ(timezones), μ§μνλ λ μ§ ν¬λ§·(localized date formats), κ·Έλ¦¬κ³ λ¬λ ₯ μ°μ (μλ₯Ό λ€μ΄, 1λ¬ μ , 5μΌ ν λ±λ±)μ μ§μνλ λ°©λ²μ
λλ€.
DateFormatter λ λ μ§μ κ·Έκ²μ ν μ€νΈ νμ κ°μ λ³ν μμ μ ν μ μλλ‘ ν΄μ€λλ€.
Date
μμ String
μΌλ‘ λ³ννκΈ° - Date
μ Locale
ν¬λ§·ν
νκΈ°
Date
νμ
μ μ±μ μ μ λ€μκ² λ³΄μ¬μ£Όκ³ μΆμ λ, μ΄λ»κ² Date
λ₯Ό String
μΌλ‘ λ³νν μ μμ΅λκΉ?
let now = Date()
let dtFormatter = DateFormatter()
dtFormatter.dateStyle = .full
dtFormatter.timeStyle = .full
let formattedDateTime = dtFormatter.string(from: now)
print(formattedDateTime)
μμ Swift μ½λλ μ½μμ Monday, March 01, 2021 at 9:00:00 AM India Standard Time
μ μΆλ ₯νμ΅λλ€.
μ°λ¦¬λ dateStyle
κ³Ό timeStyle
νλ‘νΌν°λ₯Ό ν΅ν΄ λ€μν ννλ₯Ό μ νν μ μμ΅λλ€. λμ λͺ¨λ [DateFormatter.Style](http://DateFormatter.Style)
enumμΌλ‘λΆν° κ°μ κ°μ Έμ΅λλ€. μ°λ¦¬λ dateStyle
κ³Ό timeStyle
μ μ‘°ν©ν΄ λ μ§ λλ μκ°μ, λλ λ λ€ ν¬ν¨μν¬μ§ κ²°μ ν μ μμ΅λλ€. μλμ 리μ€νΈλ κ°κ°μ styleλ€μ΄ ν μ μλ κ²μ λνλ
λλ€:
DateFormatter.Style |
Date | Time |
---|---|---|
.none | (nothing!) | (nothing!) |
.short | 1/3/21 | 9:15 AM |
.medium | Mar 1, 2021 | 9:15:09 AM |
.long | March 1, 2021 | 9:15:09 AM GMT+5:30 |
.full | Monday, March 1, 2021 | 9:15:09 AM India Standard Time |
μ νν λ μ§ ν¬λ§·μ μμ€ν μ localeμ μμ‘΄ν©λλ€. localeμ΄ λ¬΄μμ λκΉ? μμ½νμλ©΄, localeμ μ¬μ©μμ μΈμ΄, μ§μ(λλ κ΅κ°), κ·Έλ¦¬κ³ μΆκ°μ μΈ μ€μ μ κ²°μ νλ νλΌλ―Έν°λ€μ μ§ν©μ λλ€.
μμ νλ en_IN
localeλ‘ μμ±λμμ΅λλ€. μ΄κ²μ λ μ§μ μκ° ν¬λ§·ν
μ μΈλ μμ΄ styleμ μ¬μ©νλ€λ κ²μ μλ―Έν©λλ€: AM/PM, μ/μΌ/μ° μΌλ‘. μ΄λ₯Ό μΈκ³μ λ€λ₯Έ κ΅κ°μ λΉκ΅ν΄ 보면, 24μκ°μ λ₯Ό μ¬μ©νκ³ , μΌ-μ-μ° νμμ
λλ€. μ localeμ΄ μ€μνμ§ μ μ μμ΅λλ€.
λΉμ μ μμ€ν μ localeμ΄ λ¬΄μμΈμ§ μκ³ μΆλ€λ©΄, μλ μ½λλ₯Ό μ€νν΄ κ²°κ³Όλ₯Ό νμΈνμμμ€.
let dtFormatter = DateFormatter()
print(dtFormatter.locale ?? "N/A")
DateFormatter
κ°μ²΄λ κΈ°λ³Έμ μΌλ‘ μμ΄ν°μ μμ€ν
localeμ μ¬μ©ν©λλ€. DateFormatter
κ°μ²΄λ₯Ό λ§λ€κ³ , dateStyle
κ³Ό timeStyle
μ μ¬μ©νκ³ , κ·Έ λ€μ string(from:)
μ μ¬μ©νλ€λ©΄, μ¬μ©μμ localeμ λ§λ λ μ§/μκ° ν
μ€νΈ νμμ λ§λ€μλ€λ κ²μ κ±°μ νμ ν μ μμ΅λλ€.
컀μ€ν λ μ§/μκ° ν¬λ§·μ λ§λ€κ³ μΆμ κ²½μ°μλ μλμ κ°μ΄ ν μ μμ΅λλ€:
let now = Date()
let dtFormatter = DateFormatter()
dtFormatter.locale = Locale(identifier: "en_GB")
dtFormatter.setLocalizedDateFormatFromTemplate("dd-MM-yyyy")
let formattedDateTime = dtFormatter.string(from: now)
print(formattedDateTime)
μμ Swift μ½λλ μκ΅μμ μΌλ°μ μΈ λ μ§ νμμ μΆλ ₯ν©λλ€. λμ¬(-
)λ₯Ό μ¬μ©ν΄ μΌ-μ-μ° μμΌλ‘ λνλ
λλ€.
String
μμ Date
λ‘ λ³ννκΈ° - Date
μ Timezone
νμ±νκΈ°
Stringμ Dateλ‘ λ³νν΄μΌ νλ λͺλͺ μ μ€μΌμ΄μ€κ° μμ΅λλ€:
- λ°μ΄ν°λ² μ΄μ€λ‘λΆν° ISO8601 Stringμ λ°κ³ , κ·Έκ²μ Swiftμμ Dateλ‘ λ³νν΄μΌ ν λ
- λ°μ΄ν°λ² μ΄μ€μμ Unix νμμ€ν¬νλ₯Ό μ μ₯νκ³ , κ·Έκ²μ Swiftμμ Dateλ‘ λ³νν΄μΌ ν λ
- μ°λ¦¬κ° λ€λ£¨λ λ°μ΄ν°κ° νΉμ λ μ§ ν¬λ§·μ κ°μ§κ³ μκ³ , κ·Έκ²μ Swiftμμ Dateλ‘ λ³νν΄μΌ ν λ
let dtFormatter = DateFormatter()
dtFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss Z"
if let dt = dtFormatter.date(from: "01-03-2021 09:15:07 +0530") {
print(dt)
}
μμ Swiftμ½λλ β2021-03-01 03:45:07 +0000βμ μ½μμ μΆλ ₯ν©λλ€.
μ°λ¦¬λ λ μ§ λ¬Έμμ΄κ³Ό μΆλ ₯λ Dateκ°μ²΄ μ¬μ΄μ λΆμΌμΉλ₯Ό νμΈν μ μμ΅λλ€. μ°λ¦¬λ 09:15:07μ΄λΌκ³ λͺ μνλλ°, Dateκ°μ²΄κ° μΆλ ₯λμ΄ λμ¬ λλ 03:45:07μ΄λΌλ κ°μ μ»μμ΅λλ€. κ·Έ μ΄μ κ° λ¬΄μμ λκΉ?
λ΄κ° μμ μ½λλ₯Ό μ€νν Macμ μΈλ νμ€μ(IST)λ‘ μ€μ λμ΄ μμ΅λλ€. μΈλ νμ€μλ UTC(Coordinated Universal Time)λ³΄λ€ 5μκ° λ°μ΄ λΉ λ¦
λλ€. +0000
μ λ³΄κ³ , μ°λ¦¬λ μΆλ ₯λ datetime κ°μ²΄κ° timezone offsetμ κ°μ§ μμμ νμΈν μ μμ΅λλ€ - μ¦ UTC μκ°μ
λλ€.
μ°λ¦¬λ Mac λλ iPhoneμ timezoneμ μλ μ½λλ‘ νμΈν μ μμ΅λλ€:
let timeZone = TimeZone.current
print(timeZone)
μμ Swift μ½λλ λ΄ Macμ μ½μμμ βAsia/Kolkata (current)βμ μΆλ ₯ν©λλ€.
Swiftμ ISO8601DateFormatter
ν΄λμ€λ ISO 8061 λ μ§/μκ° ν¬λ§·μ λνλ
λλ€. μ΄κ²μ timezoneμ΄λ localeλ‘λΆν° μ°λ¦¬λ₯Ό μμ λ‘κ² ν΄ μ€λλ€.
μ¬κΈ°μ ISO8601DateFormatter
λ₯Ό μ¬μ©ν΄ νμ¬ λ μ§/μκ°μ μΆλ ₯νλ λ°©λ²μ΄ μμ΅λλ€:
let now = Date()
let dtFormatter = ISO8601DateFormatter()
let formattedDateTime = dtFormatter.string(from: now)
print(formattedDateTime)
μμ Swift μ½λλ μ½μμ β2021-03-01T09:15:07Zβλ₯Ό μΆλ ₯ν©λλ€.
let dtFormatter = ISO8601DateFormatter()
if let dt = dtFormatter.date(from: "2021-03-01T09:15:07Z") {
print(dt)
}
μμ Swift μ½λλ ISO 8601 ν¬λ§·μ λ μ§/μκ° Stringμ Date
κ°μ²΄λ‘ λ³ννλ λ°©λ²μ μλ €μ€λλ€.
DateFormatter
μ ν¬λ§· μ΅μ
μλμ νλ DateFormatter
μμ μ°(Year)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
y | 2021 | ν¨λ©μ΄ μλ μ°λ |
yy | 21 | λ μ리μ μ°λ (νμν κ²½μ° 0μΌλ‘ ν¨λ©) |
yyyy | 2021 | λ€ μ리μ μ°λ (νμν κ²½μ° 0μΌλ‘ ν¨λ©) |
μλμ νλ DateFormatter
μμ λΆκΈ°(Quarter)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
Q | 4 | ν΄λΉ μ°λμ λΆκΈ° |
04 | ν΄λΉ μ°λμ λΆκΈ°. 0μΌλ‘ ν¨λ©μ λ£κΈ° μν λ μ¬μ© | |
QQQ | Q4 | "Q" λ₯Ό ν¬ν¨ν λΆκΈ° |
QQQQ | 4th quarter | quarter λΌλ λ¬Έμ ν¬ν¨ |
μλμ νλ DateFormatter
μμ μ(Month)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
M | 3 | μ«μλ‘ λ μ |
MM | 03 | μ«μλ‘ λ μ. 0μΌλ‘ ν¨λ©μ λ£κ³ μΆμ λ μ¬μ© |
MMM | Mar | μμ μΆμ½λ μ΄λ¦ |
MMMM | March | μμ μ 체 μ΄λ¦ |
MMMMM | M | μμ μΆμ½ μ΄λ¦ |
μλμ νλ DateFormatter
μμ μΌ(Day)/μμΌμ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
d | 1 | μμ μΌ |
dd | 01 | μμ μΌ. 0μΌλ‘ ν¨λ©μ λ£κ³ μΆμ λ μ¬μ© |
F | 1st Monday in March | μμμ κ·Έ μ£Όμ μμΌ |
E | Mon | κ·Έ μ£Όμ μμΌμ μ½μ |
EEEE | Monday | κ·Έ μ£Όμ μμΌμ μ 체 μ΄λ¦ |
EEEEE | M | κ·Έ μ£Όμ μμΌμ μΆμ½ |
EEEEEE | Mo | κ·Έ μ£Όμ μμΌμ μ½μ |
μλμ νλ DateFormatter
μμ μ(Hour)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
h | 9 | 12μκ°μ μκ° |
hh | 09 | 12μκ°μ μκ° (0μΌλ‘ ν¨λ© ν¬ν¨) |
H | 21 | 24μκ°μ μκ° |
HH | 21 | 24μκ°μ μκ° (0μΌλ‘ ν¨λ© ν¬ν¨) |
a | AM | 12μκ°μ νμμμμ μ€μ /μ€ν |
μλμ νλ DateFormatter
μμ λΆ(Minute)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
m | 15 | λΆ |
mm | 15 | λΆ (0μΌλ‘ ν¨λ© ν¬ν¨) |
μλμ νλ DateFormatter
μμ μ΄(Second)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
s | 7 | μ΄ |
ss | 07 | μ΄ (0μΌλ‘ ν¨λ© ν¬ν¨) |
SSS | 700 | λ°λ¦¬μ΄ |
μλμ νλ DateFormatter
μμ μκ°λ(Time zone)μ μ¬μ© κ°λ₯ν ν¬λ§· μ΅μ
μ λνλ
λλ€:
Characters | Example | Description |
---|---|---|
zzz | IST | time zoneμ 3κΈμ μ΄λ¦. μ΄λ¦μ΄ μλ €μ§μ§ μμ κ²½μ° GMC-08:00μΌλ‘ μ²λ¦¬ |
zzzz | India Standard Time | time zoneμ μ 체 μ΄λ¦. μ΄λ¦μ΄ μλ €μ§μ§ μμ κ²½μ° GMC-08:00μΌλ‘ μ²λ¦¬ |
ZZZZ | IST-05:30 | time zoneμ μ½μμ μ€νμ |
Z | +0530 | RFC 822 GMT ν¬λ§· |
ZZZZZ | +05:30 | ISO 8601 time zone ν¬λ§· |
DateComponents
λ‘ Date
λ₯Ό μμ±νκ³ κ³μ°νκΈ°
DateComponents
λ λ μ§λ₯Ό μμ±ν λλ§ μ μ©ν κ²μ΄ μλλλ€ - μ΄κ²μ κΈ°κ°μ νΉμ ν λλ λμμ΄ λ©λλ€. DateComponents
ꡬ쑰체λ νΉμ μμ μ μ μν μ μκ³ , μμ μ κΈ°κ°λ μ μν μ μμ΅λλ€.
DateComponents
λ λ μ§μ μ»΄ν¬λνΈ(components)λ₯Ό νμ₯ κ°λ₯νκ³ κ΅¬μ‘°νλ λ°©λ²μΌλ‘ μΊ‘μνν©λλ€. μ΄κ²μ νΉμ λ¬λ ₯μ λ μ§μ μκ°μ ꡬμ±νλ μμ μ»΄ν¬λνΈλ€μ μ 곡ν¨μΌλ‘μ¨ μ΄λ€ λ μ§λ₯Ό νΉμ νκΈ° μν΄ μ¬μ©λ©λλ€: μ, λΆ, μ΄, μΌ, μ, λ
λ±λ±. μ΄κ²μ λν μμ μ κΈ°κ°μ λνλΌ λλ μ°μ
λλ€ - μλ₯Ό λ€μ΄, 5μκ° 16λΆ. DateComponents
λ λͺ¨λ μ»΄ν¬λνΈ λΆλΆμ μ νμ μΌλ‘ μ μ κ°λ₯ν©λλ€.
let now = DateComponents(calendar: Calendar.current, year: 2021, month: 3, day: 1)
print(now)
μμ Swift μ½λλ βcalendar: gregorian (current) year: 2021 month: 3 day: 1 isLeapMonth: falseβ λ₯Ό μ½μμ μΆλ ₯ν©λλ€.
μ°λ¦¬λ λν νΉμ λ μ§μ λ λ§μ λ¨μλ₯Ό μΆκ°νκΈ° μν΄ κ°λ³ λ μ§ μ»΄ν¬λνΈλ€μ μ¬μ©ν μ μμ΅λλ€:
let now = DateComponents(calendar: Calendar.current, year: 2021, month: 3, day: 1)
if let dt = now.date,
let later = Calendar.current.date(byAdding: .month, value: 1, to: dt) {
print(later)
}
μμ Swift μ½λλ β2021-03-31 18:30:00 +0000βμ μ½μμ μΆλ ₯ν©λλ€. (κΈ°μ‘΄ λ μ§μ monthλ₯Ό 1κ° λν΄ 2021-03-01 μμ 2021-03-31μ΄ λ¨)
Calendar
μ DateComponents
λ₯Ό μ¬μ©ν¨μΌλ‘μ¨, νΉμ λ μ§μ μμκ³Ό λμ μ»μ μλ μμ΅λλ€.
let todayStartOfDay = Calendar.current.startOfDay(for: Date())
let todayEndOfDay = Calendar.current.date(byAdding: DateComponents(day: 1),
to: todayStartOfDay)?.addingTimeInterval(-1)
print(todayStartOfDay)
print(todayEndOfDay!)
μμ Swift μ½λλ νμ¬ λ μ§μ μμκ³Ό λμ μ½μμ μΆλ ₯ν©λλ€.
if let date: Date = DateComponents(calendar: Calendar.current, year: 2020, month: 3, day: 1).date {
let units = Array<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
let components = Calendar.current.dateComponents(Set(units), from: date, to: Date())
for unit in units {
guard let value = components.value(for: unit) else {
continue
}
if value > 0 {
print("\(value) \(unit)s ago")
}
}
}
μμ Swift μ½λλ β11 months agoβ, β27 days agoβ, β22 hours agoβ, β48 minutes agoβ, κ·Έλ¦¬κ³ β16 seconds agoβλ₯Ό μ½μμ μΆλ ₯ν©λλ€.
μ€μ Swift κ°λ°μμ Date
μ extension
μ μ¬μ©νλ μμ
extension Date {
init?(value: String, format: String) {
let dtFormatter = DateFormatter()
dtFormatter.dateFormat = format
if let date = dtFormatter.date(from: value) {
self = date
} else {
return nil
}
}
init?(value: String, format: String, timeZone: TimeZone? = nil) {
let dtFormatter = DateFormatter()
dtFormatter.dateFormat = format
if let value = timeZone {
dtFormatter.timeZone = value
}
if let date = dtFormatter.date(from: value) {
self = date
} else {
return nil
}
}
func to(format: String) -> String {
let dtFormatter = DateFormatter()
dtFormatter.dateFormat = format
return dtFormatter.string(from: self)
}
func to(format: String, timeZone: TimeZone) -> String {
let dtFormatter = DateFormatter()
dtFormatter.dateFormat = format
dtFormatter.timeZone = timeZone
return dtFormatter.string(from: self)
}
func to(dateStyle: DateFormatter.Style, relativeFormatting: Bool = false, timeZone: TimeZone? = nil) -> String {
let dtFormatter = DateFormatter()
dtFormatter.dateStyle = dateStyle
dtFormatter.doesRelativeDateFormatting = relativeFormatting
if let value = timeZone {
dtFormatter.timeZone = value
}
return dtFormatter.string(from: self)
}
}
if let dt = Date(value: "2021-01-01T08:35:00", format: "yyyy-MM-dd'T'HH:mm:ss", timeZone: TimeZone(abbreviation: "UTC")) {
print(dt.to(format: "dd-MM-yyyy", timeZone: (TimeZone(abbreviation: "IST") ?? TimeZone.current)))
}
μμ Swift μ½λλ β01-01-2021βμ μ½μμ μΆλ ₯ν©λλ€.
κ²°λ‘
Swiftμ Date
ꡬ쑰체λ Swiftλ‘ κ°λ°νλ©° λ μ§μ μκ°μ λ€λ€μΌ ν λ λ§€μ° μ μ©ν©λλ€. νμ§λ§, μ°λ¦¬κ° λ μ§ κ³μ°μ μν΄ μλ§μ APIλ₯Ό μ¬μ©νκΈ°λ§
νλ€λ©΄, μμ€ν
μ΄ μ°λ¦¬λ₯Ό μν΄ κ·Έ 볡μ‘μ±λ€μ λ€λ£¨μ΄ μ€λλ€.