iOS : UTC NSDate를 현지 시간대로 변환


139

NSDateObjective C 또는 Swift에서 UTC 를 현지 시간대 NSDate 로 어떻게 변환 합니까?


14
날짜에는 반드시 시간대가 있습니다.
Glenn Maynard

1
도움이된다면 온도를 생각하십시오. 화씨, 섭씨 또는 켈빈 어로 표현할 수 있습니다. 그러나 표현되는 정보 (분자의 평균 운동)는 본질적인 단위는 없지만 일부 단위로 표현할 때 우리에게만 의미가 있습니다.
소프트웨어가

7
@DaveDeLong NSDate에는 시간대가 있습니다. NSDate 클래스 참조에서 : "이 메소드는 절대 참조 날짜 (2001 년 1 월 1 일의 첫 번째 순간 인 GMT)에 상대적인 시간 값을 리턴합니다." GMT에 대한 명확하고 구체적인 참조에 유의하십시오.
Murray Sagal

3
동의하지 않습니다. NSDate에는 시간대가 없습니다. NSDate의 시간대를 지정하려면 NSCalendar 객체 또는 NSDateFormatter 객체를 사용합니다. 시간대가 지정되지 않은 문자열에서 NSDate를 생성하면 NSDate는 문자열이 GMT 시간이라고 가정합니다.
Rickster December

1
@MurraySagal 하나의 특정 메소드가 특정 시간대의 날짜에 상대적인 시간 값을 리턴한다고해서 NSDate가 날짜를 시간대에 상대적인 것으로 모델링한다는 의미는 아닙니다.
eremzeit

답변:


139
NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];

NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[df_utc setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];
[df_local setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];

// you can also use NSDateFormatter dateFromString to go the opposite way

문자열 매개 변수 형식화 테이블 :

https://waracle.com/iphone-nsdateformatter-date-formatting-table/

성능이 우선 순위 인 경우 사용을 고려할 수 있습니다. strftime

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/strftime.3.html


아마도 포맷터를 사용하여 문자열에서 날짜를 다시 읽을 수도 있습니다.
slf

34
@DaveDeLong은 날짜를 문자열로 표시하는 경우 모두 좋습니다. 그러나 날짜에 시간대 변환을 수행하는 데는 완전히 유효한 이유가 있습니다. 예를 들어 setDate :를 사용하여 UIDatePicker의 날짜를 기본값으로 설정하려는 경우. 웹 서비스에서 반환 한 날짜는 종종 UTC이지만 TV 목록과 같이 사용자의 현지 시간대 이벤트를 나타냅니다. 변환되지 않은 날짜를 전달하면 선택기에 잘못된 시간이 표시됩니다.
Christopher Pickslay

5
@GlennMaynard 동의하지 않습니다. 이 답변의 본질은 NSDate객체 로의 변환 이 필요 하지 않다는 것 입니다. 시간대에는 시간대가 없기 때문에 날짜를 만들 때가 아니라 형식을 지정할 때 시간대로 변환됩니다.
Dave DeLong

1
@GlennMaynard ... 단지 NSCalendarDate사용되지 않습니다.
Dave DeLong

1
또한 다음을 참고하십시오 : oleb.net/blog/2011/11/… "GMT! = UTC"
huggie

106

편집 내가 이것을 쓸 때 아마 더 나은 접근 방식 인 dateformatter를 사용해야한다는 것을 몰랐 slf습니다. 그래서 의 답변도 확인하십시오 .

UTC로 날짜를 반환하는 웹 서비스가 있습니다. 내가 사용하는 toLocalTime로컬 시간으로 변환하고 toGlobalTime필요한 경우 다시 변환 할 수 있습니다.

여기에서 내 대답을 얻었습니다.

https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/

@implementation NSDate(Utils)

