버그 잡이

Swift - Date()는 왜 9시간 전의 날짜를 반환할까? 본문

카테고리 없음

Swift - Date()는 왜 9시간 전의 날짜를 반환할까?

버그잡이 2024. 7. 28. 16:05

 

문제의 발단


오늘 하루 동안 다시 보지 않기를 위해서

현재 시간에 1일을 더한 날짜를 저장하고

그 시간을 현재 시간과 비교하는 로직을 구현해야 했는데요.

관련해서 print문을 찍어보니 Date()가 9시간 전의 시간으로 출력되는 것을 확인했습니다.

 

// 현재 시간 (한국 시간 7월 28일 15시)
let currentDate = Date()
print("\(currentDate)")  // 2024-07-28 06:04:34 +0000

 

 

 

왜 그럴까요?

 

원인은 TimeZone 때문입니다.

Date()는 기본적으로 UTC 기준으로 생성됩니다.

UTC는 한국 시간 보다 9시간 전의 시간입니다.

 

사실 UTC 기준으로 Date를 저장하고 UTC 기준으로 Date를 비교하면 문제 없습니다.

24시간 기준으로 한다면 말이죠.

둘 다 UTC 기준으로 값을 저장하고 비교하면 됩니다.

let currentDate = Date()
print("\(currentDate)") // 2024-07-28 06:07:46 +0000


let oneDayLater = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)!
print("\(oneDayLater)") // 2024-07-29 06:07:46 +0000

 

하지만 오늘 하루 보지 않기의 기준이 24시간이 아닌 다음날 0시라면

TimeZone을 보다 유심히 봐야합니다.

 

DateFormatter로 가공하는 경우

 

아래 코드를 봅시다.

아래 코드는 한국 시간 기준 07-28 15:45분에 테스트 했을 경우 아래와 같이 22시가 나오는 것을 볼 수 있습니다.

var component = Calendar.current.dateComponents([.year, .month, .day], from: Date())
let dateWithoutTime = Calendar.current.date(from: component)!

let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: dateWithoutTime)

print(nextDate) // 2024-07-28 22:00:00 +0000

 

뭔가 TimeZone이 잘 안 맞는 것 같죠?

한국으로 TimeZone을 설정해보겠습니다.

var component = Calendar.current.dateComponents([.year, .month, .day], from: Date())
component.timeZone = TimeZone(abbreviation: "KST")
let dateWithoutTime = Calendar.current.date(from: component)!

let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: dateWithoutTime)

print(nextDate) // 2024-07-28 15:00:00 +0000

 

어라? 근데 28일 15시로 나오네요?

제가 기대했던 결과는 29일 00시 인데 말이죠.

 

여기서 다시 한번 봅시다. 결국 우리는 아래 로직을 체크하고 싶은건데요.

let isOver = Date() >=  startOfNextDay
// 28일 15시 >= 28일 15시
// true

 

Date()는 UTC 기준이라고 했죠?

그럼 한국시간 기준 29일 00시에 Date를 찍는다면 28일 15시가 나올겁니다.

네 맞습니다. 그래서 위에서 나온 결과가 28일 15시인 것입니다.

그래야 정확한 비교가 되니까요?

 

만약 UTC 기준으로 Timezone을 설정하면 어떻게 될까요?

 

var component = Calendar.current.dateComponents([.year, .month, .day], from: Date())
component.timeZone = TimeZone(abbreviation: "UTC")
let dateWithoutTime = Calendar.current.date(from: component)!

let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: dateWithoutTime)

print(nextDate)  // 2024-07-29 00:00:00 +0000

 

UTC는 표준이기 때문에 29일 00시로 나옵니다.

하지만 한국시간 기준 29일 1시에 Date를 찍는다면 Date는 28일 16시로 나오기 때문에 우리가 원하던 동작을 하지 않을 것입니다.

 

let isOver = Date() >=  startOfNextDay
// 28일 16시 >= 29일 00시
// false

 

 

그렇기 때문에 이런 경우 한국 시간을 timezone으로 잡고 비교해야합니다.

 

 

정리

 

1. Date()는 UTC 기준으로 한국 시간 보다 9시간 전의 값을 반환한다.

 

2. Date()로 비교하는 로직을 수행할때는 9시간 전 값이라는 것을 염두해두고 로직을 작성하자

 

3. formatter를 사용할때는 필요시 KST로 Timezone을 설정하자.

 

 

 

 

반응형
Comments