Iphone 目标C:将分钟转换为时间

Iphone 目标C:将分钟转换为时间,iphone,objective-c,ios5,Iphone,Objective C,Ios5,我在将午夜后的分钟数转换为正确的时间时遇到问题。在我到达中午之前,一切正常。此时时间变为0:45AM,中午之后的任何内容都为空。我的格式中是否遗漏了什么 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"h:m"]; NSLog(@"Minutes %i",minutes); NSString *time = [NSString st

我在将午夜后的分钟数转换为正确的时间时遇到问题。在我到达中午之前,一切正常。此时时间变为
0:45AM
,中午之后的任何内容都为空。我的格式中是否遗漏了什么

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"h:m"];
    NSLog(@"Minutes %i",minutes);
    NSString *time = [NSString stringWithFormat:@"%i:%i", (minutes / 60), (minutes % 60)];
    NSLog(@"time: %@",time);
    NSDate *formatTime = [dateFormatter dateFromString:time];
    NSLog(@"formatTime %@",formatTime);
    dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    [dateFormatter setDateFormat:@"H:mma"];
    NSString *newTime = [dateFormatter stringFromDate:formatTime];
    NSLog(@"NewTime: %@",newTime);
    dateFormatter = nil;
日志

编辑: 我正在使用下面的Munid的Edit 2,它工作得很好,只是当我通过
日期格式化程序运行它时,它似乎从
newDate
中减去了7个小时

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    //dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    [dateFormatter setDateFormat:@"hh:mm a"];
    NSDate *midnight = [NSDate dateWithTimeIntervalSince1970:0];
    NSLog(@"midnight %@",midnight);
    NSDate *newDate = [midnight dateByAddingTimeInterval:minutes*60];
    NSLog(@"new date %@", newDate);
    //[dateFormatter setDateFormat:@"hh:mma"];
    NSString *newTime = [dateFormatter stringFromDate:newDate];
    NSLog(@"Time: %@", newTime);
    dateFormatter = nil;
将记录

2012-01-25 16:15:03.418 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.418 MyApp[44721:f803] new date 1970-01-01 08:00:00 +0000
2012-01-25 16:15:03.419 MyApp[44721:f803] Time: 01:00 AM
2012-01-25 16:15:03.420 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.420 MyApp[44721:f803] new date 1970-01-01 08:15:00 +0000
2012-01-25 16:15:03.420 MyApp[44721:f803] Time: 01:15 AM
2012-01-25 16:15:03.421 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.422 MyApp[44721:f803] new date 1970-01-01 12:45:00 +0000
2012-01-25 16:15:03.422 MyApp[44721:f803] Time: 05:45 AM
2012-01-25 16:15:03.423 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.424 MyApp[44721:f803] new date 1970-01-01 08:00:00 +0000
2012-01-25 16:15:03.424 MyApp[44721:f803] Time: 01:00 AM
2012-01-25 16:15:03.425 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.425 MyApp[44721:f803] new date 1970-01-01 08:15:00 +0000
2012-01-25 16:15:03.426 MyApp[44721:f803] Time: 01:15 AM
2012-01-25 16:15:03.427 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.427 MyApp[44721:f803] new date 1970-01-01 09:15:00 +0000
2012-01-25 16:15:03.427 MyApp[44721:f803] Time: 02:15 AM
2012-01-25 16:15:03.428 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.429 MyApp[44721:f803] new date 1970-01-01 09:30:00 +0000
2012-01-25 16:15:03.429 MyApp[44721:f803] Time: 02:30 AM
2012-01-25 16:15:03.430 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.431 MyApp[44721:f803] new date 1970-01-01 10:30:00 +0000
2012-01-25 16:15:03.431 MyApp[44721:f803] Time: 03:30 AM
2012-01-25 16:15:03.432 MyApp[44721:f803] midnight 1970-01-01 00:00:00 +0000
2012-01-25 16:15:03.432 MyApp[44721:f803] new date 1970-01-01 11:30:00 +0000
2012-01-25 16:15:03.433 MyApp[44721:f803] Time: 04:30 AM

首先,可能你的格式化字符串的方法有点太复杂了。不要忘记,
NSLog
输出也需要格式化,否则您将获得不同的区域设置和时区,因此这些值对于检查逻辑是否正确是不可靠的

简单的解决方案是使用
NSTimeInterval
以秒为单位这一事实。因此:

NSDate *midnight; // the date you want, at 0:00 am
NSDate *newDate = [midnight dateByAddingTimeInterval:minutes*60];
编辑:

