Получить NSDate от NSDate с учетом часового пояса - PullRequest
16 голосов
/ 20 сентября 2011

У меня есть объект NSDate.Скажем, оно представляет «1-10-2011»

NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"];

Эта дата переводится в «2011-09-30 22:00:00» из-за моего часового пояса.

Вопрос: Какполучить новый объект Date, представляющий «2011-10-01 00:00:00» в моем местном часовом поясе?

Ответы [ 2 ]

30 голосов
/ 09 августа 2012

NSDate представляет собой абсолютный момент времени .У него нет понятия часового пояса или календаря.Когда вы создаете экземпляр NSDate, это всего лишь количество секунд с 1 января 2001 года по Гринвичу!Не имеет значения, находитесь ли вы в Нью-Йорке, Токио, Барселоне или Иерусалиме.

В вашем примере вы создаете NSDate на основе времени по Гринвичу, но [date description] (используется в NSLog) переводит его в вашместное время.Там у вас есть несоответствие.

Итак, нужно рассмотреть две части:

1.Создание NSDate с использованием NSCalendar и NSTimeZone

Если вы создаете дату вручную, вы должны указать календарь (2012 на григорианском, но 5772 на иврите) и часовой пояс (22:00 по лондонскому времени, но 7:00 по сиднейскому времени).

// Use the user's current calendar and time zone
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone: [NSTimeZone systemTimeZone]];

// Specify the date components manually (year, month, day, hour, minutes, etc.)
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
[timeZoneComps setHour:22];
[timeZoneComps setMinute:0];
[timeZoneComps setSecond:0];
// ... year, month, ...

// transform the date compoments into a date, based on current calendar settings
NSDate *date = [calendar dateFromComponents:timeZoneComps];

В этот момент дата хранит точный момент времени (в секундах), представляющий текущий календарь.

2.Вывод NSDate с использованием NSDateFormatter

Для управляемого вывода вашего NSDate вам потребуется NSDateFormatter , который используется для преобразования дат в строки.

На основеApple NSDateFormatter Справочник по классам документация

Существует множество атрибутов, которые вы можете получить и установить в формататоре даты в стиле , ... Однако вам рекомендуется не изменять индивидуальные настройки .Вместо этого вы должны принять настройки по умолчанию, установленные при инициализации, и указать формат , используя setDateStyle :, setTimeStyle:

Это особенно важно для выходных данных, которые различны для каждой локали.По умолчанию NSDateFormatter учитывает настройки локали текущего пользователя.Таким образом, одна и та же NSDate может быть 22.11.2011 18:33:19, или Nov 22, 2011 6:33:19 PM, или 2011-11-22 下午6:33:19, или даже २२-११-२०११ ६:३३:१९ अपराह्, все для одного и того же входа и с тем же кодом.

И код:

//  NSDate *date -> NSString *dateString 

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];

// Medium style date, short style time => "Nov 23, 1937 3:30pm"
NSString *dateString = [dateFormatter stringFromDate:date];

Или вы можете преобразовать его, используя метод класса localizedStringFromDate: dateStyle: timeStyle:

Надеюсь, это решит проблему.

6 голосов
/ 20 сентября 2011

[NSDate date] возвращает дату в GMT.

Когда вы заявляете:

Эта дата переводится как "2011-09-30 22:00:00" из-за моего часовой пояс.

Это из NSLog или NSDateFormatter? Не полагайтесь на [date description], который использует NSLog, он учитывает ваш местный часовой пояс, используйте NSDateFormatter. NSDateFormatter имеет метод setTimeZone.

Из документов Apple на [date description]:

Представление не гарантируется постоянным по всему разные выпуски операционной системы. Чтобы отформатировать дату, вы следует использовать объект форматера даты вместо

...