Swany Swany - 9 months ago 27
iOS Question

How To Localize a "Timer" on iPhone

I need to display a timer in "hh:mm:ss" format on the iPhone, but want it localized. Finland, for example uses a period instead of a colon between the time components (hh.mm.ss). Apple's NSDateFormatter would do the trick if I was dealing with a "time" but I need to display hours much greater than 24.

I have not been able to make an NSDate/NSDateFormatter work because when you make one with seconds...

NSDate *aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTotalSeconds];

... every 86,400 seconds (one day's worth) NSDate automatically increments the day and hours, minutes, and seconds go back to zero. I need to make it work on an any number of seconds without rolling over. For example, with 86,401 seconds I want to display 24:00:01 (or 24.00.01 in Finland).

My code manages total seconds fine, so the only problem I have is the display. A simple...

[NSString stringWithFormat:@"%d%@%d%@%d", hours, sepString, mins, sepString, secs]

... would work if I could find a way to get at a localized "sepString" (the time component separator). NSLocale does not seem to have this.


Answer Source

Here is a admittedly hackish way to get the time component separator for any locale. It should work on iOS 3.2 and above. I know the code can be more concise, but I turned my "maximum-verbosity" flag on to make it as readable as possible.

- (NSString*)timeComponentSeparator
    // Make a sample date (one day, one minute, two seconds)
    NSDate *aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:((24*60*60)+62)];

    // Get the localized time string
    NSDateFormatter *aFormatter = [[NSDateFormatter alloc] init];
    [aFormatter setDateStyle:NSDateFormatterNoStyle];
    [aFormatter setTimeStyle:NSDateFormatterShortStyle];
    NSString *aTimeString = [aFormatter stringFromDate:aDate]; // Not using +localizedStringFromDate... because it is iOS 4.0+

    // Get time component separator
    NSCharacterSet *aCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@":-."];
    NSRange aRange = [aTimeString rangeOfCharacterFromSet:aCharacterSet];
    NSString *aTimeComponentSeparator = [aTimeString substringWithRange:aRange];    

    // Failsafe
    if ([aTimeComponentSeparator length] != 1)
        aTimeComponentSeparator = @":";

    return [[aTimeComponentSeparator copy] autorelease];