views:

182

answers:

3

Hi,

Whats the best way to ensure the user has entered a valid time string such as:

5:24 5.4

102:30 102.5

It will be entered into a UITextField therefore will be in a NSString.

I want to allow the user to enter the time in either hours and minutes (hh:mm) or hours and decimal minutes (hh.m).

In the hours minutes example they should be able to enter as many hours as the like but only between 0 - 59 minutes. With the hours decimal minutes I want them to only be able to enter again as many hours as the like but decimal minutes can only be 0 - 9.

Many Thanks

+1  A: 

If you are using the latest non beta SDK (3.2), you can use regular expressions for this.

NSString *myString = @"5:24";
NSString *myRegex = @"^\\d+(?:[:](?:[0-5]?\\d)|\\.\\d)$";
NSRange myRange = [myString rangeOfString:myRegex options:NSRegularExpressionSearch];
if (myRange.location != NSNotFound)
  // the string is valid
else
  // the string is invalid

Matches:

5:12
5:1
5:01
5:0
5:00
1234567:12
0:0
5.1
5.0
0.1
0.0
1234567.1

Non-matches:

5     // symbol required (i.e. ":" or ".")
5:    // minutes are required
5:123 // too many minutes, max is 2 digits
5:67  // minutes can only be up to 59
-5:12 // negative numbers aren't allowed
5.    // minutes are required
5.12  // too many minutes, max is 1 digit
:12   // hours are required
.12   // hours are required
5.1a  // string must not contain "a"
 5.1  // string must not contain whitespace " "
Senseful
That looks great but unfortunately it's for the iPhone so on 3.1.3
Daniel Granger
A: 

As I'm using 3.1.3, I did a quick search in the documentation for using regular expressions with strings and I came up with this, I just copied what was in the documentation but added eagles regex but I added a load of \\ as that what they had done in the docs and it seems to work but as I have no knowledge of regular expressions I have no idea if this is correct and if it should work, please advise (In the mean time I will start reading up on regular expressions):

NSArray *array = [NSArray arrayWithObjects: @"5:24", @"5.4", @"e3:32", @"1023:90", @"3432.2", nil];
NSPredicate *timePred = [NSPredicate predicateWithFormat:@"SELF MATCHES '^\\\\d+(?:[:](?:[0-5]?\\\\d)|\\\\.\\\\d)$'"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:timePred];

for (NSString *oneString in filteredArray) {
    NSLog(@"%@", oneString);
}
Daniel Granger
+1  A: 

Why not just create a date format object and see if it returns a valid NSDate?

Paul Lynch
Paul, thanks for the reply but I don't believe NSDate will accept hours greater then 23 e.g. if I wanted to put 102:32. Please correct me if I am wrong!
Daniel Granger
I'd be tempted to say create a custom subclass of NSFormatter, but in this case I suspect that the regex solution is the way to go.
Paul Lynch
Thanks for the advice :-)
Daniel Granger