Created
October 9, 2014 12:10
-
-
Save Odie/e26bc299bfc1f020e636 to your computer and use it in GitHub Desktop.
Parse user friendly time duration string in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
extension NSDateComponents { | |
subscript(unit: String) -> Int { | |
get { | |
switch unit{ | |
case "month": | |
return self.month | |
case "day": | |
return self.day | |
case "hour": | |
return self.hour | |
case "minute": | |
return self.minute | |
case "second": | |
return self.second | |
default: | |
return 0 | |
} | |
} | |
set(newValue) { | |
switch unit{ | |
case "month": | |
self.month = newValue | |
case "day": | |
self.day = newValue | |
case "hour": | |
self.hour = newValue | |
case "minute": | |
self.minute = newValue | |
case "second": | |
self.second = newValue | |
default: | |
break | |
} | |
} | |
} | |
} | |
func dateComponentFromNaturalLanguageString(var input: String) -> NSDateComponents { | |
// Define the time units we can understand | |
var timeUnits = [ | |
// Unit kind => [Unit aliases...] | |
"month": ["months", "month", "mon"], | |
"week": ["weeks", "week", "w"], | |
"day": ["days", "day", "d"], | |
"hour": ["hours", "hour", "hrs", "hr", "h"], | |
"second": ["seconds", "seconds", "secs", "sec", "s"] | |
] | |
// Construct a reverse lookup table to go from unit alias => unit kind | |
var unitKindTable = Dictionary<String, String>() | |
for (kind, aliasArray) in timeUnits { | |
for alias in aliasArray { | |
unitKindTable[alias] = kind | |
} | |
} | |
// Break input into individual tokens | |
// This works well for English and other western languages only | |
var tokens = input.componentsSeparatedByString(" "); | |
var duration = NSDateComponents() | |
// Process each of the tokens found | |
for (index, element) in enumerate(tokens) { | |
// Try to find a unit alias in the list of tokens | |
var unitKind = unitKindTable[element] | |
if(unitKind == nil || index == 0){ | |
continue | |
} | |
// Try to parse the token before the unit as a number | |
var value = tokens[index-1].toInt() | |
if(value == nil) { | |
continue | |
} | |
// At this point, we've determine the unit type and the quantity | |
// NSDateComponent doesn't deal with weeks the way we want. | |
// Remap a week as 7 days | |
if(unitKind == "week") { | |
unitKind = "day" | |
value! *= 7 | |
} | |
// Set the component value through the extension | |
duration[unitKind!] = value! | |
} | |
return duration | |
} | |
var duration = dateComponentFromNaturalLanguageString("1 week 1 hours") | |
var targetDate = NSCalendar.currentCalendar().dateByAddingComponents(duration, toDate: NSDate(), options: NSCalendarOptions(0)) | |
println(targetDate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment