Como faço para obter a data atual em Cocoa
-
21-08-2019 - |
Pergunta
Eu estou começando a desenvolver para o iPhone e, como tal, eu estou olhando para diferentes tutoriais on-line, bem como tentar algumas coisas diferentes de mim. Atualmente, eu estou tentando criar uma contagem regressiva até meia-noite. Para obter o número de horas, minutos e segundos, eu faço o seguinte (que eu encontrei em algum lugar):
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];
No entanto, cada lugar que eu uso -dateWithCalendarFormat:timeZone:
eu recebo o seguinte erro:
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')
Este parece ser algo muito simples. O que eu estou ausente?
Além disso, tenho notado em diferentes locais e em diferentes épocas do asterisco (*) é localizado logo após o NSDate* now
tempo ou logo antes de a variável NSDate *now
. Qual é a diferença entre os dois e por que você usaria um contra o outro?
Solução
Você deve usar o seguinte:
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];
Não há nenhuma diferença entre NSDate * agora e NSDate * agora, é apenas uma questão de preferência. Do ponto de vista do compilador, nada muda.
Outras dicas
Você tem problemas com iOS 4.2? Utilize este código:
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
Você também pode usar:
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
Eu acho que isso tem as seguintes vantagens:
- No alocação de memória direta.
- Segundos é um casal em vez de um inteiro.
- Não há chamadas de mensagens.
- Faster.
// você pode obter a data / hora com o seguinte código atual:
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];
Substitua o seguinte:
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];
Com este:
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];
Além disso, tenho notado em diferentes locais e em diferentes épocas do asterisco (
*
) é localizado logo após oNSDate* now
tempo ou logo antes de a variávelNSDate *now
. Qual é a diferença entre os dois e por que você usaria um contra o outro?
O compilador não se importa, mas colocar o asterisco antes do espaço pode ser enganosa. Aqui está o meu exemplo:
int* a, b;
O que é o tipo de b
?
int *
Se você adivinhou, você está errado. É apenas int
.
A outra maneira torna este um pouco mais clara, mantendo o * ao lado da variável a que pertence:
int *a, b;
É claro, existem duas formas que são ainda mais claro do que isso:
int b, *a;
int *a;
int b;
Você precisa fazer algo ao longo das linhas do seguinte:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);
E assim por diante.
Aqui está outra maneira:
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;
Você perde precisão subsecond com o elenco do NSTimeInterval para um int, mas isso não importa.
NSDate* now
e NSDate *now
são a mesma coisa:. Um ponteiro para um objeto NSDate
Você provavelmente vai querer usar descriptionWithCalendarFormat: Fuso horário: locale: em vez de dateWithCalendarFormat: - este último retorna um NSCalendarDate, que os documentos dizem está programado para ser preterido em algum ponto.
O cartaz original - a maneira que você está determinando segundos até a meia-noite não vai funcionar em um dia em que o horário de verão começa ou termina. Aqui está um pedaço de código que mostra como fazê-lo ... Vai ser em número de segundos (um NSTimeInterval); você pode fazer a divisão / módulo / etc para chegar até o que você precisa.
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);
Não há nenhuma diferença na localização do asterisco (em em C, que Obj-C é baseada em, não importa). É puramente preferência (estilo).
Levei um tempo para localizar porque as obras de aplicativos de amostra, mas o meu não.
A biblioteca (Foundation.Framework) que o autor se refere é a biblioteca de sistema (a partir OS), onde o iPhone SDK (estou usando 3.0) não é apoiar mais.
Por isso, a aplicação da amostra (de about.com, http://www.appsamuck.com/day1 .html ) funciona, mas o nosso não.
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Mark estava certo este código é muito mais eficiente para gerenciar datas horas min e segs. Mas ele esqueceu o @ no início da declaração de string de formato.
+ (NSString *)displayCurrentTimeWithAMPM
{
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"h:mm aa"];
NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];
return dateTime;
}
retorno 03h33