Как правильно преобразовать объект даты с отдельным часовым поясом в NSDate? - PullRequest
0 голосов
/ 01 декабря 2018

Мое приложение получает данные из веб-службы (PHP), которая предоставляет даты в следующем формате:

        endDate =             {
            date = "2020-09-30 16:16:08.000000";
            timezone = "-04:00";
            "timezone_type" = 1;
        };

Это код, который я использовал для преобразования в NSDate, и он работает, насколько яможет сказать, в каждом тесте, но он не работает на нескольких устройствах в соответствии с пользовательскими отчетами и журналами отладки.

Обратите внимание, что правильное преобразование этой даты определяет, разблокировано ли содержимое в приложении, поэтому в случае сбоя клиенты связываются с нами по этому поводу.

             NSDictionary* dateDict = [responseDict objectForKey:@"endDate"];
             NSString* strEndDate = [dateDict objectForKey:@"date"];
             NSString* strOffset = [dateDict objectForKey:@"timezone"];

             NSTimeInterval zoneSeconds = 0;
             NSRange rng = [strOffset rangeOfString:@":"];
             if (rng.location != NSNotFound && rng.location >= 1)
             {
                 NSString* hoursOnly = [strOffset substringToIndex:rng.location];   
                 NSInteger offsetValue = [hoursOnly integerValue];
                 zoneSeconds = (3600 * offsetValue);
             }

             NSDateFormatter* df = [[NSDateFormatter alloc] init];
             NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:zoneSeconds];
             [df setTimeZone:timeZone];
             [df setDateFormat:@"yyyy-MM-dd HH:mm:ss.000000"];

             NSDate* newEndDate = [df dateFromString:strEndDate];

Однако журналы отладки от нескольких пользователей показывают, что вызов dateFromString завершился неудачно и возвращает ноль.

У нас есть один пользователь, у которого есть 2 устройства iOS и которые используют одну и ту же учетную запись (ту же дату), приложение работает, как ожидалось, на одном из них, но не работает на другом.Тот же Apple ID, оба работают под управлением iOS12.Журналы отладки показывают, что оба устройства получили одинаковую дату с сервера, но одному из них не удалось преобразовать дату из строки в NSDate.

Мое предположение до сих пор состоит в том, что на устройстве (ах) имеется какая-то настройка или конфигурация, в которой происходит сбой, которая отличается.Но я весь день возился с настройками календаря и даты и не могу этого сделать.Я знаю, что у данного пользователя оба устройства настроены на один и тот же часовой пояс.

Есть ли лучший, более правильный способ преобразования даты, который мог бы быть более надежным?

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Вопрос на самом деле был похож на ( Каков наилучший способ справиться с локалью NSDateFormatter "feechur"? ), как было предложено изначально, но это был другой вопрос ( NSDateFormatter не удаетсявернуть дату и время для британского региона с 12-часовыми часами, установленными ), что действительно заставило его щелкнуть меня - это британский регион с 12-часовыми часами, который приводит к сбою кода, но dateFormatter легко исправить, просто установив для локали значение"un_US_POSIX", как было предложено в ответе на этот вопрос (он также был предложен ниже vadian - однако я не пробовал его код).Спасибо всем, кто внес намеки и приводит!

0 голосов
/ 01 декабря 2018

При использовании произвольного формата даты настоятельно рекомендуется установить locale средства форматирования даты на фиксированное значение en_US_POSIX.

Вместо того, чтобы вычислять секунды из GMT itможет быть более эффективно обрезать миллисекунды с помощью регулярного выражения, добавить строку часового пояса и использовать соответствующий формат даты.

Этот код использует более современный синтаксис для установки свойств средства форматирования даты с точечной нотацией и подписью литерального ключа словаря

NSDictionary *dateDict = responseDict[@"endDate"];
NSString *strEndDate = dateDict[@"date"];
NSString *strTimeZone = dateDict[@"timezone"];
NSString *dateWithoutMilliseconds = [strEndDate stringByReplacingOccurrencesOfString:@"\\.\\d+" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, strEndDate.length)];
NSString *dateWithTimeZone = [NSString stringWithFormat:@"%@%@", dateWithoutMilliseconds, strTimeZone];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
df.dateFormat = @"yyyy-MM-dd HH:mm:ssZZZZZ"];
NSDate *newEndDate = [df dateFromString:dateWithTimeZone];
...