Как получить текущую дату в Cocoa
я начинаю разработку для iPhone, и поэтому я смотрю на разные учебники в интернете, а также пробую некоторые разные вещи. В настоящее время я пытаюсь создать обратный отсчет до полуночи. Чтобы получить количество часов, минут и секунд, я делаю следующее (что я нашел где-то):
NSDate* now = [NSDate date];
int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay];
int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour];
int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute];
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, min,sec];
однако, каждое место я использую -dateWithCalendarFormat:timeZone:
Я получаю следующую ошибку:
warning: 'NSDate' may not respond to '-dateWithCalendarFormat:timeZone:'
(Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.)
warning: no '-hourOfDay' method found
error: invalid operands to binary - (have 'int' and 'id')
это кажется чем-то очень простым. Что я не хватает?
кроме того, я заметил в разных местах и в разное время звездочка (*) находится либо сразу после времени NSDate* now
или прямо перед переменной NSDate *now
. В чем разница между ними и почему вы используете один против другого?
14 ответов:
вы должны использовать следующее:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:yourDateHere]; NSInteger hour = [dateComponents hour]; NSInteger minute = [dateComponents minute]; NSInteger second = [dateComponents second]; [gregorian release];
нет никакой разницы между NSDate* now и NSDate *now, это просто вопрос предпочтения. С точки зрения компилятора, ничего не меняется.
у вас есть проблемы с iOS 4.2? Используйте этот код:
NSDate *currDate = [NSDate date]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"dd.MM.YY HH:mm:ss"]; NSString *dateString = [dateFormatter stringFromDate:currDate]; NSLog(@"%@",dateString);
-->20.01.2011 10:36:02
вы также можете использовать:
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem()); countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02.0f", currentDate.hour, currentDate.minute, currentDate.second]; CFRelease(currentDate); // Don't forget this! VERY important
Я думаю, что это имеет следующие преимущества:
- нет прямого выделения памяти.
- секунды-это двойной вместо целого числа.
- нет сообщения.
- быстрее.
// вы можете получить текущую дату/время с помощью следующего кода:
NSDate* date = [NSDate date]; NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; NSTimeZone *destinationTimeZone = [NSTimeZone systemTimeZone]; formatter.timeZone = destinationTimeZone; [formatter setDateStyle:NSDateFormatterLongStyle]; [formatter setDateFormat:@"MM/dd/yyyy hh:mma"]; NSString* dateString = [formatter stringFromDate:date];
заменить:
NSDate* now = [NSDate date]; int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay]; int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour]; int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute]; countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, min,sec];
С этого:
NSDate* now = [NSDate date]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now]; NSInteger hour = [dateComponents hour]; NSInteger minute = [dateComponents minute]; NSInteger second = [dateComponents second]; [gregorian release]; countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, second];
кроме того, я заметил в разных местах и в разное время звездочка (
*
) находится либо сразу после времениNSDate* now
или прямо перед переменнойNSDate *now
. В чем разница между ними и почему вы используете один против другого?компилятору все равно, но ставить звездочку перед пробелом может ввести в заблуждение. Вот мой пример:
int* a, b;
что то типа
b
?если вы угадал
int *
, вы ошибаетесь. Это простоint
.другой способ делает это немного яснее, сохраняя * рядом с переменной, к которой он принадлежит:
int *a, b;
конечно, есть два способа, которые еще яснее, чем это:
int b, *a; int *a; int b;
вам нужно сделать что-то вроде следующего:
NSDate *now = [NSDate date]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now]; NSLog(@"%d", [components hour]);
и так далее.
вот еще один способ:
NSDate *now = [NSDate date]; //maybe not 100% approved, but it works in English. You could localize if necessary NSDate *midnight = [NSDate dateWithNaturalLanguageString:@"midnight tomorrow"]; //num of seconds between mid and now NSTimeInterval timeInt = [midnight timeIntervalSinceDate:now]; int hours = (int) timeInt/3600; int minutes = ((int) timeInt % 3600) / 60; int seconds = (int) timeInt % 60;
вы теряете субсекундных точности с литой NSTimeInterval в int, но это не должно волновать.
NSDate* now
иNSDate *now
то же самое: указатель на объект NSDate.вы, вероятно, хотите использовать descriptionWithCalendarFormat:часовой пояс: locale:, а не dateWithCalendarFormat: - последний возвращает NSCalendarDate, который, как говорят документы, должен быть устаревшим в какой-то момент.
оригинальный плакат-способ определения секунд до полуночи не будет работать в день, когда начинается или заканчивается переход на летнее время. Вот кусок кода, который показывает как это сделать... Это будет в количестве секунд (NSTimeInterval); вы можете сделать деление/модуль/etc, чтобы добраться до того, что вам нужно.
NSDateComponents *dc = [[NSCalendar currentCalendar] components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:[NSDate date]]; [dc setDay:dc.day + 1]; NSDate *midnightDate = [[NSCalendar currentCalendar] dateFromComponents:dc]; NSLog(@"Now: %@, Tonight Midnight: %@, Hours until midnight: %.1f", [NSDate date], midnightDate, [midnightDate timeIntervalSinceDate:[NSDate date]] / 60.0 / 60.0);
нет никакой разницы в расположении звездочки (at в C, на котором основан Obj-C, это не имеет значения). Это чисто предпочтение (стиль).
Мне потребовалось некоторое время, чтобы найти, почему образец приложения работает, но мой нет.
библиотека (фонд.Framework), на который ссылается автор, - это системная библиотека (из ОС), где iPhone sdk (я использую 3.0) больше не поддерживается.
поэтому пример приложения (от about.com, http://www.appsamuck.com/day1.html) работает, но наши не делают.
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem()); countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Марк был прав этот код намного эффективнее для управления датами часов мин и сек. Но он забыл @ в начале объявления строки формата.