60

我开始为 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')

这看起来很简单。我错过了什么?

另外,我注意到在不同的地方和不同的时间,星号 (*) 位于 time 之后NSDate* now或变量之前NSDate *now。两者有什么区别,为什么要使用其中一个而不是另一个?

4

14 回答 14

59

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

于 2011-01-20T09:39:10.633 回答
48

您必须使用以下内容:

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 之间没有区别,这只是一个偏好问题。从编译器的角度来看,没有任何变化。

于 2009-07-01T17:37:10.823 回答
21

您还可以使用:


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. 快点。
于 2009-07-01T20:16:00.723 回答
12

// 您可以使用以下代码获取当前日期/时间:

    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];
于 2012-12-27T12:47:33.117 回答
5

替换这个:

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];
于 2009-09-22T19:21:07.783 回答
4

您需要执行以下操作:

NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);

等等。

于 2009-07-01T17:45:58.613 回答
4

另外,我注意到在不同的地方和不同的时间,星号 ( *) 位于 time 之后NSDate* now或 variable 之前NSDate *now。两者有什么区别,为什么要使用其中一个而不是另一个?

编译器不在乎,但是将星号放在空格之前可能会产生误导。这是我的例子:

int* a, b;

是什么类型的b

如果你猜到int *了,那你就错了。只是int

另一种方法是通过将 * 放在它所属的变量旁边来使这一点更加清晰:

int *a, b;

当然,还有两种比这更清楚的方法:

int b, *a;

int *a;
int b;
于 2009-07-02T02:35:41.377 回答
1

NSDate* now并且NSDate *now是同一件事:指向 NSDate 对象的指针。

您可能想要使用descriptionWithCalendarFormat:timeZone:locale:而不是dateWithCalendarFormat: — 后者返回一个 NSCalendarDate,文档说它计划在某个时候被弃用。

于 2009-07-01T17:39:25.733 回答
1

这是另一种方式:

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 会丢失亚秒级精度,但这无关紧要。

于 2009-07-01T19:36:58.430 回答
1

原始海报 - 您确定直到午夜的秒数的方式在夏令时开始或结束的那一天不起作用。这是一段代码,它显示了如何做到这一点......它将以秒为单位(一个 NSTimeInterval);你可以做除法/模数/等来得到你需要的任何东西。

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);
于 2011-09-07T11:40:32.870 回答
0

星号的位置没有区别(在Obj-C所基于的C中,没关系)。这纯粹是偏好(风格)。

于 2009-07-01T17:32:45.057 回答
0

我花了一段时间才找到示例应用程序工作的原因,但我的却没有。

作者引用的库(Foundation.Framework)是不再支持iphone sdk(我使用的是3.0)的系统库(来自OS)。

因此,示例应用程序(来自 about.com,http://www.appsamuck.com/day1.html)有效,但我们的应用程序无效。

于 2009-08-15T14:05:02.483 回答
0
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];

马克是对的,这段代码在管理日期小时分钟和秒方面效率更高。但是他忘记了格式字符串声明开头的@。

于 2010-04-08T15:55:42.550 回答
0
+ (NSString *)displayCurrentTimeWithAMPM 
{
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"h:mm aa"];

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

    return dateTime;
}

凌晨 3 点 33 分返回

于 2012-12-17T19:32:40.567 回答