我正在开始为 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* nowNSDate *now 是同一件事:指向 NSDate 对象的指针。

你可能想使用 描述与日历格式:时区:区域设置: 而不是 日期与日历格式: — 后者返回一个 NSCalendarDate,文档称该日期计划在某个时候被弃用。

原始海报 - 您确定午夜前秒数的方式在夏令时开始或结束的那一天不起作用。这是一段代码,展示了如何做到这一点......将以秒数为单位(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);

星号的位置没有区别(Obj-C 所基于的 C 中的星号并不重要)。这纯粹是偏好(风格)。

我花了一段时间才找到为什么示例应用程序可以工作,但我的应用程序却不能。

作者引用的库(Foundation.Framework)是系统库(来自操作系统),其中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