개발하면서 매우 중요한 타임존과 로케일에 대해 알아보겠습니다.
(틀린게 있다면 지적바랍니다)
이름에서도 알수 있듯이 타임존은 동일한 로컬 시간을 따르는 지역을 의미합니다.
그리니치 천문대를 기준으로 경도값에 의해 보통 달라지는 것이 일반적이지만, 국가와 해당 지역의 경계를 따르는 경우도 있습니다. (통신이 빈번한 지역이 같은 시간을 유지하는 것이 편리하기 때문이죠. 지도에서 보면 딱 경도로 떨어지진 않는 게 보이죠? 😀)
보통 국가별로 각자의 고유한 타임존을 사용하고 있으며, 미국이나 캐나다처럼 면적이 넓은 나라인 경우 지역별로 각지 다른 타임존을 사용하기도 합니다.
우리가 핸드폰에서 시간대를 설정할 수 있는데 이게 타임존이라고 보면 됩니다.
제 타임존은 서울이고, 서울은 UTC +09 입니다.
로케일은 사용자 인터페이스 에서 사용되는 언어, 지역 설정, 출력 형식 등을 정의하는 문자열입니다.
핸드폰에서 타임존과 마찬가지로 로케일을 설정할 수 있는데요.
언어는 한국어를 사용할거고 지역은 대한민국입니다. 즉, ko_KR 을 이용한다는 것이죠.
밑에 출력형식(포맷) 예를 보여주네요.
우리나라에서는 날짜를 표현할 때는 0000년 00월 00일 0요일,
화폐단위는 ₩ 을 쓰니 이에 맞게 포맷을 보여주고 있습니다.
날짜와 시간의 표기에 관한 국제 표준 규격입니다. 날짜와 시간을 표현할 때 나라마다 표시형식이 다르다보니 국제 표준화 기구(ISO)에서 정한 날짜 및 시간 표시 형식입니다.
1) ISO8601에서 날짜의 표기는 그레고리력을 따릅니다. (아래와 같은 표기를 따른다는 말입니다.)
2) 시간의 표기에는 쌍점을 쓴 hh:mm:ss (확장 형식) 또는 hhmmss (기본 형식)을 사용합니다.
hh는 시를 나타내며 00부터 24까지의 값을 가지고, mm은 분으로 00부터 59까지의 값을, ss는 초로 00부터 59까지의 값을 가집니다.
날짜와 시간을 함께 표기할 때에는, 날짜와 시간 사이에 T를 넣어 표기합니다.
예) 1981-02-22T09:00:00 : 1981년 2월 22일 09:00:00
3) 시간대(타임존)를 표기할때에는 Z또는 +/- 기호를 사용합니다.
UTC 시간대에서는 시각 뒤에 Z를 붙입니다.
예) 1981-02-22T09:00Z 또는 19810222T0900Z : UTC 시간대에서의 1981년 2월 22일 오전 9시 00초
UTC 외의 시간대에서는 오프셋으로 시각 뒤에 +- hh:mm, +- hhmm, +- hh 를 덧붙여 씁니다.
예) 1981-02-22T09:00:00+09:00 : UTC+9 시간대에서의 1981년 2월 22일 오전 9시 00초
+가 붙으면, UTC의 시각보다 더 "빠르다"다는 의미입니다. 반대로 -는 느리다는 것을 의미합니다. (앞에서 우리나라는 UTC+9 라고 했죠?)
예를 들어, 1981-02-22T09:00+09:00 는 1981-02-22T00:00Z 와 동일하다.
즉, UTC+9 시간대에서는 오전 9시이지만, UTC 시간대에서는 오전 0시이다.
이 외의 자세한 내용은 위키피디아의 ISO8601을 읽어보시길 바랍니다. (한번쯤은 읽어보세용)
앞서 설명한 ISO8601은 ISO에서 정한 규격일 뿐이지 인터넷과 아무 상관이 없습니다. 인터넷 상에서 ISO8601을 사용하기 위해서는 RFC 3339를 이용해 표현합니다.
즉, ISO8601을 인터넷 프로토콜로 어떻게 다룰 것인지를 규정한 것이 RFC 3339입니다.
개념적으로 거의 비슷해서 혼용해서 사용하긴 하지만 약간의 차이점은 있습니다.
예를 들면, RFC 3339에서는 'T'의 생략을 허용하지 않고, 날짜와 시간 사이의 공백을 허용합니다.
먼저 GMT(그리니치 표준시)는 그리니치 천문대를 기준으로 하는 표준시를 의미합니다.
앞서 계속 UTC +9 와 같이 UTC 라는게 계속 나왔는데요.
UTC(협정 세계표준시)는 1972년 1월 1일부터 시행된 국제 표준시를 의미합니다. UTC는 국제원자시와 윤초 보정을 기반으로 표준화된 것입니다.
UTC는 그리니치 평균시(GMT)에 기반하므로 GMT로도 불리기도 하는데, UTC와 GMT는 초의 소숫점 단위에서만 차이가 나기 때문에 일상에서는 혼용되기도 합니다. 기술적인 표기에서는 UTC가 사용됩니다.
즉, UTC는 GMT 기반이나 윤초보정을 한 것이고, GMT는 윤초보정 안한 것입니다.
미국에서는 Daylight saving time(DST), 영국에서는 써머타임이라고 부르는 이 개념은 하절기에 표준시를 원래 시간보다 한 시간 앞당긴 시간을 쓰는 것을 말합니다.
00시에서 01시 대신에 바로 02시로 바꿉니다. 예로 들면 8시는 9시로 바뀌게 되고, 2시는 3시로 바뀌게 됩니다.
써머타임을 사용하는 국가들이 있기 때문에 글로벌 서비스를 한다면 개발 할 때 이 부분도 고려해야겠죠?
각 개발언어마다 처리하는 방법이 있을건데요. swift 에서는 isDaylightSavingTime로 처리를 할 수 있겠네요 :)
위 코드를 간략히 설명하자면 Locale은 "en_US_POSIX"로 지정해주었고, dateFormat 은 우리가 앞서 살펴보았던 RFC 3339 를 적용하였습니다.
timeZone은 오프셋을 0으로 설정한 코드입니다. (0으로 설정했으니 표준시인 UTC를 사용한다는 말이겠네요.)
중요한 점은 macOS 10.12 이상 또는 iOS 10 이상에서 ISO 8601 날짜 표현으로 작업할 때 ISO8601DateFormatter 클래스를 사용하라고 되어있네요.
Date Format에 관한 많은 예제를 보면서 왜 Locale을 "en_US_POSIX" 를 사용하지?
라는 의문이 있었는데요.
사용하는 데엔 이유가 있었습니다..
고정 형식 날짜로 작업해야 하는 경우 Date Formatter의 Locale을 고정 형식에 적합한 것으로 설정해야 하는데요. 이럴 때 선택하는 Locale이 "en_US_POSIX" 입니다 !
이 로케일은 사용자 및 시스템 기본 설정에 관계없이 미국 영어 결과를 생성하도록 특별히 설계된 로케일입니다.
우리가 핸드폰에서 12시간 방식을 쓸건지 24시간 쓸건지 선택하잖아요? "en_US_POSIX"를 사용하면 핸드폰에서 12시간 방식을 쓸거라고 선택했더라도 24시간 형식을 얻을 수 있는 겁니다!
그리고 우리는 이러한 형식을 서버에 보내줘야 하죠! 그리고 대부분 서버로 보내는 날짜가 영어로 되어 있기 때문에 Locale을 "en_US_POSIX"를 쓰는 것이었습니다..
한가지 예를 더 들어볼까요? 일본에서는 연호라는 걸 사용하는데요. 아이폰에서 일본력을 쓸 수 있도록 선택할 수 있습니다. 만약 사용자가 일본력을 쓰도록 설정해놨으면 Date Format 할 때 에러가 발생할 수도 있겠죠. 이를 방지하기 위해서는 "en_US_POSIX"를 Locale로 해서 사용자의 설정에 구애 받지 않는 고정 형식을 쓸 수 있겠습니다.
"en_US_POSIX"는 또한 시간에 따라 변하지 않습니다(미국이 미래의 어느 시점에서 날짜 형식을 변경하는 경우 "en_US"는 새 동작을 반영하도록 변경되지만 "en_US_POSIX"는 변경되지 않음), 그리고 컴퓨터 간에("en_US_POSIX"는 OS X에서와 마찬가지로 iOS에서도 동일하게 작동하며 다른 플랫폼에서도 작동합니다.
다른 플랫폼에서도 작동한다는 말이 무엇이냐면, 유닉스와 리눅스와 같은 POSIX 기반의 시스템에서는 같은 형식을 공유하고 있다는 말입니다. 애플의 맥OS를 비롯한 Darwin 계열 운영체제들도 POSIX 호환이 되기 때문에 같은 형식의 로케일 문자열을 사용한다는 것입니다.
iOS 또는 Swift 에 관심이 있으시다면 읽어보시길 권장드립니다.
Dates in Swift
DateFormatter
NSDateFormatter and Internet Dates
참고 )
위키피디아
나무위키
로케일 이란
UTC 와 표기법, 그리고 ISO 8601, RFC 3339 표준
정말 큰 도움이 되었습니다! 좋은 글 감사합니다 👍🏻