Date/time formatting

Discussion in 'iOS Programming' started by Brien, May 26, 2009.

  1. Brien macrumors 68020

    Brien

    Joined:
    Aug 11, 2008
    #1
    Hey everyone, right now I have a a timer (in seconds). I need to convert that to hours/mins/seconds/milliseconds and then use that as the title for a UILabel.

    I've looked into NSDateformatter but can't quite figure it out.

    Any help would be appreciated.

    Here's what I have right now, but all I get is a blank Label:

    Code:
    -(void)updateTimer {
    	NSString *secondsPassed = [NSString stringWithFormat:@"%i",incr];
    	NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    	[dateFormat setDateFormat:@"HH:mm:ss"];
    	[dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
    	NSDate *formattedString = [dateFormat dateFromString:secondsPassed];
    	myTimer.text = [dateFormat stringFromDate:formattedString];
    }
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Does your NSDate (formattedString) actually get created? I'd check if it's nil as that looks like the most likely place for that to fail.
     
  3. johnnyjibbs macrumors 68030

    johnnyjibbs

    Joined:
    Sep 18, 2003
    Location:
    London, UK
    #3
    You don't need to bother with NSDateFormatter. You can use NSCalendar's components:fromDate:toDate: options: parameter to compare the time between two dates. The components will bring back the highest possible format (e.g. 1 hr 15 mins instead of 75 mins, etc).

    To get two dates (the start and end dates, which will be timeInterval apart) you can use NSDate's dateWithTimeIntervalSinceNow:. You're just interested in the difference between the dates so you can specify the following:

    Code:
    NSTimeInterval timeInterval = [blah blah your time interval in seconds]
    NSDate *startDate = [NSDate date];  // just get the current date time stamp
    NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:timeInterval];  // This end date is exactly timeInterval seconds after the first date (which is now)
    
    // Now you need to set up an NSCalendar object
    // and use these two dates as the from and to dates
    // in the function at the top of this post
    
    I have some sample code I can post when I get home if you need any more help.
     
  4. Brien thread starter macrumors 68020

    Brien

    Joined:
    Aug 11, 2008
    #4
    Sure, every bit helps. Although what I'm really trying to do it get a leading 0 in front of the hours/mins/seconds, because I can do it with if statements but they'll spit out timecode that looks like 1:12:9 instead of 01:12:09.
     
  5. johnnyjibbs macrumors 68030

    johnnyjibbs

    Joined:
    Sep 18, 2003
    Location:
    London, UK
    #5
    I think once you have your time intervals in their individual elements, you can format the string easily to include the leading zero:

    Code:
    NSInteger hours;
    NSInteger mins;
    NSInteger seconds;
    
    label.text = [NSString stringWithFormat:@"%2d%2d%2d",hours,mins,seconds];
    
    I think that will work. Sorry I was away from my computer last night but I'll send through some example code from start to finish tonight when I'm at my Mac.
     
  6. johnnyjibbs macrumors 68030

    johnnyjibbs

    Joined:
    Sep 18, 2003
    Location:
    London, UK
    #6
    Here's the code I've used in one of my apps. It specifies minutes and seconds for an elapsed time but you could easily adapt to provide hours support as well. Hope it helps.

    Code:
    // Firstly, get start and end dates that are our time interval appart
    	NSDate *startDate = [NSDate date];
    	NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:musicPlayer.currentTime];
    	// Now calculate the components between them using NSCalendar
    	NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    	// Prepare the unti flags parameter
    	NSUInteger unitFlags = NSMinuteCalendarUnit | NSSecondCalendarUnit;
    	// Now get the highest individual components possible (e.g. 1 min and 15 seconds rather than 75 seconds)
    	NSDateComponents *components = [gregorian components:unitFlags fromDate:startDate toDate:endDate options:0];
    	// Finally split out into component minutes and seconds
    	NSInteger minutes = [components minute];
    	NSInteger seconds = [components second];
    	// Update the label
    	if (seconds < 10) {
    		elapsedLabel.text = [NSString stringWithFormat:@"%i:0%i",minutes,seconds];  // insert leading zero in the seconds column
    	} else {
    		elapsedLabel.text = [NSString stringWithFormat:@"%i:%2i",minutes,seconds];
    	}
    	// Memory control
    	[gregorian release];
     

Share This Page