Как мне получить текущую дату в Cocoa
-
21-08-2019 - |
Вопрос
Я начинаю разработку для 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
Я думаю, что это имеет следующие преимущества:
- Нет прямого выделения памяти.
- Секунды - это двойное число, а не целое.
- Никаких звонков с сообщениями.
- Быстрее.
// вы можете получить текущую дату / время с помощью следующего кода:
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 утра