jens@0: // jens@0: // TimeIntervalFormatter.m jens@0: // MYUtilities jens@0: // jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "TimeIntervalFormatter.h" jens@0: jens@0: jens@0: @implementation TimeIntervalFormatter jens@0: jens@0: jens@1: - (id) init jens@1: { jens@1: self = [super init]; jens@1: if (self != nil) { jens@1: _showsMinutes = YES; jens@1: } jens@1: return self; jens@1: } jens@1: jens@0: - (void) awakeFromNib jens@0: { jens@0: _showsMinutes = YES; jens@0: } jens@0: jens@0: - (void) setShowsMinutes: (BOOL)show {_showsMinutes = show;} jens@0: - (void) setShowsFractionalSeconds: (BOOL)show {_showsFractionalSeconds = show;} jens@0: jens@1: + (NSString*) formatTimeInterval: (NSTimeInterval)interval jens@1: { jens@1: TimeIntervalFormatter *fmt = [[self alloc] init]; jens@1: NSString *result = [fmt stringForObjectValue: [NSNumber numberWithDouble: interval]]; jens@1: [fmt release]; jens@1: return result; jens@1: } jens@1: jens@0: jens@0: - (NSString*) stringForObjectValue: (id)object jens@0: { jens@0: if (![object isKindOfClass:[NSNumber class]]) jens@0: return nil; jens@0: NSTimeInterval time = [object doubleValue]; jens@0: NSString *sign; jens@0: if( time==0.0 ) jens@0: return nil; jens@0: else if( time < 0.0 ) { jens@0: sign = @"-"; jens@0: time = -time; jens@0: } else jens@0: sign = @""; jens@0: if( ! _showsFractionalSeconds ) jens@0: time = floor(time); jens@0: int minutes = (int)floor(time / 60.0); jens@0: if( _showsMinutes || minutes>0 ) { jens@0: double seconds = time - 60.0*minutes; jens@0: return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%d:%06.3lf" :@"%@%d:%02.0lf"), jens@0: sign,minutes,seconds]; jens@0: } else { jens@0: return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%.3lf" :@"%@%.0lf"), jens@0: sign,time]; jens@0: } jens@0: } jens@0: jens@0: jens@0: - (BOOL)getObjectValue:(id *)anObject jens@0: forString:(NSString *)string jens@0: errorDescription:(NSString **)error jens@0: { jens@0: NSScanner *scanner = [NSScanner scannerWithString: string]; jens@0: [scanner setCharactersToBeSkipped: [NSCharacterSet whitespaceCharacterSet]]; jens@0: double seconds; jens@0: if( [scanner isAtEnd] ) { jens@0: seconds = 0.0; jens@0: } else { jens@0: if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error; jens@0: if( [scanner scanString: @":" intoString: NULL] ) { jens@0: double minutes = seconds; jens@0: if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error; jens@0: seconds += 60*minutes; jens@0: } jens@0: if( ! [scanner isAtEnd] ) goto error; jens@0: } jens@0: *anObject = [NSNumber numberWithDouble: seconds]; jens@0: return YES; jens@0: jens@0: error: jens@0: *anObject = nil; jens@0: if( error ) jens@0: *error = @"Not a valid time interval"; jens@0: return NO; jens@0: } jens@0: jens@0: jens@0: - (BOOL)isPartialStringValid:(NSString **)partialStringPtr jens@0: proposedSelectedRange:(NSRangePointer)proposedSelRangePtr jens@0: originalString:(NSString *)origString jens@0: originalSelectedRange:(NSRange)origSelRange jens@0: errorDescription:(NSString **)error jens@0: { jens@0: static NSCharacterSet *sIllegalChars; jens@0: if( ! sIllegalChars ) jens@0: sIllegalChars = [[[NSCharacterSet characterSetWithCharactersInString: @"0123456789.:"] jens@0: invertedSet] retain]; jens@0: return [*partialStringPtr rangeOfCharacterFromSet: sIllegalChars].length == 0; jens@0: } jens@0: jens@0: jens@0: @end jens@11: jens@11: jens@11: /* jens@11: Copyright (c) 2008, Jens Alfke . All rights reserved. jens@11: jens@11: Redistribution and use in source and binary forms, with or without modification, are permitted jens@11: provided that the following conditions are met: jens@11: jens@11: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@11: and the following disclaimer. jens@11: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions jens@11: and the following disclaimer in the documentation and/or other materials provided with the jens@11: distribution. jens@11: jens@11: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@11: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@11: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@11: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@11: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@11: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@11: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@11: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@11: */