TimeIntervalFormatter.m
author Jens Alfke <jens@mooseyard.com>
Thu Mar 20 09:05:58 2008 -0700 (2008-03-20)
changeset 1 e55a17cdabd2
parent 0 d84d25d6cdbb
child 11 e5976864dfe9
permissions -rw-r--r--
Configurable logging (LogTo).
Added "my_" prefix to category method names.
Added MurmurHash.
Added UniqueWindowController.
Bug fixes.
     1 //
     2 //  TimeIntervalFormatter.m
     3 //  MYUtilities
     4 //
     5 //  Copyright 2008 Jens Alfke. All rights reserved.
     6 //
     7 
     8 #import "TimeIntervalFormatter.h"
     9 
    10 
    11 @implementation TimeIntervalFormatter
    12 
    13 
    14 - (id) init
    15 {
    16     self = [super init];
    17     if (self != nil) {
    18         _showsMinutes = YES;
    19     }
    20     return self;
    21 }
    22 
    23 - (void) awakeFromNib
    24 {
    25     _showsMinutes = YES;
    26 }
    27 
    28 - (void) setShowsMinutes: (BOOL)show                {_showsMinutes = show;}
    29 - (void) setShowsFractionalSeconds: (BOOL)show      {_showsFractionalSeconds = show;}
    30 
    31 + (NSString*) formatTimeInterval: (NSTimeInterval)interval
    32 {
    33     TimeIntervalFormatter *fmt = [[self alloc] init];
    34     NSString *result = [fmt stringForObjectValue: [NSNumber numberWithDouble: interval]];
    35     [fmt release];
    36     return result;
    37 }
    38 
    39 
    40 - (NSString*) stringForObjectValue: (id)object
    41 {
    42     if (![object isKindOfClass:[NSNumber class]])
    43         return nil;
    44     NSTimeInterval time = [object doubleValue];
    45     NSString *sign;
    46     if( time==0.0 )
    47         return nil;
    48     else if( time < 0.0 ) {
    49         sign = @"-";
    50         time = -time;
    51     } else
    52         sign = @"";
    53     if( ! _showsFractionalSeconds )
    54         time = floor(time);
    55     int minutes = (int)floor(time / 60.0);
    56     if( _showsMinutes || minutes>0 ) {
    57         double seconds = time - 60.0*minutes;
    58         return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%d:%06.3lf" :@"%@%d:%02.0lf"),
    59                                            sign,minutes,seconds];
    60     } else {
    61         return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%.3lf" :@"%@%.0lf"),
    62                                            sign,time];
    63     }
    64 }
    65 
    66 
    67 - (BOOL)getObjectValue:(id *)anObject
    68              forString:(NSString *)string 
    69       errorDescription:(NSString **)error
    70 {
    71     NSScanner *scanner = [NSScanner scannerWithString: string];
    72     [scanner setCharactersToBeSkipped: [NSCharacterSet whitespaceCharacterSet]];
    73     double seconds;
    74     if( [scanner isAtEnd] ) {
    75         seconds = 0.0;
    76     } else {
    77         if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error;
    78         if( [scanner scanString: @":" intoString: NULL] ) {
    79             double minutes = seconds;
    80             if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error;
    81             seconds += 60*minutes;
    82         }
    83         if( ! [scanner isAtEnd] ) goto error;
    84     }
    85     *anObject = [NSNumber numberWithDouble: seconds];
    86     return YES;
    87     
    88 error:
    89     *anObject = nil;
    90     if( error )
    91         *error = @"Not a valid time interval";
    92     return NO;
    93 }
    94 
    95 
    96 - (BOOL)isPartialStringValid:(NSString **)partialStringPtr 
    97        proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
    98               originalString:(NSString *)origString 
    99        originalSelectedRange:(NSRange)origSelRange 
   100             errorDescription:(NSString **)error
   101 {
   102     static NSCharacterSet *sIllegalChars;
   103     if( ! sIllegalChars )
   104         sIllegalChars = [[[NSCharacterSet characterSetWithCharactersInString: @"0123456789.:"] 
   105                                 invertedSet] retain];
   106     return [*partialStringPtr rangeOfCharacterFromSet: sIllegalChars].length == 0;
   107 }
   108 
   109 
   110 @end