2017-02-15 2 views
0

Мы получили проблему в нашем существующем приложении iOS, разработанном с использованием Objective-c.RFC 3339 date formatters - почему дата вывода сдвинута на один день?

выпуск: дата выхода сдвигается на один день назад, только для зоны времени 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; 
} 

Input DateString = 2017-01-16T00: 00: 00-06: 00

UTC Формат: дата = 2017-01-16 06:00:00 +0000

DateString выходных = 2017-01-15

Пожалуйста, помогите нам исправить проблему.

+0

Это не так. Ожидается то, что вы видите. И дело не только в PST (западное побережье США). Он покажет 15 января для любого устройства с смещением часового пояса больше -6 (далее на запад). – rmaddy

+0

2017-01-16T00: 00: 00-06: 00 (например, полночь утром 16 января в Чикаго), было 10 часов 15 января в Лос-Анджелесе. Таким образом, ваш вывод имеет смысл. Вопрос в том, какова ваша более широкая задача. Вы говорите, что вам все равно, когда придет что-то, только в тот день, когда он был там? Тогда вы, вероятно, не должны включать временную часть в свои строки даты вообще. Отступив назад, вы должны отредактировать свой вопрос, чтобы описать более широкую задачу дизайна, и мы можем посоветовать, как его решить. – 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

Я не проголосовал, но, вероятно, был проголосован, потому что это не решает вопрос OPs. У него есть строка 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.

Смежные вопросы