Bibi's DevLog πŸ€“πŸŽ

[Swift] Date, DateFormatter λ³Έλ¬Έ

πŸ“±πŸŽ iOS/πŸ•Š Swift

[Swift] Date, DateFormatter

λΉ„λΉ„ bibi 2023. 6. 4. 23:07

이 글은 μ•„λž˜ 링크 μ›λ¬Έμ˜ λ²ˆμ—­λ³Έμž…λ‹ˆλ‹€.
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 ν•΄λ‹Ή μ—°λ„μ˜ λΆ„κΈ°
QQ 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λ₯Ό μ‚¬μš©ν•˜κΈ°λ§Œ
ν•œλ‹€λ©΄, μ‹œμŠ€ν…œμ΄ 우리λ₯Ό μœ„ν•΄ κ·Έ λ³΅μž‘μ„±λ“€μ„ 닀루어 μ€λ‹ˆλ‹€.