2017-02-15 8 views
0

Objective-c를 사용하여 개발 한 기존 iOS 응용 프로그램에서 문제가 발생했습니다.RFC 3339 날짜 포맷터 - 출력 날짜가 하루 씩 이동 한 이유는 무엇입니까?

문제 : 출력 날짜가 PST 시간대에만 1 일 뒤로 이동합니다.

날짜를 짧은 형식으로 변환하기위한 코드를 작성했습니다.

-(NSString *)getDisplayDateFormat:(NSString *)dateString 
{ 
    NSLocale *enUSPOSIXLocale; 
    NSDateFormatter *inputformatter = [[NSDateFormatter alloc] init]; 
    enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
    [inputformatter setLocale:enUSPOSIXLocale]; 
    inputformatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; 
    [inputformatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssSSSZZZZ"]; 
    NSDate *date= [inputformatter dateFromString:dateString]; 
    NSDateFormatter *OutPutformatter = [[NSDateFormatter alloc] init]; 
    [OutPutformatter setDateFormat:@"yyyy-MM-dd"]; 
    NSString *dispalyDateString = [OutPutformatter stringFromDate:date]; 
    return dispalyDateString; 
} 

입력 날짜 열 = 2017-01-16T00 : 00 : 00-06 : 00

UTC 형식 : 날짜 = 2017년 1월 16일 6시 0분 0초 0000

출력 날짜 열 = 2017-01-15

문제를 해결하는 데 도움을주세요.

+0

잘못이 아닙니다. 당신이보고있는 것이 기대됩니다. 그리고 그것은 PST (미국 서부 해안)에만있는 것이 아닙니다. -6보다 큰 시간대 오프셋 (offset)을 가진 모든 장치에 대해 1 월 15 일을 표시합니다 (추가 서쪽). – rmaddy

+0

2017-01-16T00 : 00 : 00-06 : 00 (예 : 시카고에서 1 월 16 일 자정). 1 월 15 일 로스 앤젤레스에서 오후 10시에 개최되었습니다. 따라서 귀하의 결과물은 의미가 있습니다. 문제는 더 넓은 목적이 무엇인가하는 것입니다. 당신은 무슨 일이 일어 났는지 상관하지 않는다고 말하고 있습니까? 그렇다면 날짜 문자열에 시간 부분을 포함하면 안됩니다. 뒤로 물러나서 질문을 편집하여보다 광범위한 디자인 목표를 설명해야하며이를 해결하는 방법을 조언 할 수 있습니다. – Rob

+0

설명해 주셔서 감사합니다. 서버에서 "2017-01-16T00 : 00 : 00-06 : 00"날짜가 표시되며 2017-01-16로 변환해야합니다. 친절하게 제안하십시오. – Raj

답변

-1

아무 때나 실제로 어떤 시간을 알고 있습니까? 이 시도 :

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSString *d = @"2017-01-16T00:00:00-06:00"; 

    NSArray *abbrevs = @[@"UTC", @"EDT", @"PST", @"HST", @"JST"]; 

    NSArray *names = @[@"UTC", @"America/New York", @"America/Los Angeles", @"Pacific/Honolulu", @"Asia/Japan"]; 

    for (int n = 0; n < abbrevs.count; n++) { 

     NSString *na = abbrevs[n]; 
     NSString *nm = names[n]; 
     NSString *r = [self getDisplayDateFormat:d inTimeZone:[NSTimeZone timeZoneWithAbbreviation:na]]; 

     NSLog(@"Time is %@ in %@ (%@)", r, nm, na); 

    } 
} 

-(NSString *)getDisplayDateFormat:(NSString *)dateString inTimeZone:(NSTimeZone*)tz 
{ 
    NSLocale *enUSPOSIXLocale; 
    NSDateFormatter *inputformatter = [[NSDateFormatter alloc] init]; 
    enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
    [inputformatter setLocale:enUSPOSIXLocale]; 
    inputformatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; 
    [inputformatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssSSSZZZZ"]; 
    NSDate *date= [inputformatter dateFromString:dateString]; 
    NSDateFormatter *OutPutformatter = [[NSDateFormatter alloc] init]; 
    //[OutPutformatter setDateFormat:@"yyyy-MM-dd"]; 
    // show the time also, for clarity 
    [OutPutformatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
    // This is important! You must set the TimeZone for the output string - otherwise you get the local/device timezone 
    OutPutformatter.timeZone = tz; 
    NSString *dispalyDateString = [OutPutformatter stringFromDate:date]; 
    return dispalyDateString; 
} 
+0

그래서, 저는 여기에 글을 게시하는 것에 상대적으로 새로운 ... 궁금한 이유를 물어 봅니다. – DonMag

+0

나는 다운 투표하지는 않았지만 이것이 OP 질문를 해결하지 못했기 때문에 아마도 투표를 중단했을 것입니다. 그는 ISO8601 문자열을 가지고 있으며 날짜 구성 요소가 무엇인지 알고 싶어합니다. 그는 현지 시간대로 날짜를보고 싶지 않습니다. 원래의 코드에 문제가 있습니다. 여기서 간단히 재현했습니다. – Rob

+0

의견을 보내 주셔서 감사합니다. 나는 실제 * 날짜 *와 날짜가 * 제시된 방식 인 OP를 두 개의 독립된 것으로 전달하려고했습니다. 아마도 내가 실증적 코드를 제공하기보다는 평이한 언어로 설명했다면 더 나은 접근 방법이었을 것이다. – DonMag

0

을 당신이 날짜 문자열의 날짜 부분의 문자열 표현을 캡처 할 경우에 관계없이 사용하는 로컬 시간대는 자신의 다른 여부의 가장 쉬운 방법이 모두를 무시하는 것입니다 시간대 및 시간대 정보를 입력하고 날짜 부분 만 잡으십시오. 가장 간단한 형태로, 당신이 할 수 있습니다 : 당신이 정말로 (경우에 사용자가 태양력을 사용하지 않는) 장치의 로케일로 변환하고자하는 경우,

- (NSString *)getDisplayDateFormat:(NSString *)dateString { 
    return [dateString substringToIndex:10]; 
} 

을 또는, 당신은 할 것 :

- (NSString *)getDisplayDateFormat:(NSString *)dateString { 
    NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init]; 
    NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
    [inputFormatter setLocale:enUSPOSIXLocale]; 
    [inputFormatter setDateFormat:@"yyyy-MM-dd"]; 
    NSDate *date = [inputFormatter dateFromString:[dateString substringToIndex:10]]; 
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; 
    [outputFormatter setDateFormat:@"yyyy-MM-dd"]; 
    return [outputFormatter stringFromDate:date]; 
} 

그런 다음 다시 사용자의 캘린더로 변환하려는 경우 yyyy-MM-dd 형식을 사용하지 않고 일부 사용자에게 친숙한 dateStyle을 사용합니다.