此外,我检查了您的代码-您可以通过更改格式字符串来修复它。问题是日期格式化程序与具有1或2位数字的分钟混淆

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
for (NSInteger minutes = 495; minutes < 1000; minutes +=60) {
    [dateFormatter setDateFormat:@"hh:mm"];
    NSLog(@"Minutes %2i",minutes);
    NSString *time = [NSString stringWithFormat:@"%2i:%2i", (minutes / 60), (minutes % 60)];
    NSLog(@"time: %@",time);
    NSDate *formatTime = [dateFormatter dateFromString:time];
    NSLog(@"formatTime %@",formatTime);
    dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    [dateFormatter setDateFormat:@"HH:mm a"];
    NSString *newTime = [dateFormatter stringFromDate:formatTime];
    NSLog(@"NewTime: %@",newTime);
}
dateFormatter = nil;        
NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];
对于(NSInteger分钟数=495;分钟数<1000;分钟数+=60){
[日期格式化程序setDateFormat:@“hh:mm”];
NSLog(@“分钟%2i”,分钟);
NSString*time=[NSString stringWithFormat:@“%2i:%2i”,(分钟/60),(分钟%60)];
NSLog(@“时间:%@”,时间);
NSDate*formatTime=[dateFormatter dateFromString:time];
NSLog(@“formatTime%@”,formatTime);
dateFormatter.locale=[[NSLocale alloc]initWithLocaleIdentifier:@“en-US”];
[dateFormatter setDateFormat:@“HH:mm a”];
NSString*newTime=[dateFormatter stringFromDate:formatTime];
NSLog(@“新时间:%@”,新时间);
}
dateFormatter=nil;
EDIT2:

按要求扩展上述代码:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"hh:mm a"];
NSDate *midnight = [NSDate dateWithTimeIntervalSince1970:0];
for (NSInteger minutes = 495; minutes < 1000; minutes +=60) {
    NSDate *newDate = [midnight dateByAddingTimeInterval:minutes*60];
    NSLog(@"newDate: %@", [dateFormatter stringFromDate:newDate]);
}
dateFormatter = nil;        
NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@“hh:mm a”];
NSDate*midnight=[NSDate DATE WITH TIME INTERVALSECSENC1970:0];
对于(NSInteger分钟数=495;分钟数<1000;分钟数+=60){
NSDate*newDate=[午夜日期通过添加时间间隔:分钟*60];
NSLog(@“newDate:%@,[dateFormatter stringFromDate:newDate]);
}
dateFormatter=nil;

这里有一个解决方案,可以正确处理用户区域设置的时区和时间显示:

void doMinutes(NSUInteger minutes) {
    static const NSUInteger minutesInDay = 60 * 24;

    if (minutes >= minutesInDay) {
        minutes = minutes % minutesInDay;
    }

    //Create a new date at midnight GMT
    NSDate *newDate = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:minutes * 60];
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    [fmt setTimeStyle:NSDateFormatterShortStyle];
    [fmt setDateStyle:NSDateFormatterNoStyle];
    [fmt setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
    NSLog(@"minutes: %ld, new date: %@", minutes, [fmt stringFromDate:newDate]);
    [fmt release];
    [newDate release];
}

int main(int argc, char *argv[]) {
    NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];

    doMinutes(480);
    doMinutes(765);
    doMinutes(840);
    doMinutes(30);
    doMinutes(1430);
    [p release];
}
日志输出:

minutes: 480, new date: 8:00 AM
minutes: 765, new date: 12:45 PM
minutes: 840, new date: 2:00 PM
minutes: 30, new date: 12:30 AM
minutes: 1430, new date: 11:50 PM
将区域设置设置为英国时的日志输出:

minutes: 480, new date: 08:00
minutes: 765, new date: 12:45
minutes: 840, new date: 14:00
minutes: 30, new date: 00:30
minutes: 1430, new date: 23:50

我编辑了我的答案,以更正您的代码并扩展我的方法。Edit1似乎无法解决问题,Edit2将时间改为凌晨1点开始,而不是早上8点。Edit2看起来不错,并且在日志中以正确的新日期显示正确,但当我们通过格式化程序运行它时,它似乎会扰乱时间。当我在newDate它看起来很完美,一旦我通过dateFormatter运行它,距离newDate只有-7小时了。我是MST,时间为-7小时,但我没有设置dateFormatter区域设置。我把它拿出来看看是否能修好,但运气不好。有什么想法吗?我会编辑我原来的帖子。好的,我想好了。NSDate的时间为GMT,日期格式化程序为MST。我将dateFormatter设置为GMT,一切正常
[dateFormatter setTimeZone:[NSTimeZone TimeZoneWithAbRevision:@“GMT”]根据我痛苦的经历,我相信NSLog使用系统时区(NSTimeZone systemTimeZone))格式化日期。NSDateformatter将解释它配置的时区的日期,我认为默认情况下是@“UTC”。这可能是你所看到的7小时差异的原因。如果我对绝对时间不感兴趣(这就是日期的含义),我会确保所有计算都在一个时区内完成,通常我会将它们全部设置为UTC。我避免使用NSLog查看日期,因为它只会造成混乱,除非您密切关注此细节。@Jim此答案是在我将上述答案标记为完成后创建的。我还把时区问题的解决方案贴在了那个答案的评论上
minutes: 480, new date: 08:00
minutes: 765, new date: 12:45
minutes: 840, new date: 14:00
minutes: 30, new date: 00:30
minutes: 1430, new date: 23:50