Разбираемся с NSDate

UTC — это всемирное координированное время, стандарт времени, принятый на Земле. От UTC отсчитываются часовые пояса. UTC заменил устаревшее время по Гринвичу (GMT). UTC расшифровывается как Coordinated Universal Time (по-английски).


Получим текущее время с помощью метода date класса NSDate. Xcode при наведении указателя на временную переменную показывает её значение как UTC время.

2015-09-28 21:46:56 +0000

Если я сейчас зайду на один следующих сайтов:
то я увижу то же самое значение, которое показывает Xcode:
21:46:56
Monday, September 28, 2015

Это UTC время.

Теперь если преобразовать эту временную переменную в строку с помощью следующего кода:

    NSDateFormatter *theDateFormatter = [[NSDateFormatter alloc] init];
    [theDateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss:SSS"];
    NSString *theString = [theDateFormatter stringFromDate:theDate];

то значение строковой переменной будет 2015/09/29 03:46:56:000. Именно столько сейчас показывают часы моего компьютера. NSDateFormatter по умолчанию использует мою временную зону.

С помощью того же экземпляра класса NSDateFormatter можно выполнить обратное преобразование. 



То же самое при получении даты изменения файла:

    NSString *theFilePath = [@"~/Documents/a/b/c.txt" stringByExpandingTildeInPath];
    NSURL *theFileURL = [NSURL fileURLWithPath:theFilePath];
    NSDate *theDate = nil;
    NSError *theError = nil;
    [theFileURL getResourceValue:&theDate
                       forKey:NSURLContentModificationDateKey
                        error:&theError];

Сейчас 2015-09-28 22:11:02 +0000 по UTC и я изменил файл ~/Documents/a/b/c.txt. Xcode будет показывать эту дату при наведении указателя на переменную theDate.

Одна из частых ошибок при работе с датами, это выводить дату в одной временной зоне, а считывать в другой.

Если вы сохраняете время в JSON-файле например, то нужно понимать в какой временной зоне вы его сохранили и потом в такой временной зоне его считывать. Например, если вы при записи использовали такой форматтер:

    NSDateFormatter *theDateTimeFormatter = [[NSDateFormatter alloc] init];
    [theDateTimeFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
    [theDateTimeFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

а при чтении используете такой:

    NSDateFormatter *theDateTimeFormatter = [[NSDateFormatter alloc] init];

То вы получите неверный результат.