Вопрос

Я начинаю разработку для 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.В чем разница между ними и почему вы бы использовали одно по сравнению с другим?

Это было полезно?

Решение

Вы должны использовать следующее:

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

Я думаю, что это имеет следующие преимущества:

  1. Нет прямого выделения памяти.
  2. Секунды - это двойное число, а не целое.
  3. Никаких звонков с сообщениями.
  4. Быстрее.

// вы можете получить текущую дату / время с помощью следующего кода:

    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.

Вы, вероятно, захотите использовать Описание с календарным форматом: Часовой пояс: локаль: вместо того , чтобы Дата с календарным форматом: — последний возвращает 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);

Нет никакой разницы в расположении звездочки (в C, на котором основан Obj-C, это не имеет значения).Это чисто предпочтение (стиль).

Мне потребовалось некоторое время, чтобы понять, почему примерное приложение работает, а мое - нет.

Библиотека (Foundation.Framework), на которую ссылается автор, является системной библиотекой (из OS), где 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];

Марк был прав, этот код намного эффективнее для управления датами, часами, минутами и секундами.Но он забыл @ в начале объявления строки формата.

+ (NSString *)displayCurrentTimeWithAMPM 
{
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"h:mm aa"];

    NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];

    return dateTime;
}

возвращение в 3:33 утра

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top