-(NSDate *) toLocalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = [tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

-(NSDate *) toGlobalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = -[tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

@end

25
이러지 마 NSDates는 항상 UTC입니다. 이것은 단지 문제를 혼란스럽게합니다.
JeremyP

13
이것은 위에서 언급 한 "웹 서비스"사례에 매우 유용 할 수 있습니다. UTC로 이벤트를 저장하는 서버가 있고 클라이언트가 오늘 발생한 모든 이벤트를 요청하려고한다고 가정합니다. 이렇게하려면 클라이언트가 현재 날짜 (UTC / GMT)를 가져 와서 서버로 보내기 전에 시간대 오프셋으로 이동해야합니다.
Taylor Lafrinere

@JeremyP NSDates가 항상 GMT에 있다고 말하는 것이 더 정확합니다. NSDate 클래스 참조에서 : "이 메소드는 절대 참조 날짜 (2001 년 1 월 1 일의 첫 번째 순간 인 GMT)에 상대적인 시간 값을 리턴합니다." GMT에 대한 명확하고 구체적인 참조에 유의하십시오. GMT와 UTC에는 기술적 인 차이가 있지만 대부분의 사람들이 찾고있는 솔루션과는 관련이 없습니다.
Murray Sagal


2
@aryaxt 당신이 맞아요, 미안합니다. 나는 정답을 게시했을 때 어디에서 복사했는지 기억하지 못했습니다.
gyozo kudor

49

내가 찾은 가장 쉬운 방법은 다음과 같습니다.

NSDate *someDateInUTC = …;
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];

3
이 답변은 더 휴대하기 편합니다. 아래 답변은 시간대가 런타임에 고정되어 있다고 가정하지만 위의 답변은 플랫폼에서 시간대를 파생시킵니다.
bleeckerj

9
매우 도움이됩니다. secondsFromGMTForDate일광 절약 시간을 고려하려면 한 가지 추가 사항을 사용해야합니다.
Sergey Markelov를

1
이것은 DST 변경을 고려하지 않습니다.
lkraider

36

스위프트 3+ : UTC에서 로컬로, 로컬에서 UTC로

extension Date {

    // Convert UTC (or GMT) to local time
    func toLocalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

    // Convert local time to UTC (or GMT)
    func toGlobalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }
}

시간대를 UTC로 변환하거나 그 반대로 변환합니까?
Mitesh

26

현지 날짜와 시간을 원한다면 이 코드를 사용해보십시오 :-

NSString *localDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];

좋은 대답입니다! 이것은 현재 날짜를 잡습니다. 날짜 문자열을 사용하는 이것에 대한 적응은로 대체 [NSDate date]됩니다 [NSDate dateWithNaturalLanguageString:sMyDateString].
Volomike

7

UTC 날짜를 현지 날짜로 변환

-(NSString *)getLocalDateTimeFromUTC:(NSString *)strDate
{
    NSDateFormatter *dtFormat = [[NSDateFormatter alloc] init];
    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    NSDate *aDate = [dtFormat dateFromString:strDate];

    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone systemTimeZone]];

    return [dtFormat stringFromDate:aDate];
}

이와 같이 사용

NSString *localDate = [self getLocalDateTimeFromUTC:@"yourUTCDate"];

1
나를 위해 아니 작품은 내 로컬 시간 +3 및 +2이 코드 반환입니다
파디 Abuzant

6

여기에 입력은 문자열 currentUTCTime (형식 08/30/2012 11:11)이 GMT의 입력 시간을 시스템 설정 영역 시간으로 변환합니다.

//UTC time
NSDateFormatter *utcDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[utcDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[utcDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: 0]];

// utc format
NSDate *dateInUTC = [utcDateFormatter dateFromString: currentUTCTime];

// offset second
NSInteger seconds = [[NSTimeZone systemTimeZone] secondsFromGMT];

// format it and send
NSDateFormatter *localDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[localDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[localDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: seconds]];

// formatted string
NSString *localDate = [localDateFormatter stringFromDate: dateInUTC];
return localDate;

4
//This is basic way to get time of any GMT time.

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"hh:mm a"];  // 09:30 AM
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:1]]; // For GMT+1
NSString *time = [formatter stringFromDate:[NSDate date]];  // Current time


2

날짜 시간을 LocalTimeZone으로 변환하기 위해이 방법을 작성합니다.

-여기에서 (NSString *) TimeZone 매개 변수는 서버 시간대입니다.

