2017-02-15 94 views
0

我們在使用Objective-c開發的現有iOS應用程序中收到了一個問題。RFC 3339日期格式化程序 - 爲什麼輸出日期偏移了一天?

問題:僅在PST時區內,輸出日期向後移動一天。

我們已經寫下如下代碼來將日期轉換爲短格式。

-(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; 
} 

輸入dateString = 2017-01-16T00:00:00-06:00

UTC格式:日期= 2017年1月16日六時○○分00秒0000

輸出dateString = 2017-01-15

請幫助我們解決問題。

+0

這沒有錯。你所看到的是預期的。這不僅僅是PST(美國西海岸)。它將在1月15日顯示時區偏移大於-6(更西)的任何設備。 – 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

所以,我在SO上張貼這個相對較新的...好奇爲什麼有人會對這個答案投票呢? – 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