Skip to content

Instantly share code, notes, and snippets.

@Odie
Created October 9, 2014 12:10
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Odie/e26bc299bfc1f020e636 to your computer and use it in GitHub Desktop.
Save Odie/e26bc299bfc1f020e636 to your computer and use it in GitHub Desktop.
Parse user friendly time duration string in Swift
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