-(NSString *)convertTimeIntoLocal:(NSString *)defaultTime :(NSString *)TimeZone
{
    NSDateFormatter *serverFormatter = [[NSDateFormatter alloc] init];
    [serverFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:TimeZone]];
    [serverFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *theDate = [serverFormatter dateFromString:defaultTime];
    NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
    [userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [userFormatter setTimeZone:[NSTimeZone localTimeZone]];
    NSString *dateConverted = [userFormatter stringFromDate:theDate];
    return dateConverted;
}

1

아무도 사용하고있는 것으로 보였다 없기 때문에 NSDateComponents, 나는에서 ...이 버전에서는 아무도 던질 것이라고 생각 NSDateFormatter사용된다, 따라서 어떤 문자열 구문 분석 및 NSDateGMT (UTC)의 시간 외부를 나타내는 데 사용되지 않습니다. 원본 NSDate은 변수에 i_date있습니다.

NSCalendar *anotherCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:i_anotherCalendar];
anotherCalendar.timeZone = [NSTimeZone timeZoneWithName:i_anotherTimeZone];

NSDateComponents *anotherComponents = [anotherCalendar components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond) fromDate:i_date];

// The following is just for checking   
anotherComponents.calendar = anotherCalendar; // anotherComponents.date is nil without this
NSDate *anotherDate = anotherComponents.date;

i_anotherCalendarNSCalendarIdentifierGregorian또는 다른 캘린더 일 수 있습니다 . 은 NSString허용 i_anotherTimeZone으로 획득 할 수 [NSTimeZone knownTimeZoneNames]있지만, anotherCalendar.timeZone[NSTimeZone defaultTimeZone]또는 [NSTimeZone localTimeZone]또는 [NSTimeZone systemTimeZone]전부.

실제로 anotherComponents새 시간대의 시간을 유지합니다. 당신이 알 수는 anotherDate동일 i_date는 그리니치 표준시 (UTC)에 시간을 보유하고 있기 때문에.


0

당신은 이것을 시도 할 수 있습니다 :

NSDate *currentDate = [[NSDate alloc] init];
NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"ZZZ"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];
NSMutableString *mu = [NSMutableString stringWithString:localDateString];
[mu insertString:@":" atIndex:3];
 NSString *strTimeZone = [NSString stringWithFormat:@"(GMT%@)%@",mu,timeZone.name];
 NSLog(@"%@",strTimeZone);

-1

UTC 시간을 현재 시간대로 변환하십시오.

통화 기능

NSLocale *locale = [NSLocale autoupdatingCurrentLocale];

NSString *myLanguageCode = [locale objectForKey: NSLocaleLanguageCode];
NSString *myCountryCode = [locale objectForKey: NSLocaleCountryCode];

NSString *rfc3339DateTimeString = @"2015-02-15 00:00:00"];
NSDate *myDateTime = (NSDate*)[_myCommonFunctions _ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString LanguageCode:myLanguageCode CountryCode:myCountryCode Formated:NO];

함수

-NSObject*)_ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString     LanguageCode:(NSString *)lgc CountryCode:(NSString *)ctc Formated:(BOOL) formated
{
    NSDateFormatter *sUserVisibleDateFormatter = nil;
    NSDateFormatter *sRFC3339DateFormatter = nil;

    NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];

    if (sRFC3339DateFormatter == nil)
    {
        sRFC3339DateFormatter = [[NSDateFormatter alloc] init];

        NSLocale *myPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:[NSString stringWithFormat:@"%@", timeZone]];

        [sRFC3339DateFormatter setLocale:myPOSIXLocale];
        [sRFC3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
        [sRFC3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    }

    // Convert the RFC 3339 date time string to an NSDate.
    NSDate *date = [sRFC3339DateFormatter dateFromString:rfc3339DateTimeString];

    if (formated == YES)
    {
        NSString *userVisibleDateTimeString;

        if (date != nil)
        {
            if (sUserVisibleDateFormatter == nil)
            {
                sUserVisibleDateFormatter = [[NSDateFormatter alloc] init];
                [sUserVisibleDateFormatter setDateStyle:NSDateFormatterMediumStyle];
                [sUserVisibleDateFormatter setTimeStyle:NSDateFormatterShortStyle];
            }

            // Convert the date object to a user-visible date string.
            userVisibleDateTimeString = [sUserVisibleDateFormatter stringFromDate:date];

            return (NSObject*)userVisibleDateTimeString;
        }
    }

    return (NSObject*)date;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.