iPhone/Objective-C — Помощь с проблемами NSDateComponents и NSCalendar с зарубежными часовыми поясами

Я использую приведенный ниже метод Utility для отображения прошедших секунд, минут, часов и т. Д.

например, 1 час назад

У меня есть друг за границей, тестирующий наше приложение для iPhone, и каждый раз, когда они отправляют элемент, метод всегда возвращает «1 час назад», потому что Новая Зеландия опережает на 2 часа, а сервер находится в Австралии, что, очевидно, отстает на 2 часа.

Это только до тех пор, пока наш SQL Server не догонит; когда дата элемента начинает рассчитываться правильно.

Просто интересно, как я могу справиться с разницей в часовых поясах и изменить мой метод Utility для работы в глобальном масштабе? Пожалуйста, не стесняйтесь помочь изменить метод, чтобы это было не так много строк кода (если вам действительно скучно - и великодушно).

Заранее спасибо.

+ (NSString *)elapsedTime:(NSDate *)date {
    NSUInteger desiredComponents = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

    NSDateComponents *elapsedTimeUnits = [[NSCalendar currentCalendar] components:desiredComponents
                                                                         fromDate:date
                                                                           toDate:[NSDate date]
                                                                          options:0];

    // Format to be used to generate string to display.
    NSString *scannedFormat = @"%d %@ ago";
    NSInteger number = 0;
    NSString *unit;

    if ([elapsedTimeUnits year] > 0) {
        number = [elapsedTimeUnits year];
        unit = [NSString stringWithFormat:@"year"];
    } else if ([elapsedTimeUnits month] > 0) {
        number = [elapsedTimeUnits month];
        unit = [NSString stringWithFormat:@"month"];
    } else if ([elapsedTimeUnits week] > 0) {
        number = [elapsedTimeUnits week];
        unit = [NSString stringWithFormat:@"week"];
    } else if ([elapsedTimeUnits day] > 0) {
        number = [elapsedTimeUnits day];
        unit = [NSString stringWithFormat:@"day"];
    } else if ([elapsedTimeUnits hour] > 0) {
        number = [elapsedTimeUnits hour];
        unit = [NSString stringWithFormat:@"hour"];
    } else if ([elapsedTimeUnits minute] > 0) {
        number = [elapsedTimeUnits minute];
        unit = [NSString stringWithFormat:@"minute"];
    } else if ([elapsedTimeUnits second] > 0) {
        number = [elapsedTimeUnits second];
        unit = [NSString stringWithFormat:@"second"];
    } else {
        number = 1;
        unit = @"second";
    }

    // Check if unit number is greater than 1, then append 's' at the end.
    if (number > 1) {
        unit = [NSString stringWithFormat:@"%@s", unit];
    }

    // Resultant string required.
    NSString *scannedString = [NSString stringWithFormat:scannedFormat, number, unit];

    return scannedString;
}

person fulvio    schedule 06.05.2011    source источник


Ответы (1)


Вам нужно будет использовать [NSTimeZone localTimeZone], чтобы получить часовой пояс, в котором в настоящее время находится iPhone, а затем вам нужно будет обработать разницу между местным временем и временем сервера. Самый безопасный вариант, вероятно, состоит в том, чтобы преобразовать все время в GMT внутри (особенно при отправке времени на сервер), а затем преобразовать в местное время при отображении времени пользователю.

Вы также можете использовать «время сервера» в качестве эталонного часового пояса, убедитесь, что ваше приложение знает (либо запросив сервер, либо жестко подключив его к вашему приложению), что это за часовой пояс, а затем преобразуйте все значения времени в «время сервера». " внутренне ... но это может привести к проблемам, если ваш сервер изменит часовые пояса или проблемы с почасовой оплатой, когда ваш сервер запускает и заканчивает летнее время.

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

person Scott Forbes    schedule 06.05.2011
comment
Это будет включать [[NSTimeZone localTimeZone] secondsFromGMT] и NSDate метод dateByAddingTimeInterval, но помимо этого мне нужно написать собственный код. :-) - person Scott Forbes; 07.05.2011