Вопрос о NSDateFormatter и NSCalendar (включая часовые пояса) - PullRequest
0 голосов
/ 02 августа 2011

У меня есть следующий код:

    self.formatter = [[NSDateFormatter alloc] init];
    [formatter setTimeZone:timeZone];
    [formatter setDateFormat:@"YYYY-MM-dd hh:mm:ss a z"];
    timeStampForCity = [formatter stringFromDate:[NSDate date]];
    NSLog(@"%@", timeStampForCity);
    updateDate = [formatter dateFromString:timeStampForCity];
    NSLog(@"%@", updateDate);

NSLog(@"%@", timeStampForCity); выходы:

2011-08-01 10:05:50 PM EDT

но NSLog(@"%@", updateDate); выходы:

2011-08-02 02:05:50 +0000

мне нужно updateDate для отображения времени в текущем часовом поясе (например, как видно из первого выхода NSLog ()).Как мне сделать это правильно?

РЕДАКТИРОВАТЬ 1

У меня также есть этот код:

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit;
    NSDateComponents *dateComponents = [gregorian components:unitFlags fromDate:[NSDate date]];
    [dateComponents setTimeZone:[NSTimeZone timeZoneWithName:cityNameFormatted]];
    updateDate = [gregorian dateFromComponents:dateComponents];
    [gregorian release];

, но отображаемые часовые пояса отключены дляво многих регионах.

Заранее благодарим за помощь.

1 Ответ

7 голосов
/ 02 августа 2011

Вот и снова ...

Дата - это независимый момент времени.Он существует и будет существовать всегда, независимо от того, существуют люди или наши приборы для измерения времени.Часовые пояса являются изобретением человека, чтобы помочь нам не сойти с ума.До сих пор не решено, насколько они эффективны.: P

Когда вы говорите о желании «даты в EDT или любом другом часовом поясе», вы не понимаете, что такое дата.Часовой пояс - это просто один из аспектов , как отображать точку во времени .

Итак, у вас есть NSDate.Эта дата является правильной датой, независимо от того, в каком часовом поясе вы находитесь. Так как же вы «отображаете время в текущем часовом поясе»?Вы используете NSDateFormatter.

NSDate по своей сути нечитабелен.Есть способы, которыми мы можем представлять дату, например, интервал в секундах (который сам по себе является произвольно длинным интервалом) из другого момента времени.Однако сделать дату удобочитаемой для человека можно только путем ее форматирования в строку.Итак, давайте сделаем это:

NSDate *myDate = [NSDate date]; // or whatever date you want to make human-readable
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateStyle:NSDateFormatterLongStyle];
[f setTimeStyle:NSDateFormatterLongStyle];

NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];
for (NSString *name in timeZoneNames) {
    NSTimeZone *tz = [NSTimeZone timeZoneWithName:name];
    [f setTimeZone:tz];
    NSLog(@"%@", [f stringFromDate:date]);
}

Теперь, очевидно, выход для этого будет очень длинным (у меня более 400 строк).Но вот пример этого вывода:

...
August 2, 2011 1:03:38 AM GMT-03:00
August 2, 2011 12:03:38 AM AST
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM EST
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 11:03:38 PM CDT
August 2, 2011 12:03:38 AM AST
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 10:03:38 PM CST
August 2, 2011 12:03:38 AM AST
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM GMT-05:00
August 1, 2011 10:03:38 PM MDT
August 1, 2011 10:03:38 PM MDT
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM CDT
August 1, 2011 11:33:38 PM GMT-04:30
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 11:03:38 PM EST
August 1, 2011 11:03:38 PM CDT
August 1, 2011 10:03:38 PM MDT
...

Итак, что мы видим здесь? та же дата имеет целую кучу различных строковых представлений!NEAT!Другими словами, часовой пояс форматера - это то, что используется при определении того, как выглядит выведенная строка.

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


Update Из твоего комментария, думаю, я получу то, что ты хочешь.Вы хотите, чтобы компоненты даты были отформатированы для определенного часового пояса?Другими словами, у вас есть момент времени, и вы хотите знать, какой час / минуту / секунду находится, скажем, в восточном часовом поясе США?

Если это так, то вы делаете это на основе календарь :

NSDate *date = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];

NSDateComponents *components = [cal components:NSUIntegerMax fromDate:date];
NSLog(@"%@", components);

И это даст вам:

<NSDateComponents: 0x100124240> 
 Calendar: <CFCalendar 0x100133e90 [0x7fff7605cea0]>{identifier = 'gregorian'} / Time Zone: EST (GMT-05:00) offset -18000
 Era: 1
 Year: 2011
 Month: 8
 Day: 2
 Hour: 9
 Minute: 47
 Second: 21
 Week of Month: 1
 Week of Year: 31
 Year for Week of Year: 2011
 Weekday: 3
 Weekday Ordinal: 1
 Quarter: 0
...