I'm getting started developing for the iPhone and as such I am looking at different tutorials online as well as trying some different things out myself. Currently, I'm trying to create a countdown until midnight. To get the number of hour, minutes, and seconds, I do the following (which I found somewhere):
我开始为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];
However, each place I use -dateWithCalendarFormat:timeZone:
I get the following error:
但是,我使用的每个地方-dateWithCalendarFormat:时区:我得到以下错误:
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')
This seems like something very simple. What am I missing?
这看起来很简单。我缺少什么?
Also, I've noticed at different places and at different times the asterisk (*) is located either right after the time NSDate* now
or right before the variable NSDate *now
. What is the difference in the two and why would you use one versus the other?
另外,我注意到在不同的地方和不同的时间星号(*)要么在NSDate*之后,要么就在NSDate*之前。两者的区别是什么?为什么要用一个而不是另一个?
14 个解决方案
#1
47
You must use the following:
您必须使用以下内容:
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];
There is no difference between NSDate* now and NSDate *now, it's just a matter of preference. From the compiler perspective, nothing changes.
NSDate now和NSDate now之间没有区别,这只是偏好的问题。从编译器的角度来看,没有什么变化。
#2
57
You have problems with iOS 4.2? Use this Code:
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
- - > 20.01.2011 10:36:02
#3
21
You can also use:
您还可以使用:
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
I think this has the following advantages:
我认为这有以下优点:
- No direct memory allocation.
- 没有直接内存分配。
- Seconds is a double instead of an integer.
- 秒是双精度数而不是整数。
- No message calls.
- 没有消息调用。
- Faster.
- 得更快。
#4
12
// you can get current date/time with the following code:
//您可以通过以下代码获得当前日期/时间:
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];
#5
5
Replace this:
替换:
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];
With this:
用这个:
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];
#6
4
Also, I've noticed at different places and at different times the asterisk (
*
) is located either right after the timeNSDate* now
or right before the variableNSDate *now
. What is the difference in the two and why would you use one versus the other?另外,我注意到在不同的地方和不同的时间星号(*)要么在NSDate*之后,要么就在NSDate*之前。两者的区别是什么?为什么要用一个而不是另一个?
The compiler doesn't care, but putting the asterisk before the space can be misleading. Here's my example:
编译器并不在意,但是在空格前加上星号会引起误解。这是我的例子:
int* a, b;
What is the type of b
?
b的类型是什么?
If you guessed int *
, you're wrong. It's just int
.
如果你猜是int *,那你错了。它只是int。
The other way makes this slightly clearer by keeping the * next to the variable it belongs to:
另一种方法是将*放在它所属的变量的旁边,从而使这一点稍微清晰一些:
int *a, b;
Of course, there are two ways that are even clearer than that:
当然,有两种方式比这更清晰:
int b, *a;
int *a;
int b;
#7
3
You need to do something along the lines of the following:
你需要按照以下原则做一些事情:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);
And so on.
等等。
#8
1
Here's another way:
这是另一种方式:
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;
You lose subsecond precision with the cast of the NSTimeInterval to an int, but that shouldn't matter.
当将NSTimeInterval转换为int类型时,您将失去每秒的精度,但这并不重要。
#9
1
NSDate* now
and NSDate *now
are the same thing: a pointer to an NSDate object.
NSDate* now和NSDate*现在是一样的:指向NSDate对象的指针。
You probably want to use descriptionWithCalendarFormat:timeZone:locale: rather than dateWithCalendarFormat: — the latter returns an NSCalendarDate, which the docs say is scheduled to be deprecated at some point.
您可能希望使用descriptionWithCalendarFormat:timeZone:locale:而不是dateWithCalendarFormat: -后者返回一个NSCalendarDate,文档中说这个日期在某些时候是不可取的。
#10
1
Original poster - the way you're determining seconds until midnight won't work on a day when daylight savings starts or ends. Here's a chunk of code which shows how to do it... It'll be in number of seconds (an NSTimeInterval); you can do the division/modulus/etc to get down to whatever you need.
这里有一段代码展示了如何实现它……它将以秒为单位(一个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);
#11
0
There is no difference in the location of the asterisk (at in C, which Obj-C is based on, it doesn't matter). It is purely preference (style).
星号的位置没有区别(在C中,这是object -C的基础,没关系)。这纯粹是偏好(风格)。
#12
0
It took me a while to locate why the sample application works but mine don't.
我花了一段时间才找到示例应用程序工作的原因,但我的应用程序不工作。
The library (Foundation.Framework) that the author refer to is the system library (from OS) where the iphone sdk (I am using 3.0) is not support any more.
作者提到的库(Foundation.Framework)是系统库(从OS),其中iphone sdk(我正在使用3.0)不再支持。
Therefore the sample application (from about.com, http://www.appsamuck.com/day1.html) works but ours don't.
因此,示例应用程序(来自about.com, http://www.appsamuck.com/day1.html)工作,但我们的没有。
#13
0
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Mark was right this code is MUCH more efficient to manage dates hours min and secs. But he forgot the @ at the beginning of format string declaration.
Mark说得对,这段代码在管理日期上比在最小和秒要有效得多。但是他在格式字符串声明的开头忘记了@。
#14
0
+ (NSString *)displayCurrentTimeWithAMPM
{
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"h:mm aa"];
NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];
return dateTime;
}
return 3:33 AM
返回33秒我
#1
47
You must use the following:
您必须使用以下内容:
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];
There is no difference between NSDate* now and NSDate *now, it's just a matter of preference. From the compiler perspective, nothing changes.
NSDate now和NSDate now之间没有区别,这只是偏好的问题。从编译器的角度来看,没有什么变化。
#2
57
You have problems with iOS 4.2? Use this Code:
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
- - > 20.01.2011 10:36:02
#3
21
You can also use:
您还可以使用:
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
I think this has the following advantages:
我认为这有以下优点:
- No direct memory allocation.
- 没有直接内存分配。
- Seconds is a double instead of an integer.
- 秒是双精度数而不是整数。
- No message calls.
- 没有消息调用。
- Faster.
- 得更快。
#4
12
// you can get current date/time with the following code:
//您可以通过以下代码获得当前日期/时间:
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];
#5
5
Replace this:
替换:
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];
With this:
用这个:
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];
#6
4
Also, I've noticed at different places and at different times the asterisk (
*
) is located either right after the timeNSDate* now
or right before the variableNSDate *now
. What is the difference in the two and why would you use one versus the other?另外,我注意到在不同的地方和不同的时间星号(*)要么在NSDate*之后,要么就在NSDate*之前。两者的区别是什么?为什么要用一个而不是另一个?
The compiler doesn't care, but putting the asterisk before the space can be misleading. Here's my example:
编译器并不在意,但是在空格前加上星号会引起误解。这是我的例子:
int* a, b;
What is the type of b
?
b的类型是什么?
If you guessed int *
, you're wrong. It's just int
.
如果你猜是int *,那你错了。它只是int。
The other way makes this slightly clearer by keeping the * next to the variable it belongs to:
另一种方法是将*放在它所属的变量的旁边,从而使这一点稍微清晰一些:
int *a, b;
Of course, there are two ways that are even clearer than that:
当然,有两种方式比这更清晰:
int b, *a;
int *a;
int b;
#7
3
You need to do something along the lines of the following:
你需要按照以下原则做一些事情:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);
And so on.
等等。
#8
1
Here's another way:
这是另一种方式:
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;
You lose subsecond precision with the cast of the NSTimeInterval to an int, but that shouldn't matter.
当将NSTimeInterval转换为int类型时,您将失去每秒的精度,但这并不重要。
#9
1
NSDate* now
and NSDate *now
are the same thing: a pointer to an NSDate object.
NSDate* now和NSDate*现在是一样的:指向NSDate对象的指针。
You probably want to use descriptionWithCalendarFormat:timeZone:locale: rather than dateWithCalendarFormat: — the latter returns an NSCalendarDate, which the docs say is scheduled to be deprecated at some point.
您可能希望使用descriptionWithCalendarFormat:timeZone:locale:而不是dateWithCalendarFormat: -后者返回一个NSCalendarDate,文档中说这个日期在某些时候是不可取的。
#10
1
Original poster - the way you're determining seconds until midnight won't work on a day when daylight savings starts or ends. Here's a chunk of code which shows how to do it... It'll be in number of seconds (an NSTimeInterval); you can do the division/modulus/etc to get down to whatever you need.
这里有一段代码展示了如何实现它……它将以秒为单位(一个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);
#11
0
There is no difference in the location of the asterisk (at in C, which Obj-C is based on, it doesn't matter). It is purely preference (style).
星号的位置没有区别(在C中,这是object -C的基础,没关系)。这纯粹是偏好(风格)。
#12
0
It took me a while to locate why the sample application works but mine don't.
我花了一段时间才找到示例应用程序工作的原因,但我的应用程序不工作。
The library (Foundation.Framework) that the author refer to is the system library (from OS) where the iphone sdk (I am using 3.0) is not support any more.
作者提到的库(Foundation.Framework)是系统库(从OS),其中iphone sdk(我正在使用3.0)不再支持。
Therefore the sample application (from about.com, http://www.appsamuck.com/day1.html) works but ours don't.
因此,示例应用程序(来自about.com, http://www.appsamuck.com/day1.html)工作,但我们的没有。
#13
0
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Mark was right this code is MUCH more efficient to manage dates hours min and secs. But he forgot the @ at the beginning of format string declaration.
Mark说得对,这段代码在管理日期上比在最小和秒要有效得多。但是他在格式字符串声明的开头忘记了@。
#14
0
+ (NSString *)displayCurrentTimeWithAMPM
{
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"h:mm aa"];
NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];
return dateTime;
}
return 3:33 AM
返回33秒我