도래울

NSDate와 NSDateFormatter 사용하기 본문

개발/iOS

NSDate와 NSDateFormatter 사용하기

도래울 2016. 7. 8. 15:06

날짜와 시간을 다루는 것을 정말 중요하고 어려운 일이다. 날짜와 시간이 복잡한 이유는 여러 가지가 있다. 세상이 너무나 커서 같은 시간을 사용할 수 없기 때문이기도 하고 종교적이 이유에서 문화마다 다른 달력을 사용하고 있는 것도 복잡한 이유이다.

이 문서에는 iOS에서 날짜와 시간을 다루는 기본 클래스인 NSDate과 NSDate를 문자열로 혹은 문자열을 NSDate로 변환시켜주는 NSDateFormatter 클래스를 알아 볼 것이다.

간단한 코드

// date 클래스 생성
NSDate *now = [NSDate date];

// data formatter 생성 & 설정
// formatter를 중복해서 생성하지 않도록 static 으로 
// 설정 했다. 
static NSDateFormatter *defaultFormatter = nil;

if ( defaultFormatter == nil ) {
    // short style의 데이트 포멧을 사용한다
    defaultFormatter.dateStyle = NSDateFormatterShortStyle;
    defaultFormatter.timeStyle = NSDateFormatterShortStyle;
}

// 현재 시간을 시간 문자열로 변환
NSString *dateString = [defaultFormatter stringFromDate:now];
// 날짜-시간 문자열을 다시 NSDate로 변환
NSDate   *parsedDate = [defaultFormatter dateFromString:dateString];

NSLog(@"dataString : %@", dateString);
NSLog(@"parsedData : %@", parsedDate);

위 코드는 NSDate을 생성하고 생성된 NSDate를 사람들이 볼 수 있는 문자열 변환하는 코드이다. 그리고 문자열을 NSDate로 만드는 방법도 보여주고 있다.

iOS에서는 날짜와 시간을 나타내는 ( 내부적으로는 double 타입으로 된 값을 사용 ) NSDate를 문자열로 변환하기 위해서 NSDateFormatter를 사용한다. 변환를 어떤 식으로 할지는 dateStyle와 timeStyle값으로 결정을 한다.

// “11/23/37or3:30pm”.
dateFormatter.dateStyle = NSDateFormatterShortStyle;
dateFormatter.timeStyle = NSDateFormatterShortStyle;

//Nov 23, 1937or3:30pm”.
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
dateFormatter.timeStyle = NSDateFormatterMediumStyle;

//November 23, 1937or3:30:32pm”.
dateFormatter.dateStyle = NSDateFormatterLongStyle;
dateFormatter.timeStyle = NSDateFormatterLongStyle;

//Tuesday, April 12, 1952 ADor3:30:42pm PST”.
dateFormatter.dateStyle = NSDateFormatterFullStyle;
dateFormatter.timeStyle = NSDateFormatterFullStyle;

위 예제처럼 dateStyle와 timeStyle을 결정할 수 있다. NSDateFormatterNoneStyle를 지정하면 아무 문자열도 표시되지 않는다는 의미이다.

날짜와 시간을 좀 더 자유롭게 표현

앞에서 살펴 본것 처럼 미리 정해진 형태가 아닌 좀더 자유롭게 원하는 형식으로 출력을 하고 싶다면 다음과 같은 방법을 이용할 수 있다.

NSDate *now = [NSDate date];

// RFC 3339 date format
static NSDateFormatter *rfc3339DateFormatter = nil;
if ( rfc3339DateFormatter == nil ) {
    rfc3339DateFormatter = [[NSDateFormatter alloc] init];
    NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    [rfc3339DateFormatter setLocale:enUSPOSIXLocale];
    [rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    [rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
}

NSString *rfc3339DateTimeString = [rfc3339DateFormatter stringFromDate:now];
NSDate   *rfc3339DateTimeStringDate = [rfc3339DateFormatter dateFromString:rfc3339DateTimeString];

NSLog(@"rfc3339   : %@", rfc3339DateTimeString);
NSLog(@"converted : %@", rfc3339DateTimeStringDate);

NSDateFormatter의 setDataFormat 메소드를 사용해서 원하는 형식으로 변환을 할 수 있다. 위 예제는 RFC 3339 방식으로 표현을 한 것이다.

날짜 시간 표현 방식을 정할때는 일정한 규칙이 있는데 iOS의 NSDateFormatter는 Unicode.org에서 날짜 형태를 정의하는 방식을 사용하고 있다.

Unicode.org의 Date Format Patterns

이 형식을 이용하면 다음과 같은 방식으로 날짜와 시간을 나타낼 수 있다.

형식
yyyy-MM-dd HH:mm:ss2012–12–11 18:05:05
EEEE dd MMMM, yyyyTuesday 11 December, 2012
h:mm a, zzz9:05 AM, GMT
yyyy.MM.dd G ‘at’ HH:mm:ss zzz1996.07.10 AD at 15:08:56 PDT
EEE, MMM d, ’’yyWed, July 10, ’96
h:mm a12:08 PM
hh ‘o’‘clock’ a, zzzz12 o’clock PM, Pacific Daylight Time
K:mm a, z0:00 PM, PST
yyyyy.MMMM.dd GGG hh:mm aaa01996.July.10 AD 12:08 PM

<표 1> 날째 포멧 예제 ( 출처 : unicode.org )

위와 같이 NSDate 객체를 NSDateFormatter를 사용해서 상호 변환 할 수 있다.

NSDateFormatter를 이용해서 변환을 할때의 또 다른 요소로 locale이 있다. 이 예제의 모든 예제는 기본 로케일을 en_UR_POSIX로 고정해서 영어로 시간과 날짜로 표시되었지만 다른 나라의 로케일이라면 그에 해당하는 문자열로 표현될 것이다. 간혹 로케일을 고정하고 싶다면 local을 직접 지정해야 한다.

참고

Comments